diff --git a/README.md b/README.md index d7105e3..cd33292 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # ShadowsocksX-NG -Current version is 1.0 Beta +Current version is 1.1 [![Build Status](https://travis-ci.org/qiuyuzhou/ShadowsocksX-NG.svg?branch=develop)](https://travis-ci.org/qiuyuzhou/ShadowsocksX-NG) diff --git a/ShadowsocksX-NG.xcodeproj/project.pbxproj b/ShadowsocksX-NG.xcodeproj/project.pbxproj index f24e94b..479739d 100644 --- a/ShadowsocksX-NG.xcodeproj/project.pbxproj +++ b/ShadowsocksX-NG.xcodeproj/project.pbxproj @@ -17,6 +17,7 @@ 9B0BFFEB1D0460A70040E62B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9B0BFFEA1D0460A70040E62B /* Assets.xcassets */; }; 9B0BFFEE1D0460A70040E62B /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9B0BFFEC1D0460A70040E62B /* MainMenu.xib */; }; 9B0BFFF91D0460A70040E62B /* ShadowsocksX_NGTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B0BFFF81D0460A70040E62B /* ShadowsocksX_NGTests.swift */; }; + 9B0D55461D2CC85400A4A8E2 /* ProxyPreferencesController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9B0D55481D2CC85400A4A8E2 /* ProxyPreferencesController.xib */; }; 9B172A6A1D0ADDDD00B87B9A /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9B172A6C1D0ADDDD00B87B9A /* Localizable.strings */; }; 9B2491B41D0ACC3A003BBECC /* PreferencesWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9B2491B61D0ACC3A003BBECC /* PreferencesWindowController.xib */; }; 9B2491B71D0ACC3E003BBECC /* AdvPreferencesWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9B2491B91D0ACC3E003BBECC /* AdvPreferencesWindowController.xib */; }; @@ -38,6 +39,9 @@ 9B3FFF4C1D09D8F70019A709 /* install_helper.sh in Resources */ = {isa = PBXBuildFile; fileRef = 9B3FFF4B1D09D8F70019A709 /* install_helper.sh */; }; 9B3FFF4F1D09D9D50019A709 /* ProxyConfHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B3FFF4E1D09D9D50019A709 /* ProxyConfHelper.m */; }; 9B3FFF541D09E2D10019A709 /* proxy_conf_helper in Resources */ = {isa = PBXBuildFile; fileRef = 9B3FFF441D09CD3B0019A709 /* proxy_conf_helper */; }; + 9BA04B231D23D5A5005AAD7F /* ProxyConfTool.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BA04B221D23D5A5005AAD7F /* ProxyConfTool.m */; }; + 9BA04B261D24044D005AAD7F /* ProxyPreferencesController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BA04B241D24044D005AAD7F /* ProxyPreferencesController.swift */; }; + 9BB706A71D1B982300551F0E /* SWBApplication.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BB706A51D1B982300551F0E /* SWBApplication.m */; }; 9BE8FBBF1D0B211600CAFD01 /* libcrypto.1.0.0.dylib in Resources */ = {isa = PBXBuildFile; fileRef = 9BE8FBBD1D0B1FB900CAFD01 /* libcrypto.1.0.0.dylib */; }; 9BEEF0691D04D4D500FC52B3 /* install_ss_local.sh in Resources */ = {isa = PBXBuildFile; fileRef = 9BEEF0651D04CB8500FC52B3 /* install_ss_local.sh */; }; 9BEEF06A1D04D4D500FC52B3 /* start_ss_local.sh in Resources */ = {isa = PBXBuildFile; fileRef = 9BEEF0661D04CE8D00FC52B3 /* start_ss_local.sh */; }; @@ -104,13 +108,15 @@ 9B0BFFF41D0460A70040E62B /* ShadowsocksX-NGTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "ShadowsocksX-NGTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 9B0BFFF81D0460A70040E62B /* ShadowsocksX_NGTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShadowsocksX_NGTests.swift; sourceTree = ""; }; 9B0BFFFA1D0460A70040E62B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 9B0D55451D2CC1B800A4A8E2 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/MainMenu.strings"; sourceTree = ""; }; + 9B0D554A1D2CC85E00A4A8E2 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/ProxyPreferencesController.strings"; sourceTree = ""; }; + 9B0D554B1D2CC87400A4A8E2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ProxyPreferencesController.xib; sourceTree = ""; }; 9B172A5D1D0ACEA100B87B9A /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/AdvPreferencesWindowController.strings"; sourceTree = ""; }; 9B172A601D0ADA5B00B87B9A /* genstrings.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = genstrings.py; sourceTree = ""; }; 9B172A6B1D0ADDDD00B87B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/Localizable.strings; sourceTree = ""; }; 9B172A6D1D0ADDE800B87B9A /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = ""; }; 9B2491B51D0ACC3A003BBECC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/PreferencesWindowController.xib; sourceTree = ""; }; 9B2491B81D0ACC3E003BBECC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/AdvPreferencesWindowController.xib; sourceTree = ""; }; - 9B2491BC1D0ACC49003BBECC /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/MainMenu.strings"; sourceTree = ""; }; 9B3FFF0C1D05FEB30019A709 /* Utils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Utils.swift; sourceTree = ""; }; 9B3FFF131D0705810019A709 /* Notifications.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Notifications.swift; sourceTree = ""; }; 9B3FFF151D072FDE0019A709 /* LaunchAtLoginController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LaunchAtLoginController.h; sourceTree = ""; }; @@ -136,6 +142,11 @@ 9B3FFF4E1D09D9D50019A709 /* ProxyConfHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProxyConfHelper.m; sourceTree = ""; }; 9B3FFF501D09DAEA0019A709 /* proxy_conf_helper_version.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = proxy_conf_helper_version.h; sourceTree = ""; }; 9B3FFF511D09DBA20019A709 /* ShadowsocksX-NG-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ShadowsocksX-NG-Bridging-Header.h"; sourceTree = ""; }; + 9BA04B211D23D5A5005AAD7F /* ProxyConfTool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProxyConfTool.h; sourceTree = ""; }; + 9BA04B221D23D5A5005AAD7F /* ProxyConfTool.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProxyConfTool.m; sourceTree = ""; }; + 9BA04B241D24044D005AAD7F /* ProxyPreferencesController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProxyPreferencesController.swift; sourceTree = ""; }; + 9BB706A51D1B982300551F0E /* SWBApplication.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SWBApplication.m; sourceTree = ""; }; + 9BB706A61D1B982300551F0E /* SWBApplication.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SWBApplication.h; sourceTree = ""; }; 9BE8FBBD1D0B1FB900CAFD01 /* libcrypto.1.0.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libcrypto.1.0.0.dylib; sourceTree = ""; }; 9BE8FBC11D0B71CF00CAFD01 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/PreferencesWindowController.strings"; sourceTree = ""; }; 9BEEF0651D04CB8500FC52B3 /* install_ss_local.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = install_ss_local.sh; sourceTree = ""; }; @@ -247,6 +258,8 @@ 9B0BFFE71D0460A70040E62B /* ShadowsocksX-NG */ = { isa = PBXGroup; children = ( + 9BB706A51D1B982300551F0E /* SWBApplication.m */, + 9BB706A61D1B982300551F0E /* SWBApplication.h */, 9B3FFF511D09DBA20019A709 /* ShadowsocksX-NG-Bridging-Header.h */, 9B3FFF151D072FDE0019A709 /* LaunchAtLoginController.h */, 9B3FFF161D072FDE0019A709 /* LaunchAtLoginController.m */, @@ -267,6 +280,8 @@ 9B3FFF4D1D09D9D50019A709 /* ProxyConfHelper.h */, 9B3FFF4E1D09D9D50019A709 /* ProxyConfHelper.m */, 9B3FFF501D09DAEA0019A709 /* proxy_conf_helper_version.h */, + 9BA04B211D23D5A5005AAD7F /* ProxyConfTool.h */, + 9BA04B221D23D5A5005AAD7F /* ProxyConfTool.m */, ); path = "ShadowsocksX-NG"; sourceTree = ""; @@ -290,6 +305,8 @@ 9B2491B61D0ACC3A003BBECC /* PreferencesWindowController.xib */, 9BEEF0791D05631500FC52B3 /* AdvPreferencesWindowController.swift */, 9B2491B91D0ACC3E003BBECC /* AdvPreferencesWindowController.xib */, + 9BA04B241D24044D005AAD7F /* ProxyPreferencesController.swift */, + 9B0D55481D2CC85400A4A8E2 /* ProxyPreferencesController.xib */, ); name = UI; sourceTree = ""; @@ -431,6 +448,7 @@ 9B3FFF541D09E2D10019A709 /* proxy_conf_helper in Resources */, 9BEEF0691D04D4D500FC52B3 /* install_ss_local.sh in Resources */, 9B172A6A1D0ADDDD00B87B9A /* Localizable.strings in Resources */, + 9B0D55461D2CC85400A4A8E2 /* ProxyPreferencesController.xib in Resources */, 9B2491B41D0ACC3A003BBECC /* PreferencesWindowController.xib in Resources */, 9B3FFF291D08A1DF0019A709 /* user-rule.txt in Resources */, 9BEEF06A1D04D4D500FC52B3 /* start_ss_local.sh in Resources */, @@ -593,9 +611,11 @@ files = ( 9B3FFF171D072FDE0019A709 /* LaunchAtLoginController.m in Sources */, 9B3FFF4F1D09D9D50019A709 /* ProxyConfHelper.m in Sources */, + 9BB706A71D1B982300551F0E /* SWBApplication.m in Sources */, 9B3FFF1E1D0732660019A709 /* Utils.m in Sources */, 9B3FFF321D08CEE40019A709 /* SWBQRCodeWindowController.m in Sources */, 9B3FFF211D08826E0019A709 /* PACUtils.swift in Sources */, + 9BA04B261D24044D005AAD7F /* ProxyPreferencesController.swift in Sources */, 9B3FFF141D0705810019A709 /* Notifications.swift in Sources */, 9BEEF0701D04DDB100FC52B3 /* ServerProfileManager.swift in Sources */, 9BEEF07B1D05631500FC52B3 /* AdvPreferencesWindowController.swift in Sources */, @@ -603,6 +623,7 @@ 9B3FFF0D1D05FEB30019A709 /* Utils.swift in Sources */, 9BEEF0751D04EF3E00FC52B3 /* PreferencesWindowController.swift in Sources */, 9B0BFFE91D0460A70040E62B /* AppDelegate.swift in Sources */, + 9BA04B231D23D5A5005AAD7F /* ProxyConfTool.m in Sources */, 9BEEF0781D04FE8A00FC52B3 /* LaunchAgentUtils.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -643,11 +664,20 @@ isa = PBXVariantGroup; children = ( 9B0BFFED1D0460A70040E62B /* Base */, - 9B2491BC1D0ACC49003BBECC /* zh-Hans */, + 9B0D55451D2CC1B800A4A8E2 /* zh-Hans */, ); name = MainMenu.xib; sourceTree = ""; }; + 9B0D55481D2CC85400A4A8E2 /* ProxyPreferencesController.xib */ = { + isa = PBXVariantGroup; + children = ( + 9B0D554A1D2CC85E00A4A8E2 /* zh-Hans */, + 9B0D554B1D2CC87400A4A8E2 /* Base */, + ); + name = ProxyPreferencesController.xib; + sourceTree = ""; + }; 9B172A6C1D0ADDDD00B87B9A /* Localizable.strings */ = { isa = PBXVariantGroup; children = ( diff --git a/ShadowsocksX-NG/AppDelegate.swift b/ShadowsocksX-NG/AppDelegate.swift index 11a6c6b..74b1b1a 100644 --- a/ShadowsocksX-NG/AppDelegate.swift +++ b/ShadowsocksX-NG/AppDelegate.swift @@ -15,6 +15,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele var qrcodeWinCtrl: SWBQRCodeWindowController! var preferencesWinCtrl: PreferencesWindowController! var advPreferencesWinCtrl: AdvPreferencesWindowController! + var proxyPreferencesWinCtrl: ProxyPreferencesController! var launchAtLoginController: LaunchAtLoginController = LaunchAtLoginController() @@ -52,7 +53,8 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele "LocalSocks5.Timeout": NSNumber(unsignedInteger: 60), "LocalSocks5.EnableUDPRelay": NSNumber(bool: false), "LocalSocks5.EnableVerboseMode": NSNumber(bool: false), - "GFWListURL": "https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt" + "GFWListURL": "https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt", + "AutoConfigureNetworkServices": NSNumber(bool: true) ]) statusItem = NSStatusBar.systemStatusBar().statusItemWithLength(20) @@ -63,6 +65,12 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele let notifyCenter = NSNotificationCenter.defaultCenter() + notifyCenter.addObserverForName(NOTIFY_ADV_PROXY_CONF_CHANGED, object: nil, queue: nil + , usingBlock: { + (note) in + self.applyConfig() + } + ) notifyCenter.addObserverForName(NOTIFY_SERVER_PROFILES_CHANGED, object: nil, queue: nil , usingBlock: { (note) in @@ -81,7 +89,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele if let userInfo = note.userInfo { let urls: [NSURL] = userInfo["urls"] as! [NSURL] - let mgr = ServerProfileManager() + let mgr = ServerProfileManager.instance var isChanged = false for url in urls { @@ -191,8 +199,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele @IBAction func showQRCodeForCurrentServer(sender: NSMenuItem) { var errMsg: String? - let mgr = ServerProfileManager() - if let profile = mgr.getActiveProfile() { + if let profile = ServerProfileManager.instance.getActiveProfile() { if profile.isValid() { // Show window if qrcodeWinCtrl != nil{ @@ -273,9 +280,19 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele ctrl.window?.makeKeyAndOrderFront(self) } + @IBAction func editProxyPreferences(sender: NSObject) { + if proxyPreferencesWinCtrl != nil { + proxyPreferencesWinCtrl.close() + } + proxyPreferencesWinCtrl = ProxyPreferencesController(windowNibName: "ProxyPreferencesController") + proxyPreferencesWinCtrl.showWindow(self) + NSApp.activateIgnoringOtherApps(true) + proxyPreferencesWinCtrl.window?.makeKeyAndOrderFront(self) + } + @IBAction func selectServer(sender: NSMenuItem) { let index = sender.tag - let spMgr = ServerProfileManager() + let spMgr = ServerProfileManager.instance let newProfile = spMgr.profiles[index] if newProfile.uuid != spMgr.activeProfileId { spMgr.setActiveProfiledId(newProfile.uuid) @@ -345,7 +362,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele } func updateServersMenu() { - let mgr = ServerProfileManager() + let mgr = ServerProfileManager.instance serversMenuItem.submenu?.removeAllItems() let preferencesItem = serversPreferencesMenuItem diff --git a/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Contents.json b/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Contents.json old mode 100644 new mode 100755 index db41bc0..7cd4f8e --- a/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -3,61 +3,61 @@ { "size" : "16x16", "idiom" : "mac", - "filename" : "Icon_16x16.png", + "filename" : "icon_16x16.png", "scale" : "1x" }, { "size" : "16x16", "idiom" : "mac", - "filename" : "Icon_16x16@2x.png", + "filename" : "icon_16x16@2x.png", "scale" : "2x" }, { "size" : "32x32", "idiom" : "mac", - "filename" : "Icon_32x32.png", + "filename" : "icon_32x32.png", "scale" : "1x" }, { "size" : "32x32", "idiom" : "mac", - "filename" : "Icon_32x32@2x.png", + "filename" : "icon_32x32@2x.png", "scale" : "2x" }, { "size" : "128x128", "idiom" : "mac", - "filename" : "Icon_128x128.png", + "filename" : "icon_128x128.png", "scale" : "1x" }, { "size" : "128x128", "idiom" : "mac", - "filename" : "Icon_128x128@2x.png", + "filename" : "icon_128x128@2x.png", "scale" : "2x" }, { "size" : "256x256", "idiom" : "mac", - "filename" : "Icon_256x256.png", + "filename" : "icon_256x256.png", "scale" : "1x" }, { "size" : "256x256", "idiom" : "mac", - "filename" : "Icon_256x256@2x.png", + "filename" : "icon_256x256@2x.png", "scale" : "2x" }, { "size" : "512x512", "idiom" : "mac", - "filename" : "Icon_512x512.png", + "filename" : "icon_512x512.png", "scale" : "1x" }, { "size" : "512x512", "idiom" : "mac", - "filename" : "Icon_512x512@2x.png", + "filename" : "icon_512x512@2x.png", "scale" : "2x" } ], diff --git a/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_128x128.png b/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_128x128.png old mode 100644 new mode 100755 index 3715a3a..e37e4b5 Binary files a/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_128x128.png and b/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_128x128.png differ diff --git a/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_128x128@2x.png b/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_128x128@2x.png old mode 100644 new mode 100755 index 2efde03..8dc10c0 Binary files a/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_128x128@2x.png and b/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_128x128@2x.png differ diff --git a/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_16x16.png b/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_16x16.png old mode 100644 new mode 100755 index b023771..749fa64 Binary files a/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_16x16.png and b/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_16x16.png differ diff --git a/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_16x16@2x.png b/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_16x16@2x.png old mode 100644 new mode 100755 index bffb047..07f5a24 Binary files a/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_16x16@2x.png and b/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_16x16@2x.png differ diff --git a/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_256x256.png b/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_256x256.png old mode 100644 new mode 100755 index 6a5a960..8dc10c0 Binary files a/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_256x256.png and b/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_256x256.png differ diff --git a/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_256x256@2x.png b/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_256x256@2x.png old mode 100644 new mode 100755 index f5a2e55..21b4a19 Binary files a/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_256x256@2x.png and b/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_256x256@2x.png differ diff --git a/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_32x32.png b/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_32x32.png old mode 100644 new mode 100755 index a895ebd..f46c874 Binary files a/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_32x32.png and b/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_32x32.png differ diff --git a/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_32x32@2x.png b/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_32x32@2x.png old mode 100644 new mode 100755 index b06e676..cf80929 Binary files a/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_32x32@2x.png and b/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_32x32@2x.png differ diff --git a/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_512x512.png b/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_512x512.png old mode 100644 new mode 100755 index baa6863..608e1d9 Binary files a/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_512x512.png and b/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_512x512.png differ diff --git a/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_512x512@2x.png b/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_512x512@2x.png old mode 100644 new mode 100755 index 052d9f4..70e8eb7 Binary files a/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_512x512@2x.png and b/ShadowsocksX-NG/Assets.xcassets/AppIcon.appiconset/Icon_512x512@2x.png differ diff --git a/ShadowsocksX-NG/Base.lproj/MainMenu.xib b/ShadowsocksX-NG/Base.lproj/MainMenu.xib index cab9deb..79c059f 100644 --- a/ShadowsocksX-NG/Base.lproj/MainMenu.xib +++ b/ShadowsocksX-NG/Base.lproj/MainMenu.xib @@ -14,10 +14,10 @@ - - + + - + @@ -26,7 +26,7 @@ - + @@ -38,23 +38,37 @@ - + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ShadowsocksX-NG/Base.lproj/PreferencesWindowController.xib b/ShadowsocksX-NG/Base.lproj/PreferencesWindowController.xib index 51139b5..07f4c19 100644 --- a/ShadowsocksX-NG/Base.lproj/PreferencesWindowController.xib +++ b/ShadowsocksX-NG/Base.lproj/PreferencesWindowController.xib @@ -339,7 +339,7 @@ DQ - + diff --git a/ShadowsocksX-NG/Base.lproj/ProxyPreferencesController.xib b/ShadowsocksX-NG/Base.lproj/ProxyPreferencesController.xib new file mode 100644 index 0000000..ef62b91 --- /dev/null +++ b/ShadowsocksX-NG/Base.lproj/ProxyPreferencesController.xib @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + NSNegateBoolean + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ShadowsocksX-NG/Info.plist b/ShadowsocksX-NG/Info.plist index 01b772e..7e4cccf 100644 --- a/ShadowsocksX-NG/Info.plist +++ b/ShadowsocksX-NG/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.0 + 1.1 CFBundleSignature ???? CFBundleURLTypes @@ -36,7 +36,7 @@ CFBundleVersion - 3 + 1 LSApplicationCategoryType public.app-category.utilities LSMinimumSystemVersion @@ -48,6 +48,6 @@ NSMainNibFile MainMenu NSPrincipalClass - NSApplication + SWBApplication diff --git a/ShadowsocksX-NG/LaunchAgentUtils.swift b/ShadowsocksX-NG/LaunchAgentUtils.swift index 1488fe3..a00a9c1 100644 --- a/ShadowsocksX-NG/LaunchAgentUtils.swift +++ b/ShadowsocksX-NG/LaunchAgentUtils.swift @@ -9,9 +9,9 @@ import Foundation let SS_LOCAL_VERSION = "2.4.6" -let APP_SUPPORT_DIR = "/Library/Application Support/ShadowsocksX-NE/" +let APP_SUPPORT_DIR = "/Library/Application Support/ShadowsocksX-NG/" let LAUNCH_AGENT_DIR = "/Library/LaunchAgents/" -let LAUNCH_AGENT_CONF_NAME = "com.qiuyuzhou.shadowsocksX-NE.local.plist" +let LAUNCH_AGENT_CONF_NAME = "com.qiuyuzhou.shadowsocksX-NG.local.plist" func getFileSHA1Sum(filepath: String) -> String { @@ -44,7 +44,7 @@ func generateSSLocalLauchAgentPlist() -> Bool { // For a complete listing of the keys, see the launchd.plist manual page. let dict: NSMutableDictionary = [ - "Label": "com.qiuyuzhou.shadowsocksX-NE.local", + "Label": "com.qiuyuzhou.shadowsocksX-NG.local", "WorkingDirectory": NSHomeDirectory() + APP_SUPPORT_DIR, "KeepAlive": true, "StandardOutPath": logFilePath, @@ -147,7 +147,7 @@ func removeSSLocalConfFile() { func SyncSSLocal() { var changed: Bool = false changed = changed || generateSSLocalLauchAgentPlist() - let mgr = ServerProfileManager() + let mgr = ServerProfileManager.instance if mgr.activeProfileId != nil { changed = changed || writeSSLocalConfFile((mgr.getActiveProfile()?.toJsonConfig())!) diff --git a/ShadowsocksX-NG/Notifications.swift b/ShadowsocksX-NG/Notifications.swift index bdfac67..69b798f 100644 --- a/ShadowsocksX-NG/Notifications.swift +++ b/ShadowsocksX-NG/Notifications.swift @@ -9,4 +9,5 @@ import Foundation let NOTIFY_SERVER_PROFILES_CHANGED = "NOTIFY_SERVER_PROFILES_CHANGED" +let NOTIFY_ADV_PROXY_CONF_CHANGED = "NOTIFY_ADV_PROXY_CONF_CHANGED" let NOTIFY_ADV_CONF_CHANGED = "NOTIFY_ADV_CONF_CHANGED" \ No newline at end of file diff --git a/ShadowsocksX-NG/PACUtils.swift b/ShadowsocksX-NG/PACUtils.swift index 5e9fad9..592b756 100644 --- a/ShadowsocksX-NG/PACUtils.swift +++ b/ShadowsocksX-NG/PACUtils.swift @@ -9,7 +9,9 @@ import Foundation import Alamofire -let PACRulesDirPath = NSHomeDirectory() + "/.ShadowsocksX-NE/" +let OldErrorPACRulesDirPath = NSHomeDirectory() + "/.ShadowsocksX-NE/" + +let PACRulesDirPath = NSHomeDirectory() + "/.ShadowsocksX-NG/" let PACUserRuleFilePath = PACRulesDirPath + "user-rule.txt" let PACFilePath = PACRulesDirPath + "gfwlist.js" let GFWListFilePath = PACRulesDirPath + "gfwlist.txt" @@ -17,12 +19,23 @@ let GFWListFilePath = PACRulesDirPath + "gfwlist.txt" // Because of LocalSocks5.ListenPort may be changed func SyncPac() { + var needGenerate = false + let nowSocks5Port = NSUserDefaults.standardUserDefaults().integerForKey("LocalSocks5.ListenPort") let oldSocks5Port = NSUserDefaults.standardUserDefaults().integerForKey("LocalSocks5.ListenPort.Old") if nowSocks5Port != oldSocks5Port { - GeneratePACFile() + needGenerate = true NSUserDefaults.standardUserDefaults().setInteger(nowSocks5Port, forKey: "LocalSocks5.ListenPort.Old") } + + let fileMgr = NSFileManager.defaultManager() + if !fileMgr.fileExistsAtPath(PACRulesDirPath) { + needGenerate = true + } + + if needGenerate { + GeneratePACFile() + } } @@ -30,8 +43,12 @@ func GeneratePACFile() -> Bool { let fileMgr = NSFileManager.defaultManager() // Maker the dir if rulesDirPath is not exesited. if !fileMgr.fileExistsAtPath(PACRulesDirPath) { - try! fileMgr.createDirectoryAtPath(PACRulesDirPath - , withIntermediateDirectories: true, attributes: nil) + if fileMgr.fileExistsAtPath(OldErrorPACRulesDirPath) { + try! fileMgr.moveItemAtPath(OldErrorPACRulesDirPath, toPath: PACRulesDirPath) + } else { + try! fileMgr.createDirectoryAtPath(PACRulesDirPath + , withIntermediateDirectories: true, attributes: nil) + } } // If gfwlist.txt is not exsited, copy from bundle @@ -40,7 +57,7 @@ func GeneratePACFile() -> Bool { try! fileMgr.copyItemAtPath(src!, toPath: GFWListFilePath) } - // If gfwlist.txt is not exsited, copy from bundle + // If user-rule.txt is not exsited, copy from bundle if !fileMgr.fileExistsAtPath(PACUserRuleFilePath) { let src = NSBundle.mainBundle().pathForResource("user-rule", ofType: "txt") try! fileMgr.copyItemAtPath(src!, toPath: PACUserRuleFilePath) diff --git a/ShadowsocksX-NG/PreferencesWindowController.swift b/ShadowsocksX-NG/PreferencesWindowController.swift index b3afebf..45fc92a 100644 --- a/ShadowsocksX-NG/PreferencesWindowController.swift +++ b/ShadowsocksX-NG/PreferencesWindowController.swift @@ -36,7 +36,7 @@ class PreferencesWindowController: NSWindowController // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file. defaults = NSUserDefaults.standardUserDefaults() - profileMgr = ServerProfileManager() + profileMgr = ServerProfileManager.instance methodTextField.addItemsWithObjectValues([ "aes-128-cfb", diff --git a/ShadowsocksX-NG/ProxyConfHelper.m b/ShadowsocksX-NG/ProxyConfHelper.m index 9f336a3..282bbc7 100644 --- a/ShadowsocksX-NG/ProxyConfHelper.m +++ b/ShadowsocksX-NG/ProxyConfHelper.m @@ -99,19 +99,46 @@ } } ++ (void)addArguments4ManualSpecifyNetworkServices:(NSMutableArray*) args { + NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; + + if (![defaults boolForKey:@"AutoConfigureNetworkServices"]) { + NSArray* serviceKeys = [defaults arrayForKey:@"Proxy4NetworkServices"]; + if (serviceKeys) { + for (NSString* key in serviceKeys) { + [args addObject:@"--network-service"]; + [args addObject:key]; + } + } + } +} + + (void)enablePACProxy { - NSString* urlString = [NSString stringWithFormat:@"%@/.ShadowsocksX-NE/gfwlist.js", NSHomeDirectory()]; + NSString* urlString = [NSString stringWithFormat:@"%@/.ShadowsocksX-NG/gfwlist.js", NSHomeDirectory()]; NSURL* url = [NSURL fileURLWithPath:urlString]; - [self callHelper:@[@"--mode", @"auto", @"--pac-url", [url absoluteString]]]; + + NSMutableArray* args = [@[@"--mode", @"auto", @"--pac-url", [url absoluteString]]mutableCopy]; + + [self addArguments4ManualSpecifyNetworkServices:args]; + + [self callHelper:args]; } + (void)enableGlobalProxy { NSUInteger port = [[NSUserDefaults standardUserDefaults]integerForKey:@"LocalSocks5.ListenPort"]; - [self callHelper:@[@"--mode", @"global", @"--port", [NSString stringWithFormat:@"%lu", (unsigned long)port] ]]; + + NSMutableArray* args = [@[@"--mode", @"global", @"--port" + , [NSString stringWithFormat:@"%lu", (unsigned long)port]]mutableCopy]; + + [self addArguments4ManualSpecifyNetworkServices:args]; + + [self callHelper:args]; } + (void)disableProxy { - [self callHelper:@[@"--mode", @"off"]]; + NSMutableArray* args = [@[@"--mode", @"off"]mutableCopy]; + [self addArguments4ManualSpecifyNetworkServices:args]; + [self callHelper:args]; } @end diff --git a/ShadowsocksX-NG/ProxyConfTool.h b/ShadowsocksX-NG/ProxyConfTool.h new file mode 100644 index 0000000..467abdf --- /dev/null +++ b/ShadowsocksX-NG/ProxyConfTool.h @@ -0,0 +1,16 @@ +// +// ProxyConfTool.h +// ShadowsocksX-NG +// +// Created by 邱宇舟 on 16/6/29. +// Copyright © 2016年 qiuyuzhou. All rights reserved. +// + +#import + + +@interface ProxyConfTool : NSObject + ++(NSArray*)networkServicesList; + +@end diff --git a/ShadowsocksX-NG/ProxyConfTool.m b/ShadowsocksX-NG/ProxyConfTool.m new file mode 100644 index 0000000..69705dd --- /dev/null +++ b/ShadowsocksX-NG/ProxyConfTool.m @@ -0,0 +1,52 @@ +// +// ProxyConfTool.m +// ShadowsocksX-NG +// +// Created by 邱宇舟 on 16/6/29. +// Copyright © 2016年 qiuyuzhou. All rights reserved. +// + +#import "ProxyConfTool.h" +#import + +//https://developer.apple.com/library/mac/documentation/Networking/Conceptual/SystemConfigFrameworks/SC_Intro/SC_Intro.html + +@implementation ProxyConfTool + + ++(NSArray*)networkServicesList { + NSMutableArray* results = [NSMutableArray array]; + + SCPreferencesRef prefRef = SCPreferencesCreate(nil, CFSTR("Shadowsocks"), nil); + NSDictionary *sets = (__bridge NSDictionary *)SCPreferencesGetValue(prefRef, kSCPrefNetworkServices); + // 遍历系统中的网络设备列表 + for (NSString *key in [sets allKeys]) { + NSMutableDictionary *service = [sets objectForKey:key]; + NSString *userDefinedName = [service valueForKey:(__bridge NSString *)kSCPropUserDefinedName]; +// NSString *hardware = [service valueForKeyPath:@"Interface.Hardware"]; +// NSString *deviceName = [service valueForKeyPath:@"Interface.DeviceName"]; +// NSString *deviceType = [service valueForKeyPath:@"Interface.Type"]; + + BOOL isActive = ![service objectForKey:(NSString *)kSCResvInactive]; + // NSLog(@"%@", hardware); +// NSLog(@"%@-------------------", key); +// for(NSString* key in service) { +// NSLog(@"key=%@ value=%@", key, [service objectForKey:key]); +// } +// + if (isActive) { + if (isActive && userDefinedName) { + NSDictionary* v = @{ + @"key": key, + @"userDefinedName": userDefinedName, + }; + [results addObject:v]; + } + } + } + + return results; +} + + +@end diff --git a/ShadowsocksX-NG/ProxyPreferencesController.swift b/ShadowsocksX-NG/ProxyPreferencesController.swift new file mode 100644 index 0000000..8fc867e --- /dev/null +++ b/ShadowsocksX-NG/ProxyPreferencesController.swift @@ -0,0 +1,93 @@ +// +// ProxyPreferencesController.swift +// ShadowsocksX-NG +// +// Created by 邱宇舟 on 16/6/29. +// Copyright © 2016年 qiuyuzhou. All rights reserved. +// + +import Cocoa + +class ProxyPreferencesController: NSWindowController, NSTableViewDataSource, NSTableViewDelegate { + + var networkServices: NSArray! + var selectedNetworkServices: NSMutableSet! + + var autoConfigureNetworkServices: Bool = true + + @IBOutlet var autoConfigCheckBox: NSButton! + + @IBOutlet var tableView: NSTableView! + + override func windowDidLoad() { + super.windowDidLoad() + + // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file. + let defaults = NSUserDefaults.standardUserDefaults() + self.setValue(defaults.boolForKey("AutoConfigureNetworkServices"), forKey: "autoConfigureNetworkServices") + + if let services = defaults.arrayForKey("Proxy4NetworkServices") { + selectedNetworkServices = NSMutableSet(array: services) + } else { + selectedNetworkServices = NSMutableSet() + } + + networkServices = ProxyConfTool.networkServicesList() + tableView.reloadData() + } + + @IBAction func ok(sender: NSObject){ + ProxyConfHelper.disableProxy() + + let defaults = NSUserDefaults.standardUserDefaults() + defaults.setValue(selectedNetworkServices.allObjects, forKeyPath: "Proxy4NetworkServices") + defaults.setBool(autoConfigureNetworkServices, forKey: "AutoConfigureNetworkServices") + + defaults.synchronize() + + window?.performClose(self) + + NSNotificationCenter.defaultCenter() + .postNotificationName(NOTIFY_ADV_PROXY_CONF_CHANGED, object: nil) + } + + @IBAction func cancel(sender: NSObject){ + window?.performClose(self) + } + + //-------------------------------------------------- + // For NSTableViewDataSource + func numberOfRowsInTableView(tableView: NSTableView) -> Int { + if networkServices != nil { + return networkServices.count + } + return 0; + } + + func tableView(tableView: NSTableView, objectValueForTableColumn tableColumn: NSTableColumn? + , row: Int) -> AnyObject? { + let cell = tableColumn!.dataCell as! NSButtonCell + + let key = networkServices[row]["key"] as! String + if selectedNetworkServices.containsObject(key) { + cell.state = 1 + } else { + cell.state = 0 + } + let userDefinedName = networkServices[row]["userDefinedName"] as! String + cell.title = userDefinedName + return cell + } + + func tableView(tableView: NSTableView, setObjectValue object: AnyObject? + , forTableColumn tableColumn: NSTableColumn?, row: Int) { + let key = networkServices[row]["key"] as! String + +// NSLog("%d", object!.integerValue) + if object!.integerValue == 1 { + selectedNetworkServices.addObject(key) + } else { + selectedNetworkServices.removeObject(key) + } + } +} diff --git a/ShadowsocksX-NG/SWBApplication.h b/ShadowsocksX-NG/SWBApplication.h new file mode 100644 index 0000000..c04a8b6 --- /dev/null +++ b/ShadowsocksX-NG/SWBApplication.h @@ -0,0 +1,11 @@ +// +// Created by clowwindy on 3/1/14. +// Copyright (c) 2014 clowwindy. All rights reserved. +// + +#import +@import AppKit; + + +@interface SWBApplication : NSApplication +@end \ No newline at end of file diff --git a/ShadowsocksX-NG/SWBApplication.m b/ShadowsocksX-NG/SWBApplication.m new file mode 100644 index 0000000..171af4a --- /dev/null +++ b/ShadowsocksX-NG/SWBApplication.m @@ -0,0 +1,49 @@ +// +// Created by clowwindy on 3/1/14. +// Copyright (c) 2014 clowwindy. All rights reserved. +// + +#import "SWBApplication.h" + + +@implementation SWBApplication { + +} + +// Enable Key Shortcuts +// http://stackoverflow.com/questions/970707/cocoa-keyboard-shortcuts-in-dialog-without-an-edit-menu +- (void) sendEvent:(NSEvent *)event { + if ([event type] == NSKeyDown) { + if (([event modifierFlags] & NSDeviceIndependentModifierFlagsMask) == NSCommandKeyMask) { + if ([[event charactersIgnoringModifiers] isEqualToString:@"x"]) { + if ([self sendAction:@selector(cut:) to:nil from:self]) + return; + } + else if ([[event charactersIgnoringModifiers] isEqualToString:@"c"]) { + if ([self sendAction:@selector(copy:) to:nil from:self]) + return; + } + else if ([[event charactersIgnoringModifiers] isEqualToString:@"v"]) { + if ([self sendAction:@selector(paste:) to:nil from:self]) + return; + } + else if ([[event charactersIgnoringModifiers] isEqualToString:@"z"]) { + if ([self sendAction:@selector(undo:) to:nil from:self]) + return; + } + else if ([[event charactersIgnoringModifiers] isEqualToString:@"a"]) { + if ([self sendAction:@selector(selectAll:) to:nil from:self]) + return; + } + } + else if (([event modifierFlags] & NSDeviceIndependentModifierFlagsMask) == (NSCommandKeyMask | NSShiftKeyMask)) { + if ([[event charactersIgnoringModifiers] isEqualToString:@"Z"]) { + if ([self sendAction:@selector(redo:) to:nil from:self]) + return; + } + } + } + [super sendEvent:event]; +} + +@end \ No newline at end of file diff --git a/ShadowsocksX-NG/ServerProfileManager.swift b/ShadowsocksX-NG/ServerProfileManager.swift index 3b678da..f3be6c8 100644 --- a/ShadowsocksX-NG/ServerProfileManager.swift +++ b/ShadowsocksX-NG/ServerProfileManager.swift @@ -10,10 +10,12 @@ import Cocoa class ServerProfileManager: NSObject { + static let instance:ServerProfileManager = ServerProfileManager() + var profiles:[ServerProfile] var activeProfileId: String? - override init() { + private override init() { profiles = [ServerProfile]() let defaults = NSUserDefaults.standardUserDefaults() diff --git a/ShadowsocksX-NG/ShadowsocksX-NG-Bridging-Header.h b/ShadowsocksX-NG/ShadowsocksX-NG-Bridging-Header.h index 186788a..c4ff6cc 100644 --- a/ShadowsocksX-NG/ShadowsocksX-NG-Bridging-Header.h +++ b/ShadowsocksX-NG/ShadowsocksX-NG-Bridging-Header.h @@ -7,4 +7,5 @@ #import "LaunchAtLoginController.h" #import "SWBQRCodeWindowController.h" #import "Utils.h" -#import "ProxyConfHelper.h" \ No newline at end of file +#import "ProxyConfHelper.h" +#import "ProxyConfTool.h" \ No newline at end of file diff --git a/ShadowsocksX-NG/install_ss_local.sh b/ShadowsocksX-NG/install_ss_local.sh index a0b6dcd..dc9cbaa 100755 --- a/ShadowsocksX-NG/install_ss_local.sh +++ b/ShadowsocksX-NG/install_ss_local.sh @@ -8,11 +8,11 @@ cd `dirname "${BASH_SOURCE[0]}"` -mkdir -p "$HOME/Library/Application Support/ShadowsocksX-NE/ss-local-2.4.6" -cp -f ss-local "$HOME/Library/Application Support/ShadowsocksX-NE/ss-local-2.4.6/" -rm -f "$HOME/Library/Application Support/ShadowsocksX-NE/ss-local" -ln -s "$HOME/Library/Application Support/ShadowsocksX-NE/ss-local-2.4.6/ss-local" "$HOME/Library/Application Support/ShadowsocksX-NE/ss-local" +mkdir -p "$HOME/Library/Application Support/ShadowsocksX-NG/ss-local-2.4.6" +cp -f ss-local "$HOME/Library/Application Support/ShadowsocksX-NG/ss-local-2.4.6/" +rm -f "$HOME/Library/Application Support/ShadowsocksX-NG/ss-local" +ln -s "$HOME/Library/Application Support/ShadowsocksX-NG/ss-local-2.4.6/ss-local" "$HOME/Library/Application Support/ShadowsocksX-NG/ss-local" -cp -f libcrypto.1.0.0.dylib "$HOME/Library/Application Support/ShadowsocksX-NE/" +cp -f libcrypto.1.0.0.dylib "$HOME/Library/Application Support/ShadowsocksX-NG/" echo done \ No newline at end of file diff --git a/ShadowsocksX-NG/proxy_conf_helper_version.h b/ShadowsocksX-NG/proxy_conf_helper_version.h index fc73b0f..95c2bbc 100644 --- a/ShadowsocksX-NG/proxy_conf_helper_version.h +++ b/ShadowsocksX-NG/proxy_conf_helper_version.h @@ -9,6 +9,6 @@ #ifndef proxy_conf_helper_version_h #define proxy_conf_helper_version_h -#define kProxyConfHelperVersion @"1.1.0" +#define kProxyConfHelperVersion @"1.2.0" #endif /* proxy_conf_helper_version_h */ diff --git a/ShadowsocksX-NG/reload_conf_ss_local.sh b/ShadowsocksX-NG/reload_conf_ss_local.sh index 95bc22d..c96f790 100755 --- a/ShadowsocksX-NG/reload_conf_ss_local.sh +++ b/ShadowsocksX-NG/reload_conf_ss_local.sh @@ -6,7 +6,7 @@ # Created by 邱宇舟 on 16/6/6. # Copyright © 2016年 qiuyuzhou. All rights reserved. -#launchctl kill SIGHUP "$HOME/Library/LaunchAgents/com.qiuyuzhou.shadowsocksX-NE.local.plist" +#launchctl kill SIGHUP "$HOME/Library/LaunchAgents/com.qiuyuzhou.shadowsocksX-NG.local.plist" -launchctl unload "$HOME/Library/LaunchAgents/com.qiuyuzhou.shadowsocksX-NE.local.plist" -launchctl load "$HOME/Library/LaunchAgents/com.qiuyuzhou.shadowsocksX-NE.local.plist" +launchctl unload "$HOME/Library/LaunchAgents/com.qiuyuzhou.shadowsocksX-NG.local.plist" +launchctl load "$HOME/Library/LaunchAgents/com.qiuyuzhou.shadowsocksX-NG.local.plist" diff --git a/ShadowsocksX-NG/start_ss_local.sh b/ShadowsocksX-NG/start_ss_local.sh index 4499a2d..b4047d3 100755 --- a/ShadowsocksX-NG/start_ss_local.sh +++ b/ShadowsocksX-NG/start_ss_local.sh @@ -6,4 +6,4 @@ # Created by 邱宇舟 on 16/6/6. # Copyright © 2016年 qiuyuzhou. All rights reserved. -launchctl load "$HOME/Library/LaunchAgents/com.qiuyuzhou.shadowsocksX-NE.local.plist" \ No newline at end of file +launchctl load "$HOME/Library/LaunchAgents/com.qiuyuzhou.shadowsocksX-NG.local.plist" \ No newline at end of file diff --git a/ShadowsocksX-NG/stop_ss_local.sh b/ShadowsocksX-NG/stop_ss_local.sh index 4613fde..5a6cf57 100755 --- a/ShadowsocksX-NG/stop_ss_local.sh +++ b/ShadowsocksX-NG/stop_ss_local.sh @@ -8,4 +8,4 @@ -launchctl unload "$HOME/Library/LaunchAgents/com.qiuyuzhou.shadowsocksX-NE.local.plist" \ No newline at end of file +launchctl unload "$HOME/Library/LaunchAgents/com.qiuyuzhou.shadowsocksX-NG.local.plist" \ No newline at end of file diff --git a/ShadowsocksX-NG/zh-Hans.lproj/MainMenu.strings b/ShadowsocksX-NG/zh-Hans.lproj/MainMenu.strings index b574f5b..29dde32 100644 --- a/ShadowsocksX-NG/zh-Hans.lproj/MainMenu.strings +++ b/ShadowsocksX-NG/zh-Hans.lproj/MainMenu.strings @@ -1,60 +1,69 @@ -/* Class = "NSMenuItem"; title = "Global Mode"; ObjectID = "3Sa-e9-VXX"; */ -"3Sa-e9-VXX.title" = "全局模式"; - -/* Class = "NSMenuItem"; title = "Apply User Rules For PAC"; ObjectID = "6qf-cg-HXc"; */ +/* Class = "NSMenuItem"; title = "应用用户自定规则到 PAC"; ObjectID = "6qf-cg-HXc"; */ "6qf-cg-HXc.title" = "应用用户自定规则到 PAC"; -/* Class = "NSMenu"; title = "Servers"; ObjectID = "9Y1-db-3HK"; */ +/* Class = "NSMenuItem"; title = "手动模式"; ObjectID = "8PR-gs-c5N"; */ +"8PR-gs-c5N.title" = "手动模式"; + +/* Class = "NSMenu"; title = "服务器"; ObjectID = "9Y1-db-3HK"; */ "9Y1-db-3HK.title" = "服务器"; -/* Class = "NSMenuItem"; title = "Turn ShadowsocksX On"; ObjectID = "GSu-Tf-StS"; */ +/* Class = "NSMenuItem"; title = "打开 ShadowsocksX"; ObjectID = "GSu-Tf-StS"; */ "GSu-Tf-StS.title" = "打开 ShadowsocksX"; -/* Class = "NSMenu"; title = "ShadowsocksX-NE"; ObjectID = "Hob-KD-bx9"; */ -"Hob-KD-bx9.title" = "ShadowsocksX-NE"; +/* Class = "NSMenu"; title = "ShadowsocksX-NG"; ObjectID = "Hob-KD-bx9"; */ +"Hob-KD-bx9.title" = "ShadowsocksX-NG"; -/* Class = "NSMenuItem"; title = "Show Logs..."; ObjectID = "Jfy-sf-Fhl"; */ +/* Class = "NSMenuItem"; title = "显示日志..."; ObjectID = "Jfy-sf-Fhl"; */ "Jfy-sf-Fhl.title" = "显示日志..."; -/* Class = "NSMenuItem"; title = "About"; ObjectID = "LgB-6g-Gba"; */ +/* Class = "NSMenuItem"; title = "关于"; ObjectID = "LgB-6g-Gba"; */ "LgB-6g-Gba.title" = "关于"; -/* Class = "NSMenuItem"; title = "Server Preferences..."; ObjectID = "M5r-E7-44f"; */ +/* Class = "NSMenuItem"; title = "服务器设置..."; ObjectID = "M5r-E7-44f"; */ "M5r-E7-44f.title" = "服务器设置..."; -/* Class = "NSMenuItem"; title = "Scan QR Code From Screen ..."; ObjectID = "Qe6-bF-paT"; */ +/* Class = "NSMenuItem"; title = "全局模式"; ObjectID = "Mw3-Jm-eXA"; */ +"Mw3-Jm-eXA.title" = "全局模式"; + +/* Class = "NSMenuItem"; title = "扫描屏幕上的二维码..."; ObjectID = "Qe6-bF-paT"; */ "Qe6-bF-paT.title" = "扫描屏幕上的二维码..."; -/* Class = "NSMenuItem"; title = "Show QR Code For Current Server..."; ObjectID = "R6A-96-Zcb"; */ +/* Class = "NSMenuItem"; title = "显示当前服务器的二维码..."; ObjectID = "R6A-96-Zcb"; */ "R6A-96-Zcb.title" = "显示当前服务器的二维码..."; -/* Class = "NSMenuItem"; title = "Update PAC from GFW List"; ObjectID = "TFc-Ec-duM"; */ +/* Class = "NSMenuItem"; title = "从 GFW List 更新PAC"; ObjectID = "TFc-Ec-duM"; */ "TFc-Ec-duM.title" = "从 GFW List 更新PAC"; -/* Class = "NSMenuItem"; title = "Feedback"; ObjectID = "W7u-7g-Gv4"; */ +/* Class = "NSMenuItem"; title = "反馈"; ObjectID = "W7u-7g-Gv4"; */ "W7u-7g-Gv4.title" = "反馈"; -/* Class = "NSMenuItem"; title = "Advance Preference ..."; ObjectID = "bZ3-fy-34d"; */ +/* Class = "NSMenu"; title = "代理"; ObjectID = "YZp-bf-L40"; */ +"YZp-bf-L40.title" = "代理"; + +/* Class = "NSMenuItem"; title = "高级设置..."; ObjectID = "bZ3-fy-34d"; */ "bZ3-fy-34d.title" = "高级设置..."; -/* Class = "NSMenuItem"; title = "Launch At Login"; ObjectID = "eUq-p7-ICK"; */ +/* Class = "NSMenuItem"; title = "代理"; ObjectID = "diI-fB-Rss"; */ +"diI-fB-Rss.title" = "代理"; + +/* Class = "NSMenuItem"; title = "登录时自动启动"; ObjectID = "eUq-p7-ICK"; */ "eUq-p7-ICK.title" = "登录时自动启动"; /* Class = "NSMenuItem"; title = "Showsocks: On"; ObjectID = "fzk-mE-CEV"; */ "fzk-mE-CEV.title" = "Showsocks: On"; -/* Class = "NSMenuItem"; title = "Auto Mode By PAC"; ObjectID = "hOa-5N-3ik"; */ -"hOa-5N-3ik.title" = "PAC自动模式"; +/* Class = "NSMenuItem"; title = "PAC自动模式"; ObjectID = "r07-Gu-aEz"; */ +"r07-Gu-aEz.title" = "PAC自动模式"; -/* Class = "NSMenuItem"; title = "Edit User Rules For PAC..."; ObjectID = "rms-p0-CvB"; */ +/* Class = "NSMenuItem"; title = "编辑PAC用户自定规则..."; ObjectID = "rms-p0-CvB"; */ "rms-p0-CvB.title" = "编辑PAC用户自定规则..."; -/* Class = "NSMenuItem"; title = "Servers"; ObjectID = "u5M-hQ-VSc"; */ +/* Class = "NSMenuItem"; title = "高级设置..."; ObjectID = "sbx-yz-3lO"; */ +"sbx-yz-3lO.title" = "高级设置..."; + +/* Class = "NSMenuItem"; title = "服务器"; ObjectID = "u5M-hQ-VSc"; */ "u5M-hQ-VSc.title" = "服务器"; -/* Class = "NSMenuItem"; title = "Quit"; ObjectID = "vJS-JW-byz"; */ +/* Class = "NSMenuItem"; title = "退出"; ObjectID = "vJS-JW-byz"; */ "vJS-JW-byz.title" = "退出"; - -/* Class = "NSMenuItem"; title = "Manual Mode"; ObjectID = "vRc-N6-z1e"; */ -"vRc-N6-z1e.title" = "手动模式"; diff --git a/ShadowsocksX-NG/zh-Hans.lproj/ProxyPreferencesController.strings b/ShadowsocksX-NG/zh-Hans.lproj/ProxyPreferencesController.strings new file mode 100644 index 0000000..d735f48 --- /dev/null +++ b/ShadowsocksX-NG/zh-Hans.lproj/ProxyPreferencesController.strings @@ -0,0 +1,13 @@ + +/* Class = "NSWindow"; title = "Advance Proxy Preferences"; ObjectID = "F0z-JX-Cv5"; */ +"F0z-JX-Cv5.title" = "高级代理设置"; + +/* Class = "NSButtonCell"; title = "Auto Configure"; ObjectID = "FLv-D9-CRw"; */ +"FLv-D9-CRw.title" = "自动设置"; + +/* Class = "NSButtonCell"; title = "Cancel"; ObjectID = "lsQ-1C-OhG"; */ +"lsQ-1C-OhG.title" = "取消"; + +/* Class = "NSButtonCell"; title = "OK"; ObjectID = "rWE-M6-TvV"; */ +"rWE-M6-TvV.title" = "确定"; + diff --git a/proxy_conf_helper/main.m b/proxy_conf_helper/main.m index 9765c38..600cfe2 100644 --- a/proxy_conf_helper/main.m +++ b/proxy_conf_helper/main.m @@ -45,6 +45,11 @@ int main(int argc, const char * argv[]) [options addOption:"pac-url" flag:'u' description:@"PAC file url for auto mode." argument:&pacURL]; [options addOption:"port" flag:'p' description:@"Listen port for global mode." argument:&portString]; + NSMutableSet* networkServiceKeys = [NSMutableSet set]; + [options addOption:"network-service" flag:'n' description:@"Manual specify the network profile need to set proxy." blockWithArgument:^(NSString* value){ + [networkServiceKeys addObject:value]; + }]; + NSError *error = nil; if (![options parseArgc:argc argv:argv error:&error]) { const char * message = error.localizedDescription.UTF8String; @@ -108,7 +113,18 @@ int main(int argc, const char * argv[]) NSMutableDictionary *dict = [sets objectForKey:key]; NSString *hardware = [dict valueForKeyPath:@"Interface.Hardware"]; // NSLog(@"%@", hardware); - if ([hardware isEqualToString:@"AirPort"] || [hardware isEqualToString:@"Wi-Fi"] || [hardware isEqualToString:@"Ethernet"]) { + BOOL modify = NO; + if ([networkServiceKeys count] > 0) { + if ([networkServiceKeys containsObject:key]) { + modify = YES; + } + } else if ([hardware isEqualToString:@"AirPort"] + || [hardware isEqualToString:@"Wi-Fi"] + || [hardware isEqualToString:@"Ethernet"]) { + modify = YES; + } + + if (modify) { if ([mode isEqualToString:@"auto"]) {