Skip to content

Commit 9fc5f78

Browse files
committed
localization: translate code comments to English
Translate all non-English (mostly Chinese) code comments across app and libcore source to English. Comments only — no code, identifiers, logic, formatting, or string literals changed. Deliberately preserved (functional/UI string literals, not comments): - ProfileManager.kt "cn:中国" (country-match logic data) - NaiveSettingsActivity.kt "喵要打开隐藏功能"/"喵要关闭隐藏功能" (easter-egg triggers) - WebDAVSettingsActivity.kt "请稍后再试" (existing hardcoded Snackbar string)
1 parent 3ab203f commit 9fc5f78

28 files changed

Lines changed: 144 additions & 142 deletions

app/src/main/java/io/nekohasekai/sagernet/database/DataStore.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ object DataStore : OnPreferenceDataStoreChangeListener {
134134

135135
var rulesGeositeUrl by configurationStore.string(Key.RULES_GEOSITE_URL) { "https://github.com/SagerNet/sing-geosite/releases/latest/download/geosite.db" }
136136
var rulesGeoipUrl by configurationStore.string(Key.RULES_GEOIP_URL) { "https://github.com/SagerNet/sing-geoip/releases/latest/download/geoip.db" }
137-
var rulesUpdateInterval by configurationStore.string(Key.RULES_UPDATE_INTERVAL) { "0" } // 默认为0,不自动更新
137+
var rulesUpdateInterval by configurationStore.string(Key.RULES_UPDATE_INTERVAL) { "0" } // defaults to 0, no automatic update
138138

139139
// hopefully hashCode = mHandle doesn't change, currently this is true from KitKat to Nougat
140140
private val userIndex by lazy { Binder.getCallingUserHandle().hashCode() }
@@ -320,7 +320,7 @@ object DataStore : OnPreferenceDataStoreChangeListener {
320320
set(value) = configurationStore.putString("webdavPassword", value)
321321

322322
var webdavPath: String?
323-
get() = configurationStore.getString("webdavPath") ?: "NekoBox" // 设置默认值
323+
get() = configurationStore.getString("webdavPath") ?: "NekoBox" // set default value
324324
set(value) = configurationStore.putString("webdavPath", value)
325325

326326
var globalMode by configurationStore.boolean(Key.GLOBAL_MODE)

app/src/main/java/io/nekohasekai/sagernet/database/ProfileManager.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ object ProfileManager {
206206
)
207207
val fuckedCountry = mutableListOf("cn:中国")
208208
if (Locale.getDefault().country != Locale.CHINA.country) {
209-
// 非中文用户
209+
// non-Chinese users
210210
fuckedCountry += "ir:Iran"
211211
fuckedCountry += "ru:Russia"
212212
}

app/src/main/java/io/nekohasekai/sagernet/fmt/ConfigBuilder.kt

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ fun buildConfig(
272272
rules = mutableListOf()
273273
rule_set = mutableListOf()
274274

275-
// 添加并发拨号设置
275+
// add concurrent dial setting
276276
concurrent_dial = DataStore.concurrentDial
277277
}
278278

@@ -534,11 +534,11 @@ fun buildConfig(
534534

535535
val mainProxyTag = (if (buildSelector) TAG_PROXY else tagMap[proxy.id]) ?: TAG_PROXY
536536

537-
// 在应用用户规则之前检查全局模式
537+
// check global mode before applying user rules
538538
if (!forTest && DataStore.globalMode) {
539-
// 全局模式下的规则处理
539+
// rule handling in global mode
540540

541-
// 绕过内部网络(如果启用)
541+
// bypass internal networks (if enabled)
542542
if (DataStore.bypassLan) {
543543
route.rules.add(Rule_DefaultOptions().apply {
544544
ip_cidr = listOf(
@@ -568,7 +568,7 @@ fun buildConfig(
568568

569569
route.final_ = mainProxyTag
570570
} else {
571-
// 应用用户规则
571+
// apply user rules
572572
for (rule in extraRules) {
573573
if (rule.packages.isNotEmpty()) {
574574
PackageCache.awaitLoadSync()
@@ -601,10 +601,10 @@ fun buildConfig(
601601

602602
if (rule_set != null) generateRuleSet(rule_set, ruleSets)
603603

604-
// 存储ruleset标签和类型信息
604+
// store ruleset tag and type info
605605
val rulesetTags = mutableListOf<Pair<String, Boolean>>()
606606

607-
// 处理远程ruleset
607+
// handle remote ruleset
608608
if (rule.ruleset.isNotBlank()) {
609609
val rulesetUrls = rule.ruleset.listByLineOrComma()
610610
rulesetUrls.forEach { origUrl ->
@@ -665,7 +665,7 @@ fun buildConfig(
665665

666666
if (rule_set != null && rulesetTags.isNotEmpty()) {
667667
for (tag in rule_set) {
668-
// 只处理ruleset标签,且必须是非IP类型
668+
// only handle ruleset tags, and they must be non-IP type
669669
val tagInfo = rulesetTags.find { it.first == tag }
670670
if (tag.startsWith("ruleset-") && tagInfo != null && !tagInfo.second) {
671671
userDNSRuleList += DNSRule_DefaultOptions().apply {
@@ -749,7 +749,7 @@ fun buildConfig(
749749
Toast.LENGTH_LONG
750750
).show()
751751
} else {
752-
// block 改用新的写法
752+
// block now uses the new approach
753753
if (ruleObj.outbound == TAG_BLOCK) {
754754
ruleObj.outbound = null
755755
ruleObj.action = "reject"
@@ -761,7 +761,7 @@ fun buildConfig(
761761
}
762762
}
763763

764-
// rule_set tag 去重
764+
// deduplicate rule_set tags
765765
if (route.rule_set != null) {
766766
route.rule_set = route.rule_set.distinctBy { it.tag }
767767
}

app/src/main/java/io/nekohasekai/sagernet/fmt/snell/SnellFmt.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import io.nekohasekai.sagernet.ktx.urlSafe
44
import io.nekohasekai.sagernet.ktx.unUrlSafe
55
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
66

7-
// URI 格式: snell://base64(psk)@server:port?version=4&obfs-mode=http&obfs-host=bing.com&reuse=true&network=tcp#name
7+
// URI format: snell://base64(psk)@server:port?version=4&obfs-mode=http&obfs-host=bing.com&reuse=true&network=tcp#name
88
fun parseSnell(url: String): SnellBean {
99
val link = url.replace("snell://", "https://").toHttpUrlOrNull()
1010
?: error("Invalid snell URL")

app/src/main/java/io/nekohasekai/sagernet/fmt/trojan_go/TrojanGoBean.java

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -14,63 +14,65 @@
1414
public class TrojanGoBean extends AbstractBean {
1515

1616
/**
17-
* Trojan 的密码。
18-
* 不可省略,不能为空字符串,不建议含有非 ASCII 可打印字符。
19-
* 必须使用 encodeURIComponent 编码。
17+
* Trojan password.
18+
* Must not be omitted or empty; non-ASCII printable characters are discouraged.
19+
* Must be encoded with encodeURIComponent.
2020
*/
2121
public String password;
2222

2323
/**
24-
* 自定义 TLS SNI
25-
* 省略时默认与 trojan-host 同值。不得为空字符串。
24+
* Custom TLS SNI.
25+
* Defaults to the same value as trojan-host when omitted. Must not be empty.
2626
* <p>
27-
* 必须使用 encodeURIComponent 编码。
27+
* Must be encoded with encodeURIComponent.
2828
*/
2929
public String sni;
3030

3131
/**
32-
* 传输类型。
33-
* 省略时默认为 original,但不可为空字符串。
34-
* 目前可选值只有 original 和 ws,未来可能会有 h2、h2+ws 等取值。
32+
* Transport type.
33+
* Defaults to "original" when omitted, but must not be an empty string.
34+
* Currently only "original" and "ws" are valid; future values may include h2, h2+ws, etc.
3535
* <p>
36-
* 当取值为 original 时,使用原始 Trojan 传输方式,无法方便通过 CDN
37-
* 当取值为 ws 时,使用 wss 作为传输层。
36+
* "original" uses the raw Trojan transport, which is not easily served via a CDN.
37+
* "ws" uses wss as the transport layer.
3838
*/
3939
public String type;
4040

4141
/**
42-
* 自定义 HTTP Host 头。
43-
* 可以省略,省略时值同 trojan-host
44-
* 可以为空字符串,但可能带来非预期情形。
42+
* Custom HTTP Host header.
43+
* May be omitted; defaults to trojan-host when omitted.
44+
* May be an empty string, but that can lead to unexpected behavior.
4545
* <p>
46-
* 警告:若你的端口非标准端口(不是 80 / 443),RFC 标准规定 Host 应在主机名后附上端口号,例如 example.com:44333。至于是否遵守,请自行斟酌。
46+
* Warning: if your port is non-standard (not 80 / 443), the RFC requires the Host to
47+
* include the port after the hostname, e.g. example.com:44333. Whether to follow this
48+
* is up to you.
4749
* <p>
48-
* 必须使用 encodeURIComponent 编码。
50+
* Must be encoded with encodeURIComponent.
4951
*/
5052
public String host;
5153

5254
/**
53-
* 当传输类型 type ws、h2、h2+ws 时,此项有效。
54-
* 不可省略,不可为空。
55-
* 必须以 / 开头。
56-
* 可以使用 URL 中的 & # ? 等字符,但应当是合法的 URL 路径。
55+
* Effective when the transport type is ws, h2, or h2+ws.
56+
* Must not be omitted or empty.
57+
* Must start with "/".
58+
* May use URL characters such as & # ?, but must be a valid URL path.
5759
* <p>
58-
* 必须使用 encodeURIComponent 编码。
60+
* Must be encoded with encodeURIComponent.
5961
*/
6062
public String path;
6163

6264
/**
63-
* 用于保证 Trojan 流量密码学安全的加密层。
64-
* 可省略,默认为 none,即不使用加密。
65-
* 不可以为空字符串。
65+
* Encryption layer used to cryptographically secure Trojan traffic.
66+
* May be omitted; defaults to "none" (no encryption).
67+
* Must not be an empty string.
6668
* <p>
67-
* 必须使用 encodeURIComponent 编码。
69+
* Must be encoded with encodeURIComponent.
6870
* <p>
69-
* 使用 Shadowsocks 算法进行流量加密时,其格式为:
71+
* When using the Shadowsocks algorithm for traffic encryption, the format is:
7072
* <p>
7173
* ss;method:password
7274
* <p>
73-
* 其中 ss 是固定内容,method 是加密方法,必须为下列之一:
75+
* where "ss" is fixed and "method" is the encryption method, which must be one of:
7476
* <p>
7577
* aes-128-gcm
7678
* aes-256-gcm
@@ -79,8 +81,8 @@ public class TrojanGoBean extends AbstractBean {
7981
public String encryption;
8082

8183
/**
82-
* 额外的插件选项。本字段保留。
83-
* 可省略,但不可以为空字符串。
84+
* Extra plugin options. This field is reserved.
85+
* May be omitted, but must not be an empty string.
8486
*/
8587
// not used in NB4A
8688
public String plugin;

app/src/main/java/io/nekohasekai/sagernet/fmt/v2ray/StandardV2RayBean.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ public void initializeDefaultValues() {
143143

144144
if (JavaUtil.isNullOrBlank(mKcpSeed)) mKcpSeed = "";
145145
if (JavaUtil.isNullOrBlank(headerType)) headerType = "none";
146-
// kcpMtukcpTti kcpCwndMultiplier 保持 null,不设置默认值
146+
// kcpMtu, kcpTti and kcpCwndMultiplier stay null, no default values set
147147
}
148148

149149
@Override
@@ -265,7 +265,7 @@ public void deserialize(ByteBufferInput input) {
265265
case "grpc": {
266266
path = input.readString();
267267
if (version < 4) {
268-
// 解决老版本数据的读取问题
268+
// fix the reading issue with old version data
269269
input.readString();
270270
input.readString();
271271
}
@@ -327,13 +327,13 @@ public void deserialize(ByteBufferInput input) {
327327
}
328328
}
329329
} else if (version == 0) {
330-
// 从老版本升级上来但是 version == 0, 可能有 enableECH 也可能没有,需要做判断
331-
int position = input.getByteBuffer().position(); // 当前位置
330+
// upgraded from an old version but version == 0; may or may not have enableECH, so a check is needed
331+
int position = input.getByteBuffer().position(); // current position
332332

333333
boolean tmpEnableECH = input.readBoolean();
334334
int tmpPacketEncoding = input.readInt();
335335

336-
input.setPosition(position); // 读后归位
336+
input.setPosition(position); // reset position after reading
337337

338338
if (tmpPacketEncoding != 1 && tmpPacketEncoding != 2) {
339339
enableECH = tmpEnableECH;
@@ -342,7 +342,7 @@ public void deserialize(ByteBufferInput input) {
342342
input.readBoolean();
343343
echConfig = input.readString();
344344
}
345-
} // 否则后一位就是 packetEncoding
345+
} // otherwise the next field is packetEncoding
346346
}
347347

348348
packetEncoding = input.readInt();

app/src/main/java/io/nekohasekai/sagernet/fmt/v2ray/V2RayFmt.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ fun StandardV2RayBean.parseDuckSoft(url: HttpUrl) {
316316
}
317317
}
318318

319-
// 不确定是谁的格式
319+
// not sure whose format this is
320320
private fun tryResolveVmess4Kitsunebi(server: String): VMessBean {
321321
// vmess://YXV0bzo1YWY1ZDBlYy02ZWEwLTNjNDMtOTNkYi1jYTMwMDg1MDNiZGJAMTgzLjIzMi41Ni4xNjE6MTIwMg
322322
// ?remarks=*%F0%9F%87%AF%F0%9F%87%B5JP%20-355%20TG@moon365free&obfsParam=%7B%22Host%22:%22183.232.56.161%22%7D&path=/v2ray&obfs=websocket&alterId=0
@@ -772,7 +772,7 @@ fun buildSingBoxOutboundTLS(bean: StandardV2RayBean): OutboundTLSOptions? {
772772
insecure = bean.allowInsecure || DataStore.globalAllowInsecure
773773
if (bean.sni.isNotBlank()) server_name = bean.sni
774774
if (bean.alpn.isNotBlank()) {
775-
// 当传输协议为WebSocket时,过滤掉h2和h3
775+
// when the transport protocol is WebSocket, filter out h2 and h3
776776
val alpnList = bean.alpn.listByLineOrComma()
777777
if (bean.type == "ws") {
778778
val filtered = alpnList.filter { it == "http/1.1" }

app/src/main/java/io/nekohasekai/sagernet/group/RawUpdater.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ object RawUpdater : GroupUpdater() {
8484
subscription.subscriptionUserinfo =
8585
Util.getStringBox(response.getHeader("Subscription-Userinfo"))
8686

87-
// 修改默认名字
87+
// modify the default name
8888
if (proxyGroup.name?.startsWith("Subscription #") == true) {
8989
var remoteName = Util.getStringBox(response.getHeader("content-disposition"))
9090
if (remoteName.isNotBlank()) {
@@ -182,7 +182,7 @@ object RawUpdater : GroupUpdater() {
182182
if (toReplace.contains(name)) {
183183
val entity = toReplace[name]!!
184184
val existsBean = entity.requireBean()
185-
// 更新订阅,保留自定义覆写设置
185+
// update subscription, preserving custom override settings
186186
bean.customOutboundJson = existsBean.customOutboundJson
187187
bean.customConfigJson = existsBean.customConfigJson
188188
when {

app/src/main/java/io/nekohasekai/sagernet/ktx/Formats.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ fun JSONObject.getBool(name: String): Boolean? {
8888
}
8989

9090

91-
// 重名了喵
91+
// name collision, nya
9292
fun JSONObject.getIntNya(name: String): Int? {
9393
return try {
9494
getInt(name)

0 commit comments

Comments
 (0)