diff --git a/ClashX/Actions/TerminalCleanUpAction.swift b/ClashX/Actions/TerminalCleanUpAction.swift index 8ffefba..b5d618d 100644 --- a/ClashX/Actions/TerminalCleanUpAction.swift +++ b/ClashX/Actions/TerminalCleanUpAction.swift @@ -21,7 +21,7 @@ enum TerminalConfirmAction { ConfigManager.shared.restoreTunProxy = ConfigManager.shared.isTunModeVariable.value PrivilegedHelperManager.shared.helper()?.stopMeta() - PrivilegedHelperManager.shared.helper()?.updateTun(state: false) + PrivilegedHelperManager.shared.helper()?.updateTun(state: false, dns: ConfigManager.metaTunDNS) let path = Paths.tempPath() + "/cacheConfigs" try? FileManager.default.removeItem(atPath: path) diff --git a/ClashX/AppDelegate.swift b/ClashX/AppDelegate.swift index 91b7757..275b1df 100644 --- a/ClashX/AppDelegate.swift +++ b/ClashX/AppDelegate.swift @@ -442,7 +442,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { return } - PrivilegedHelperManager.shared.helper()?.updateTun(state: enable) + PrivilegedHelperManager.shared.helper()?.updateTun(state: enable, dns: ConfigManager.metaTunDNS) Logger.log("tun state updated, new: \(enable)") } } @@ -578,7 +578,7 @@ extension AppDelegate: ClashProcessDelegate { if ConfigManager.shared.restoreTunProxy { ApiRequest.updateTun(enable: true) { - PrivilegedHelperManager.shared.helper()?.updateTun(state: true) + PrivilegedHelperManager.shared.helper()?.updateTun(state: true, dns: ConfigManager.metaTunDNS) } } else { syncConfigWithTun(true) @@ -755,7 +755,7 @@ extension AppDelegate: ApiRequestStreamDelegate { } func didGetLog(log: String, level: String) { - Logger.log(log, level: ClashLogLevel(rawValue: level) ?? .unknow) +// Logger.log(log, level: ClashLogLevel(rawValue: level) ?? .unknow) } } diff --git a/ClashX/Base.lproj/Main.storyboard b/ClashX/Base.lproj/Main.storyboard index 6f1b919..bcc4141 100644 --- a/ClashX/Base.lproj/Main.storyboard +++ b/ClashX/Base.lproj/Main.storyboard @@ -1,7 +1,7 @@ - + - + @@ -296,15 +296,15 @@ - + - + - + @@ -318,7 +318,7 @@ - + @@ -425,15 +425,15 @@ - + - + - + @@ -447,7 +447,7 @@ - + @@ -1951,7 +1951,7 @@ - + diff --git a/ClashX/General/Managers/ConfigManager.swift b/ClashX/General/Managers/ConfigManager.swift index a4f6217..eb0d265 100644 --- a/ClashX/General/Managers/ConfigManager.swift +++ b/ClashX/General/Managers/ConfigManager.swift @@ -99,6 +99,14 @@ class ConfigManager { var proxyShouldPaused = BehaviorRelay(value: false) var isTunModeVariable = BehaviorRelay(value: false) + + static let defaultTunDNS = "8.8.8.8" + + static var metaTunDNS: String = UserDefaults.standard.object(forKey: "metaTunDNS") as? String ?? defaultTunDNS { + didSet { + UserDefaults.standard.set(metaTunDNS, forKey: "metaTunDNS") + } + } var showNetSpeedIndicator: Bool { get { diff --git a/ClashX/ViewControllers/Settings/MetaPrefs.storyboard b/ClashX/ViewControllers/Settings/MetaPrefs.storyboard index 8f4a847..a17a242 100644 --- a/ClashX/ViewControllers/Settings/MetaPrefs.storyboard +++ b/ClashX/ViewControllers/Settings/MetaPrefs.storyboard @@ -1,7 +1,7 @@ - + - + @@ -9,46 +9,103 @@ - - + + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + - + - + - + @@ -60,7 +117,7 @@ - + @@ -119,13 +176,13 @@ - + - + - + @@ -150,7 +207,7 @@ - + @@ -160,7 +217,7 @@ - + @@ -220,16 +277,27 @@ + + + + + + + + + - + - + + + @@ -238,69 +306,23 @@ + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + diff --git a/ClashX/ViewControllers/Settings/MetaPrefsViewController.swift b/ClashX/ViewControllers/Settings/MetaPrefsViewController.swift index 4a3c8d9..3ccfc86 100644 --- a/ClashX/ViewControllers/Settings/MetaPrefsViewController.swift +++ b/ClashX/ViewControllers/Settings/MetaPrefsViewController.swift @@ -6,6 +6,7 @@ // import Cocoa +import Network class MetaPrefsViewController: NSViewController { // Meta Setting @@ -28,6 +29,14 @@ class MetaPrefsViewController: NSViewController { MenuItemFactory.hideUnselectable = newState.rawValue } + @IBOutlet var tunDNSTextField: NSTextField! + @IBAction func tunDNSChanged(_ sender: NSTextField) { + let ds = sender.stringValue + guard let _ = IPv4Address(ds) else { return } + ConfigManager.metaTunDNS = ds + updateNeedsRestart() + } + // Dashboard @IBOutlet var useSwiftuiButton: NSButton! @IBOutlet var useYacdButton: NSButton! @@ -47,6 +56,7 @@ class MetaPrefsViewController: NSViewController { break } initDashboardButtons() + updateNeedsRestart() } // Alpha Core @@ -71,6 +81,7 @@ class MetaPrefsViewController: NSViewController { let use = sender.state == .on ConfigManager.useAlphaCore = use + updateNeedsRestart() } @IBAction func updateAlpha(_ sender: NSButton) { @@ -104,11 +115,21 @@ class MetaPrefsViewController: NSViewController { } + @IBOutlet var restartTextField: NSTextField! + + var prefsSnapshot = [String]() + var versionSnapshot = "none" + var alphaCoreUpdated = false + override func viewDidLoad() { super.viewDidLoad() // Meta Setting hideUnselectableButton.state = .init(rawValue: MenuItemFactory.hideUnselectable) + tunDNSTextField.placeholderString = ConfigManager.defaultTunDNS + tunDNSTextField.stringValue = ConfigManager.metaTunDNS + tunDNSTextField.delegate = self + // Dashboard initDashboardButtons() @@ -116,6 +137,11 @@ class MetaPrefsViewController: NSViewController { useAlphaButton.state = ConfigManager.useAlphaCore ? .on : .off updateProgressIndicator.isHidden = true setAlphaVersion() + + // Snapshot + prefsSnapshot = takePrefsSnapshot() + versionSnapshot = alphaVersionTextField.stringValue + restartTextField.isHidden = true } func initDashboardButtons() { @@ -156,6 +182,31 @@ class MetaPrefsViewController: NSViewController { alphaVersionTextField.stringValue = "none" updateButton.title = NSLocalizedString("Download Meta core", comment: "") } + + if let v = version, + versionSnapshot != "none", + v != versionSnapshot { + alphaCoreUpdated = true + updateNeedsRestart() + } } + func takePrefsSnapshot() -> [String] { + [ + ConfigManager.metaTunDNS, + "\(ConfigManager.useYacdDashboard)", + "\(ConfigManager.useAlphaCore)" + ] + } + + func updateNeedsRestart() { + let needsRestart = prefsSnapshot != takePrefsSnapshot() || alphaCoreUpdated + restartTextField.isHidden = !needsRestart + } +} + +extension MetaPrefsViewController: NSTextFieldDelegate { + func control(_ control: NSControl, textShouldEndEditing fieldEditor: NSText) -> Bool { + IPv4Address(fieldEditor.string) != nil + } } diff --git a/ClashX/Views/RemoteConfigAddView.xib b/ClashX/Views/RemoteConfigAddView.xib index fbc2253..911aa10 100644 --- a/ClashX/Views/RemoteConfigAddView.xib +++ b/ClashX/Views/RemoteConfigAddView.xib @@ -1,15 +1,14 @@ - + - - + - + diff --git a/ClashX/Views/StatusItem/StatusItemView.xib b/ClashX/Views/StatusItem/StatusItemView.xib index fa7dbc2..207bcf1 100644 --- a/ClashX/Views/StatusItem/StatusItemView.xib +++ b/ClashX/Views/StatusItem/StatusItemView.xib @@ -1,8 +1,7 @@ - + - - + @@ -24,7 +23,7 @@ - + @@ -32,7 +31,7 @@ - + @@ -69,6 +68,6 @@ - + diff --git a/ProxyConfigHelper/Helper-Info.plist b/ProxyConfigHelper/Helper-Info.plist index 3cc6b4d..c4a8a8e 100755 --- a/ProxyConfigHelper/Helper-Info.plist +++ b/ProxyConfigHelper/Helper-Info.plist @@ -9,9 +9,9 @@ CFBundleName com.metacubex.ClashX.ProxyConfigHelper CFBundleShortVersionString - 1.12 + 1.13 CFBundleVersion - 22 + 23 SMAuthorizedClients anchor apple generic and identifier "com.metacubex.ClashX.ProxyConfigHelper" and (certificate leaf[field.1.2.840.113635.100.6.1.9] /* exists */ or certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = MEWHFZ92DY) diff --git a/ProxyConfigHelper/MetaDNS.swift b/ProxyConfigHelper/MetaDNS.swift index 4064e57..2b75dc4 100644 --- a/ProxyConfigHelper/MetaDNS.swift +++ b/ProxyConfigHelper/MetaDNS.swift @@ -10,10 +10,10 @@ import SystemConfiguration // https://github.com/zhuhaow/Specht2/blob/main/app/me.zhuhaow.Specht2.proxy-helper/ProxyHelper.swift class MetaDNS: NSObject { - - var savedDns = [String: [String]]() - let defaultDNS = "198.18.0.2" - + private var customDNS = "8.8.8.8" + + static let savedDNSKey = "ProxyConfigHelper.SavedSystemDNSs" + var savedDNS = [String: [String]]() let authRef: AuthorizationRef override init() { @@ -29,7 +29,13 @@ class MetaDNS: NSObject { if auth == nil { NSLog("Error: No authorization has been granted to modify network configuration.") } - + + + if let data = UserDefaults.standard.data(forKey: MetaDNS.savedDNSKey), + let saved = try? JSONDecoder().decode([String: [String]].self, from: data) { + self.savedDNS = saved + } + authRef = auth! super.init() @@ -39,31 +45,35 @@ class MetaDNS: NSObject { AuthorizationFree(authRef, AuthorizationFlags()) } - @objc func updateDns() { - let dns = getAllDns() - dns.forEach { - if $0.value.count == 1, - $0.value[0] == defaultDNS { - if savedDns[$0.key] == nil { - savedDns[$0.key] = [] - } else { - // ignore save - } - } else { - savedDns[$0.key] = $0.value - } - } - + @objc func setCustomDNS(_ dns: String) { + customDNS = dns + } + + @objc func hijackDNS() { + let dns = getAllDns() + let hijacked = dns.allSatisfy { + $0.value.count == 1 && $0.value[0] == customDNS + } + + guard !hijacked else { return } + + savedDNS = dns + if let data = try? JSONEncoder().encode(savedDNS) { + UserDefaults.standard.set(data, forKey: MetaDNS.savedDNSKey) + } + let dnsDic = dns.reduce(into: [:]) { - $0[$1.key] = [defaultDNS] + $0[$1.key] = [customDNS] } updateDNSConfigure(dnsDic) } - @objc func revertDns() { - updateDNSConfigure(savedDns) - savedDns.removeAll() + @objc func revertDNS() { + guard savedDNS.count > 0 else { return } + updateDNSConfigure(savedDNS) + savedDNS.removeAll() + UserDefaults.standard.removeObject(forKey: MetaDNS.savedDNSKey) } func getAllDns() -> [String: [String]] { diff --git a/ProxyConfigHelper/ProxyConfigHelper.swift b/ProxyConfigHelper/ProxyConfigHelper.swift index 56e3a3b..4a30839 100644 --- a/ProxyConfigHelper/ProxyConfigHelper.swift +++ b/ProxyConfigHelper/ProxyConfigHelper.swift @@ -132,12 +132,13 @@ extension ProxyConfigHelper: ProxyConfigRemoteProcessProtocol { } } - func updateTun(state: Bool) { + func updateTun(state: Bool, dns: String) { DispatchQueue.main.async { + self.metaDNS.setCustomDNS(dns) if state { - self.metaDNS.updateDns() + self.metaDNS.hijackDNS() } else { - self.metaDNS.revertDns() + self.metaDNS.revertDNS() } self.metaDNS.flushDnsCache() } diff --git a/ProxyConfigHelper/ProxyConfigRemoteProcessProtocol.swift b/ProxyConfigHelper/ProxyConfigRemoteProcessProtocol.swift index dad672b..a220345 100644 --- a/ProxyConfigHelper/ProxyConfigRemoteProcessProtocol.swift +++ b/ProxyConfigHelper/ProxyConfigRemoteProcessProtocol.swift @@ -13,7 +13,7 @@ protocol ProxyConfigRemoteProcessProtocol { func startMeta(path: String, confPath: String, confFilePath: String, confJSON: String, reply: @escaping (String?) -> Void) func stopMeta() - func updateTun(state: Bool) + func updateTun(state: Bool, dns: String) func getUsedPorts(reply: @escaping (String?) -> Void)