mirror of
https://github.com/shadowsocks/ShadowsocksX-NG.git
synced 2026-11-15 10:44:21 +00:00
Domain/ 根目录原有 62 个平铺源文件,无法从目录读出主题划分。 按「目录即主题」重组为 11 个目录(Rules/Custom 为嵌套子目录):Catalog / Subscription / Rules / Runtime / Activation / Settings / SystemProxy / Plugin / Credentials / LegacyImport / Diagnostics。纯移动:类型名、模块名 与 import 均未改动,Domain/ 根下不再有散落文件。目录口径取自 GLOSSARY.md 的章节划分(配置与订阅、代理规则、代理控制与网络、设置、 凭据与诊断),而非新造分类。 配套改动: - project.yml:wrapper 与 helper 两个 target 按文件引用的 15 条显式路径 随目录改名,并补注释固定这一约定——这 15 条指向不存在的文件时, xcodegen generate 以 "missing source directory" 直接失败(实测,不静默)。 - SkeletonTests 新增 DomainLayoutTests:断言 Domain/ 根下无平铺 .swift、 树下只有 .swift。后者防的是与 App/ 同源的坑——Domain/ 整目录是 app 与 Core 的 source path,任何非源码文件都会被 XcodeGen 收进 Resources 阶段 并封进签名后的 bundle。 - README 工程结构说明同步;docs/design 与 docs/research 属历史文档不改。 验证:xcodegen generate 后 app 164 / Core 163 源文件数与整理前一致;Agent 恰好 9 个、Helper 恰好 6 个 Domain 文件(无缺失无多出);app 与 Core 各覆盖 全部 62 个。clean build 0 error;task test 1024 用例全通过(整理前 1022, +2 为新增守卫);task format 未改写任何被移动文件(证明纯移动);task lint 与整理前同为 21 条内容型 warning;packaging-gate.sh ALL CHECKS PASSED。 布局守卫已做变异验证:临时投放松散 .swift 与非 .swift 文件时两个用例均 失败并点名违规文件,清理后复验为绿。
97 lines
3.8 KiB
Swift
97 lines
3.8 KiB
Swift
import Foundation
|
|
|
|
/// Pure projection of one SystemConfiguration Proxies dictionary. The key mapping is a
|
|
/// mechanical translation of the closed typed configuration (issue #71): every field the
|
|
/// GUI supplies is written, disabled protocols lose their endpoint keys, PAC/auto-
|
|
/// discovery/simple-hostname exclusion follow their explicit flags, and the complete
|
|
/// exceptions list is always written. Keys outside the typed field set are preserved.
|
|
enum SystemProxyPropertyList {
|
|
static let httpEnabled = "HTTPEnable"
|
|
static let httpsEnabled = "HTTPSEnable"
|
|
static let socksEnabled = "SOCKSEnable"
|
|
static let httpPort = "HTTPPort"
|
|
static let httpProxy = "HTTPProxy"
|
|
static let httpsPort = "HTTPSPort"
|
|
static let httpsProxy = "HTTPSProxy"
|
|
static let socksPort = "SOCKSPort"
|
|
static let socksProxy = "SOCKSProxy"
|
|
static let pacEnabled = "ProxyAutoConfigEnable"
|
|
static let pacURL = "ProxyAutoConfigURLString"
|
|
static let pacJavaScript = "ProxyAutoConfigJavaScript"
|
|
static let autoDiscoveryEnabled = "ProxyAutoDiscoveryEnable"
|
|
static let exceptionsList = "ExceptionsList"
|
|
static let excludeSimpleHostnames = "ExcludeSimpleHostnames"
|
|
|
|
/// 一个协议族的 Proxies 键组。
|
|
private struct ProtocolKeys {
|
|
let enable: String
|
|
let proxy: String
|
|
let port: String
|
|
}
|
|
|
|
static func applying(
|
|
_ configuration: SystemProxyConfiguration, to original: [String: Any]
|
|
) -> [String: Any] {
|
|
var dictionary = original
|
|
applyProtocol(
|
|
enabled: configuration.socksEnabled, endpoint: configuration.socks,
|
|
keys: ProtocolKeys(enable: socksEnabled, proxy: socksProxy, port: socksPort),
|
|
into: &dictionary)
|
|
applyProtocol(
|
|
enabled: configuration.httpEnabled, endpoint: configuration.http,
|
|
keys: ProtocolKeys(enable: httpEnabled, proxy: httpProxy, port: httpPort),
|
|
into: &dictionary)
|
|
applyProtocol(
|
|
enabled: configuration.httpsEnabled, endpoint: configuration.https,
|
|
keys: ProtocolKeys(enable: httpsEnabled, proxy: httpsProxy, port: httpsPort),
|
|
into: &dictionary)
|
|
|
|
dictionary[pacEnabled] = configuration.pacEnabled ? 1 : 0
|
|
if !configuration.pacEnabled {
|
|
// 关闭的 PAC 不留残余:URL 与 JavaScript 值一并移除(issue #71 AC27)。
|
|
dictionary.removeValue(forKey: pacJavaScript)
|
|
dictionary.removeValue(forKey: pacURL)
|
|
}
|
|
dictionary[autoDiscoveryEnabled] = configuration.autoDiscoveryEnabled ? 1 : 0
|
|
dictionary[excludeSimpleHostnames] = configuration.excludeSimpleHostnames ? 1 : 0
|
|
dictionary[exceptionsList] = configuration.exceptions
|
|
return dictionary
|
|
}
|
|
|
|
/// Normalize only values whose SystemConfiguration meaning is equivalent.
|
|
/// Unknown fields stay verbatim; stale managed endpoint/PAC values still differ.
|
|
static func semanticallyNormalized(_ original: [String: Any]) -> [String: Any] {
|
|
var values = original
|
|
for key in [
|
|
httpEnabled, httpsEnabled, socksEnabled, pacEnabled,
|
|
autoDiscoveryEnabled, excludeSimpleHostnames,
|
|
] {
|
|
if let number = values[key] as? NSNumber {
|
|
values[key] = number.boolValue ? 1 : 0
|
|
} else if values[key] == nil {
|
|
values[key] = 0
|
|
}
|
|
}
|
|
if let exceptions = values[exceptionsList] as? [String] {
|
|
values[exceptionsList] = Set(exceptions).sorted()
|
|
}
|
|
return values
|
|
}
|
|
|
|
/// 启用的协议族写入显式端点;关闭的协议族移除端点键,保持字典与配置一致。
|
|
private static func applyProtocol(
|
|
enabled: Bool, endpoint: SystemProxyConfiguration.Endpoint,
|
|
keys: ProtocolKeys,
|
|
into dictionary: inout [String: Any]
|
|
) {
|
|
dictionary[keys.enable] = enabled ? 1 : 0
|
|
if enabled {
|
|
dictionary[keys.proxy] = endpoint.host
|
|
dictionary[keys.port] = endpoint.port
|
|
} else {
|
|
dictionary.removeValue(forKey: keys.proxy)
|
|
dictionary.removeValue(forKey: keys.port)
|
|
}
|
|
}
|
|
}
|