From 973d6984dbc7b0bb1f30f9236898f2298d1341f4 Mon Sep 17 00:00:00 2001 From: yicheng Date: Sat, 11 Aug 2018 17:29:31 +0800 Subject: [PATCH] Improve: read api port from config file --- ClashX.xcodeproj/project.pbxproj | 20 +++++++++ ClashX/AppDelegate.swift | 5 ++- ClashX/Managers/ConfigManager.swift | 18 +++++++- ClashX/Support Files/sampleConfig.ini | 2 +- ClashX/Vendor/INIParser/parseINI.swift | 59 ++++++++++++++++++++++++++ 5 files changed, 100 insertions(+), 4 deletions(-) create mode 100755 ClashX/Vendor/INIParser/parseINI.swift diff --git a/ClashX.xcodeproj/project.pbxproj b/ClashX.xcodeproj/project.pbxproj index 1c9637d..2ce7e95 100644 --- a/ClashX.xcodeproj/project.pbxproj +++ b/ClashX.xcodeproj/project.pbxproj @@ -25,6 +25,7 @@ 4966E9E32118153A00A391FB /* NSUserNotificationCenter+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4966E9E22118153A00A391FB /* NSUserNotificationCenter+Extension.swift */; }; 4966E9E6211824F300A391FB /* NSImage+extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4966E9E5211824F300A391FB /* NSImage+extension.swift */; }; 496BDEE021196F1E00C5207F /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 496BDEDF21196F1E00C5207F /* Logger.swift */; }; + 49722FE4211ED56C00650A41 /* parseINI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49722FE1211ED56B00650A41 /* parseINI.swift */; }; 497F0DF320DE2FE50077AD41 /* Icon.icns in Resources */ = {isa = PBXBuildFile; fileRef = 497F0DF220DE2FE50077AD41 /* Icon.icns */; }; 4989F98020D01C8F0001E564 /* clash.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4989F97E20D01C8F0001E564 /* clash.a */; }; 4989F98420D02D200001E564 /* Country.mmdb in Resources */ = {isa = PBXBuildFile; fileRef = 4989F98320D02D200001E564 /* Country.mmdb */; }; @@ -91,6 +92,7 @@ 4966E9E22118153A00A391FB /* NSUserNotificationCenter+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSUserNotificationCenter+Extension.swift"; sourceTree = ""; }; 4966E9E5211824F300A391FB /* NSImage+extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSImage+extension.swift"; sourceTree = ""; }; 496BDEDF21196F1E00C5207F /* Logger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Logger.swift; sourceTree = ""; }; + 49722FE1211ED56B00650A41 /* parseINI.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = parseINI.swift; sourceTree = ""; }; 497F0DF220DE2FE50077AD41 /* Icon.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = Icon.icns; sourceTree = ""; }; 4989F97E20D01C8F0001E564 /* clash.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = clash.a; sourceTree = ""; }; 4989F97F20D01C8F0001E564 /* clash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = clash.h; sourceTree = ""; }; @@ -173,6 +175,22 @@ path = ClashXLaunchHelper; sourceTree = ""; }; + 49722FDD211ED2A900650A41 /* Vendor */ = { + isa = PBXGroup; + children = ( + 49722FDE211ED2CF00650A41 /* INIParser */, + ); + path = Vendor; + sourceTree = ""; + }; + 49722FDE211ED2CF00650A41 /* INIParser */ = { + isa = PBXGroup; + children = ( + 49722FE1211ED56B00650A41 /* parseINI.swift */, + ); + path = INIParser; + sourceTree = ""; + }; 4989F98520D0AA300001E564 /* ViewControllers */ = { isa = PBXGroup; children = ( @@ -220,6 +238,7 @@ 49CF3B1F20CD7463001EBF94 /* ClashX */ = { isa = PBXGroup; children = ( + 49722FDD211ED2A900650A41 /* Vendor */, 4913C82021157CEB00F6B87C /* Macro */, 492C486E210EF621004554A0 /* Models */, 492C4866210EE69B004554A0 /* General */, @@ -538,6 +557,7 @@ 49CF3B6520CEE06C001EBF94 /* ConfigManager.swift in Sources */, 4952C3BF2115C7CA004A4FA8 /* ProxyMenuItemFactory.swift in Sources */, 4966E9E32118153A00A391FB /* NSUserNotificationCenter+Extension.swift in Sources */, + 49722FE4211ED56C00650A41 /* parseINI.swift in Sources */, 4966E9E6211824F300A391FB /* NSImage+extension.swift in Sources */, 4952C3CE2116EA2E004A4FA8 /* ProxyServerModel.swift in Sources */, ); diff --git a/ClashX/AppDelegate.swift b/ClashX/AppDelegate.swift index 489a4eb..f80041e 100644 --- a/ClashX/AppDelegate.swift +++ b/ClashX/AppDelegate.swift @@ -46,6 +46,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { self.syncConfig() } setupData() + } @@ -58,8 +59,8 @@ class AppDelegate: NSObject, NSApplicationDelegate { func setupData() { NotificationCenter.default.rx.notification(kShouldUpDateConfig).bind { [unowned self] (note) in - self.syncConfig() - }.disposed(by: disposeBag) + self.actionUpdateConfig(self) + }.disposed(by: disposeBag) ConfigManager.shared diff --git a/ClashX/Managers/ConfigManager.swift b/ClashX/Managers/ConfigManager.swift index ef1d2e8..cb1e54b 100644 --- a/ClashX/Managers/ConfigManager.swift +++ b/ClashX/Managers/ConfigManager.swift @@ -13,6 +13,8 @@ import RxSwift class ConfigManager { static let shared = ConfigManager() + var apiPort = "8080" + private init(){refreshApiPort()} var currentConfig:ClashConfig?{ get { @@ -47,7 +49,7 @@ class ConfigManager { static var apiUrl:String{ get { - return "http://127.0.0.1:8080" + return "http://127.0.0.1:\(shared.apiPort)" } } @@ -69,4 +71,18 @@ class ConfigManager { } } + func refreshApiPort(){ + if let ini = + parseConfig("\(NSHomeDirectory())/.config/clash/config.ini"), + let controller = ini["General"]?["external-controller"]{ + if controller.contains(":") { + apiPort = String(controller.split(separator: ":").last ?? "8080") + return + } + } + apiPort = "8080" + } + + + } diff --git a/ClashX/Support Files/sampleConfig.ini b/ClashX/Support Files/sampleConfig.ini index 05b4d85..71200bb 100644 --- a/ClashX/Support Files/sampleConfig.ini +++ b/ClashX/Support Files/sampleConfig.ini @@ -1,7 +1,7 @@ [General] port = 7890 socks-port = 7891 -external-controller = 127.0.0.1:8080 +external-controller = 127.0.0.1:7892 [Proxy] # name = ss, server, port, cipter, password diff --git a/ClashX/Vendor/INIParser/parseINI.swift b/ClashX/Vendor/INIParser/parseINI.swift new file mode 100755 index 0000000..15dec2a --- /dev/null +++ b/ClashX/Vendor/INIParser/parseINI.swift @@ -0,0 +1,59 @@ +import Foundation + + +typealias SectionConfig = [String: String] +typealias Config = [String: SectionConfig] + + +func trim(_ s: String) -> String { + let whitespaces = CharacterSet(charactersIn: " \n\r\t") + return s.trimmingCharacters(in: whitespaces) +} + + +func stripComment(_ line: String) -> String { + let parts = line.split( + separator: "#", + maxSplits: 1, + omittingEmptySubsequences: false) + if parts.count > 0 { + return String(parts[0]) + } + return "" +} + + +func parseSectionHeader(_ line: String) -> String { + let from = line.index(after: line.startIndex) + let to = line.index(before: line.endIndex) + return String(line[from.. (String, String)? { + let parts = stripComment(line).split(separator: "=", maxSplits: 1) + if parts.count == 2 { + let k = trim(String(parts[0])) + let v = trim(String(parts[1])) + return (k, v) + } + return nil +} + + +func parseConfig(_ filename : String) -> Config? { + guard let f = try? String(contentsOfFile: filename) else {return nil} + var config = Config() + var currentSectionName = "main" + for line in f.components(separatedBy: "\n") { + let line = trim(line) + if line.hasPrefix("[") && line.hasSuffix("]") { + currentSectionName = parseSectionHeader(line) + } else if let (k, v) = parseLine(line) { + var section = config[currentSectionName] ?? [:] + section[k] = v + config[currentSectionName] = section + } + } + return config +}