Compare commits

..
38 Commits
Author SHA1 Message Date
Charlie Qiu f03287ec0e Merge branch 'release/1.2' 2016-08-04 16:48:03 +08:00
Charlie Qiu b874a9dc23 Resize server profiles list in the preferences window. 2016-08-04 16:47:00 +08:00
Charlie Qiu 9068970c35 Resize server profiles list in the preferences window. 2016-08-04 00:55:03 +08:00
Charlie Qiu 245770afcf Fix bug #24
避免清空不是由ShadowsocksX-NG设置代理配置。
2016-08-04 00:41:00 +08:00
Charlie Qiu f096ed2b23 Merge branch 'feature/bug23' into develop 2016-08-03 23:51:55 +08:00
Charlie Qiu 2d69aedd17 Merge branch 'pr/21' into develop 2016-08-03 23:51:07 +08:00
Charlie Qiu 7e1dc05b17 Fix bug #23: 没有~/Library/LaunchAgents文件夹启动故障 2016-08-03 23:45:46 +08:00
bjzhou1990 fecc4a9ef5 revert unneed changes 2016-08-02 13:43:51 +08:00
bjzhou1990 995d43a41e add edit user rule window 2016-08-01 15:28:59 +08:00
Charlie Qiu 9e0c650e33 Update README 2016-07-10 18:36:22 +08:00
Qiu Yuzhou 8c1ea5dd38 Merge pull request #14 from jackwish/develop
Move PAC & QRCode menu items to level 2 menu
2016-07-10 18:08:31 +08:00
WANG Zhenhua de8aa45b02 Move PAC & QRCode menu items to level 2 menu
1. Move PAC related items to *Proxy* submenu.
2. Move QR related items to *Server* submenu.
3. Remove some separators of main menu.
2016-07-10 17:52:33 +08:00
Charlie Qiu 03cefc5099 Support drag & drop reorder the server profiles. 2016-07-09 15:10:05 +08:00
Charlie Qiu 6c40f8c167 Change version number to 1.2 2016-07-07 15:56:55 +08:00
Charlie Qiu 810479a40b Fix Assets.xcassets 2016-07-07 15:56:24 +08:00
Charlie Qiu 65af97edae Show current proxy mode on top menu item. 2016-07-07 15:51:27 +08:00
Charlie Qiu 7ab319e23e Merge branch 'release/1.1' 2016-07-06 19:50:34 +08:00
Charlie Qiu f1e264ae47 Localize advance proxy preferences panel. 2016-07-06 13:18:07 +08:00
Charlie Qiu e1ec9d7c8e Localization 2016-07-06 12:36:31 +08:00
Charlie Qiu e41a130c1c Change ss port minimum limit from 128 to 1. 2016-07-01 16:09:48 +08:00
Charlie Qiu ea4e006133 Advance preference for proxy.
Manual spesify network services which would be configure.
2016-06-30 02:33:37 +08:00
Charlie Qiu 1380f245d5 Fix spell errors. Rename all 'Shadowsocks-NE' to 'Shadowsocks-NG' 2016-06-25 15:00:03 +08:00
Charlie Qiu 012c0de1c5 Update README 2016-06-25 09:47:27 +08:00
Charlie Qiu 0d2172a565 Change version to 1.1 2016-06-25 09:45:36 +08:00
Charlie Qiu 2ef7adde6e Fix wrong spell in path. 2016-06-25 09:44:51 +08:00
Charlie Qiu fa6d9d64de Merge branch 'develop' of https://github.com/qiuyuzhou/ShadowsocksX-NG into develop 2016-06-23 12:10:34 +08:00
Charlie Qiu 6bfa77d773 Cocoa Keyboard Shortcuts in Dialog without an Edit Menu 2016-06-23 12:10:22 +08:00
Qiu Yuzhou 598ac6ea4d Merge pull request #8 from cs17899219/develop
Use a singleton ServerProfileManager
2016-06-23 11:24:22 +08:00
C.S 94e065ea63 Bugfix use a singleton ServerProfileManager 2016-06-23 10:07:26 +08:00
Charlie Qiu 78bb0b7d32 Change to use flat app icons. 2016-06-21 22:35:43 +08:00
Charlie Qiu 64b1e0f488 Merge branch 'release/1.0' 2016-06-20 15:42:11 +08:00
Charlie Qiu 81df618fe0 Merge branch 'release/1.0' into develop 2016-06-20 15:42:11 +08:00
Charlie Qiu 4659a963b3 Update build number to 3. 2016-06-20 15:41:12 +08:00
Charlie Qiu 23696420a5 Add show logs menu item. 2016-06-18 11:06:49 +08:00
Charlie Qiu 7e184d5a1b Add "Enable verbose mode" to adv preferences panel. 2016-06-18 10:44:09 +08:00
Charlie Qiu 326b080027 Enable ss-local verbose mode. 2016-06-15 05:38:50 +08:00
Charlie Qiu a28612b1c3 Build number to 2 2016-06-14 20:29:55 +08:00
Charlie Qiu ce2d4e8a55 Change Default listen address from localhost to 127.0.0.1 2016-06-14 20:26:12 +08:00
45 changed files with 1117 additions and 282 deletions
+12 -4
View File
@@ -1,12 +1,12 @@
# ShadowsocksX-NG # ShadowsocksX-NG
Current version is 1.0 Beta Current version is 1.2
[![Build Status](https://travis-ci.org/qiuyuzhou/ShadowsocksX-NG.svg?branch=develop)](https://travis-ci.org/qiuyuzhou/ShadowsocksX-NG) [![Build Status](https://travis-ci.org/qiuyuzhou/ShadowsocksX-NG.svg?branch=develop)](https://travis-ci.org/qiuyuzhou/ShadowsocksX-NG)
Next Generation of [ShadowsocksX](https://github.com/shadowsocks/shadowsocks-iOS) Next Generation of [ShadowsocksX](https://github.com/shadowsocks/shadowsocks-iOS)
## Why Another Implement ## Why?
It's hard to maintaine the original implement. There are too many unused code in it. It's hard to maintaine the original implement. There are too many unused code in it.
It also embed ss-local source. It's crazy to maitaine depandences of ss-local. It also embed ss-local source. It's crazy to maitaine depandences of ss-local.
@@ -42,8 +42,10 @@ Then I rewrite the gui code by swift.
- Local socks5 timeout. - Local socks5 timeout.
- If enable UDP relay. - If enable UDP relay.
- GFW List url. - GFW List url.
- Manual spesify network service profiles which would be configure the proxy.
- Could reorder shadowsocks profiles by drag & drop in servers preferences panel.
## Diferences with orignal ShadowsocksX ## Different from orignal ShadowsocksX
Run ss-local as backgroud service through launchd, not in app process. Run ss-local as backgroud service through launchd, not in app process.
So after you quit the app, the ss-local maybe is still running. So after you quit the app, the ss-local maybe is still running.
@@ -51,9 +53,15 @@ So after you quit the app, the ss-local maybe is still running.
Add a manual mode which won't configure the system proxy settings. Add a manual mode which won't configure the system proxy settings.
Then you could configure your apps to use socks5 proxy manual. Then you could configure your apps to use socks5 proxy manual.
## Contributing
Contributions must be available on a separately named branch based on the latest version of the main branch develop.
ref: [GitFlow](http://nvie.com/posts/a-successful-git-branching-model/)
## TODO List ## TODO List
- Embed the http proxy server [privoxy](http://www.privoxy.org/). - [ ] Embed the http proxy server [privoxy](http://www.privoxy.org/).
## License ## License
+52 -4
View File
@@ -17,7 +17,7 @@
9B0BFFEB1D0460A70040E62B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9B0BFFEA1D0460A70040E62B /* Assets.xcassets */; }; 9B0BFFEB1D0460A70040E62B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9B0BFFEA1D0460A70040E62B /* Assets.xcassets */; };
9B0BFFEE1D0460A70040E62B /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9B0BFFEC1D0460A70040E62B /* MainMenu.xib */; }; 9B0BFFEE1D0460A70040E62B /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9B0BFFEC1D0460A70040E62B /* MainMenu.xib */; };
9B0BFFF91D0460A70040E62B /* ShadowsocksX_NGTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B0BFFF81D0460A70040E62B /* ShadowsocksX_NGTests.swift */; }; 9B0BFFF91D0460A70040E62B /* ShadowsocksX_NGTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B0BFFF81D0460A70040E62B /* ShadowsocksX_NGTests.swift */; };
9B172A6A1D0ADDDD00B87B9A /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9B172A6C1D0ADDDD00B87B9A /* Localizable.strings */; }; 9B0D55461D2CC85400A4A8E2 /* ProxyPreferencesController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9B0D55481D2CC85400A4A8E2 /* ProxyPreferencesController.xib */; };
9B2491B41D0ACC3A003BBECC /* PreferencesWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9B2491B61D0ACC3A003BBECC /* PreferencesWindowController.xib */; }; 9B2491B41D0ACC3A003BBECC /* PreferencesWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9B2491B61D0ACC3A003BBECC /* PreferencesWindowController.xib */; };
9B2491B71D0ACC3E003BBECC /* AdvPreferencesWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9B2491B91D0ACC3E003BBECC /* AdvPreferencesWindowController.xib */; }; 9B2491B71D0ACC3E003BBECC /* AdvPreferencesWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9B2491B91D0ACC3E003BBECC /* AdvPreferencesWindowController.xib */; };
9B3FFF0D1D05FEB30019A709 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B3FFF0C1D05FEB30019A709 /* Utils.swift */; }; 9B3FFF0D1D05FEB30019A709 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B3FFF0C1D05FEB30019A709 /* Utils.swift */; };
@@ -38,6 +38,10 @@
9B3FFF4C1D09D8F70019A709 /* install_helper.sh in Resources */ = {isa = PBXBuildFile; fileRef = 9B3FFF4B1D09D8F70019A709 /* install_helper.sh */; }; 9B3FFF4C1D09D8F70019A709 /* install_helper.sh in Resources */ = {isa = PBXBuildFile; fileRef = 9B3FFF4B1D09D8F70019A709 /* install_helper.sh */; };
9B3FFF4F1D09D9D50019A709 /* ProxyConfHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B3FFF4E1D09D9D50019A709 /* ProxyConfHelper.m */; }; 9B3FFF4F1D09D9D50019A709 /* ProxyConfHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B3FFF4E1D09D9D50019A709 /* ProxyConfHelper.m */; };
9B3FFF541D09E2D10019A709 /* proxy_conf_helper in Resources */ = {isa = PBXBuildFile; fileRef = 9B3FFF441D09CD3B0019A709 /* proxy_conf_helper */; }; 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 */; };
9BC70EDC1D2E3E3100EDA4CA /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9B172A6C1D0ADDDD00B87B9A /* Localizable.strings */; };
9BE8FBBF1D0B211600CAFD01 /* libcrypto.1.0.0.dylib in Resources */ = {isa = PBXBuildFile; fileRef = 9BE8FBBD1D0B1FB900CAFD01 /* libcrypto.1.0.0.dylib */; }; 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 */; }; 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 */; }; 9BEEF06A1D04D4D500FC52B3 /* start_ss_local.sh in Resources */ = {isa = PBXBuildFile; fileRef = 9BEEF0661D04CE8D00FC52B3 /* start_ss_local.sh */; };
@@ -48,6 +52,8 @@
9BEEF0751D04EF3E00FC52B3 /* PreferencesWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BEEF0731D04EF3E00FC52B3 /* PreferencesWindowController.swift */; }; 9BEEF0751D04EF3E00FC52B3 /* PreferencesWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BEEF0731D04EF3E00FC52B3 /* PreferencesWindowController.swift */; };
9BEEF0781D04FE8A00FC52B3 /* LaunchAgentUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BEEF0771D04FE8A00FC52B3 /* LaunchAgentUtils.swift */; }; 9BEEF0781D04FE8A00FC52B3 /* LaunchAgentUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BEEF0771D04FE8A00FC52B3 /* LaunchAgentUtils.swift */; };
9BEEF07B1D05631500FC52B3 /* AdvPreferencesWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BEEF0791D05631500FC52B3 /* AdvPreferencesWindowController.swift */; }; 9BEEF07B1D05631500FC52B3 /* AdvPreferencesWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BEEF0791D05631500FC52B3 /* AdvPreferencesWindowController.swift */; };
C8E42A6C1D4F270A0074C7EA /* UserRulesController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8E42A6A1D4F270A0074C7EA /* UserRulesController.swift */; };
C8E42A6E1D4F2CAF0074C7EA /* UserRulesController.xib in Resources */ = {isa = PBXBuildFile; fileRef = C8E42A701D4F2CAF0074C7EA /* UserRulesController.xib */; };
E0E57CCA7EB34B90F9D340F2 /* Pods_ShadowsocksX_NGTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 388120F062D7EB7DD0D8DDCA /* Pods_ShadowsocksX_NGTests.framework */; }; E0E57CCA7EB34B90F9D340F2 /* Pods_ShadowsocksX_NGTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 388120F062D7EB7DD0D8DDCA /* Pods_ShadowsocksX_NGTests.framework */; };
F0809FF1595BE2966343D3C7 /* libPods-proxy_conf_helper.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E7783AEDB4A3BDDC9FF16AC /* libPods-proxy_conf_helper.a */; }; F0809FF1595BE2966343D3C7 /* libPods-proxy_conf_helper.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E7783AEDB4A3BDDC9FF16AC /* libPods-proxy_conf_helper.a */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
@@ -104,13 +110,15 @@
9B0BFFF41D0460A70040E62B /* ShadowsocksX-NGTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "ShadowsocksX-NGTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 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 = "<group>"; }; 9B0BFFF81D0460A70040E62B /* ShadowsocksX_NGTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShadowsocksX_NGTests.swift; sourceTree = "<group>"; };
9B0BFFFA1D0460A70040E62B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 9B0BFFFA1D0460A70040E62B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
9B0D55451D2CC1B800A4A8E2 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/MainMenu.strings"; sourceTree = "<group>"; };
9B0D554A1D2CC85E00A4A8E2 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/ProxyPreferencesController.strings"; sourceTree = "<group>"; };
9B0D554B1D2CC87400A4A8E2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ProxyPreferencesController.xib; sourceTree = "<group>"; };
9B172A5D1D0ACEA100B87B9A /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/AdvPreferencesWindowController.strings"; sourceTree = "<group>"; }; 9B172A5D1D0ACEA100B87B9A /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/AdvPreferencesWindowController.strings"; sourceTree = "<group>"; };
9B172A601D0ADA5B00B87B9A /* genstrings.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = genstrings.py; sourceTree = "<group>"; }; 9B172A601D0ADA5B00B87B9A /* genstrings.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = genstrings.py; sourceTree = "<group>"; };
9B172A6B1D0ADDDD00B87B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/Localizable.strings; sourceTree = "<group>"; }; 9B172A6B1D0ADDDD00B87B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/Localizable.strings; sourceTree = "<group>"; };
9B172A6D1D0ADDE800B87B9A /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = "<group>"; }; 9B172A6D1D0ADDE800B87B9A /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = "<group>"; };
9B2491B51D0ACC3A003BBECC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/PreferencesWindowController.xib; sourceTree = "<group>"; }; 9B2491B51D0ACC3A003BBECC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/PreferencesWindowController.xib; sourceTree = "<group>"; };
9B2491B81D0ACC3E003BBECC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/AdvPreferencesWindowController.xib; sourceTree = "<group>"; }; 9B2491B81D0ACC3E003BBECC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/AdvPreferencesWindowController.xib; sourceTree = "<group>"; };
9B2491BC1D0ACC49003BBECC /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/MainMenu.strings"; sourceTree = "<group>"; };
9B3FFF0C1D05FEB30019A709 /* Utils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Utils.swift; sourceTree = "<group>"; }; 9B3FFF0C1D05FEB30019A709 /* Utils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Utils.swift; sourceTree = "<group>"; };
9B3FFF131D0705810019A709 /* Notifications.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Notifications.swift; sourceTree = "<group>"; }; 9B3FFF131D0705810019A709 /* Notifications.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Notifications.swift; sourceTree = "<group>"; };
9B3FFF151D072FDE0019A709 /* LaunchAtLoginController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LaunchAtLoginController.h; sourceTree = "<group>"; }; 9B3FFF151D072FDE0019A709 /* LaunchAtLoginController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LaunchAtLoginController.h; sourceTree = "<group>"; };
@@ -136,6 +144,11 @@
9B3FFF4E1D09D9D50019A709 /* ProxyConfHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProxyConfHelper.m; sourceTree = "<group>"; }; 9B3FFF4E1D09D9D50019A709 /* ProxyConfHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProxyConfHelper.m; sourceTree = "<group>"; };
9B3FFF501D09DAEA0019A709 /* proxy_conf_helper_version.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = proxy_conf_helper_version.h; sourceTree = "<group>"; }; 9B3FFF501D09DAEA0019A709 /* proxy_conf_helper_version.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = proxy_conf_helper_version.h; sourceTree = "<group>"; };
9B3FFF511D09DBA20019A709 /* ShadowsocksX-NG-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ShadowsocksX-NG-Bridging-Header.h"; sourceTree = "<group>"; }; 9B3FFF511D09DBA20019A709 /* ShadowsocksX-NG-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ShadowsocksX-NG-Bridging-Header.h"; sourceTree = "<group>"; };
9BA04B211D23D5A5005AAD7F /* ProxyConfTool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProxyConfTool.h; sourceTree = "<group>"; };
9BA04B221D23D5A5005AAD7F /* ProxyConfTool.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProxyConfTool.m; sourceTree = "<group>"; };
9BA04B241D24044D005AAD7F /* ProxyPreferencesController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProxyPreferencesController.swift; sourceTree = "<group>"; };
9BB706A51D1B982300551F0E /* SWBApplication.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SWBApplication.m; sourceTree = "<group>"; };
9BB706A61D1B982300551F0E /* SWBApplication.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SWBApplication.h; sourceTree = "<group>"; };
9BE8FBBD1D0B1FB900CAFD01 /* libcrypto.1.0.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libcrypto.1.0.0.dylib; sourceTree = "<group>"; }; 9BE8FBBD1D0B1FB900CAFD01 /* libcrypto.1.0.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libcrypto.1.0.0.dylib; sourceTree = "<group>"; };
9BE8FBC11D0B71CF00CAFD01 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/PreferencesWindowController.strings"; sourceTree = "<group>"; }; 9BE8FBC11D0B71CF00CAFD01 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/PreferencesWindowController.strings"; sourceTree = "<group>"; };
9BEEF0651D04CB8500FC52B3 /* install_ss_local.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = install_ss_local.sh; sourceTree = "<group>"; }; 9BEEF0651D04CB8500FC52B3 /* install_ss_local.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = install_ss_local.sh; sourceTree = "<group>"; };
@@ -148,6 +161,9 @@
9BEEF0771D04FE8A00FC52B3 /* LaunchAgentUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LaunchAgentUtils.swift; sourceTree = "<group>"; }; 9BEEF0771D04FE8A00FC52B3 /* LaunchAgentUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LaunchAgentUtils.swift; sourceTree = "<group>"; };
9BEEF0791D05631500FC52B3 /* AdvPreferencesWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AdvPreferencesWindowController.swift; sourceTree = "<group>"; }; 9BEEF0791D05631500FC52B3 /* AdvPreferencesWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AdvPreferencesWindowController.swift; sourceTree = "<group>"; };
B4E6A97CA843F3943524B686 /* Pods-proxy_conf_helper.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-proxy_conf_helper.debug.xcconfig"; path = "Pods/Target Support Files/Pods-proxy_conf_helper/Pods-proxy_conf_helper.debug.xcconfig"; sourceTree = "<group>"; }; B4E6A97CA843F3943524B686 /* Pods-proxy_conf_helper.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-proxy_conf_helper.debug.xcconfig"; path = "Pods/Target Support Files/Pods-proxy_conf_helper/Pods-proxy_conf_helper.debug.xcconfig"; sourceTree = "<group>"; };
C8E42A6A1D4F270A0074C7EA /* UserRulesController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserRulesController.swift; sourceTree = "<group>"; };
C8E42A6F1D4F2CAF0074C7EA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UserRulesController.xib; sourceTree = "<group>"; };
C8E42A721D4F2CB10074C7EA /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/UserRulesController.strings"; sourceTree = "<group>"; };
E9E9FB3855DA55D0710EE7BD /* Pods-ShadowsocksX-NG.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ShadowsocksX-NG.release.xcconfig"; path = "Pods/Target Support Files/Pods-ShadowsocksX-NG/Pods-ShadowsocksX-NG.release.xcconfig"; sourceTree = "<group>"; }; E9E9FB3855DA55D0710EE7BD /* Pods-ShadowsocksX-NG.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ShadowsocksX-NG.release.xcconfig"; path = "Pods/Target Support Files/Pods-ShadowsocksX-NG/Pods-ShadowsocksX-NG.release.xcconfig"; sourceTree = "<group>"; };
FE3237E9FB24D9B924A0E630 /* Pods-ShadowsocksX-NG.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ShadowsocksX-NG.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ShadowsocksX-NG/Pods-ShadowsocksX-NG.debug.xcconfig"; sourceTree = "<group>"; }; FE3237E9FB24D9B924A0E630 /* Pods-ShadowsocksX-NG.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ShadowsocksX-NG.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ShadowsocksX-NG/Pods-ShadowsocksX-NG.debug.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
@@ -247,6 +263,8 @@
9B0BFFE71D0460A70040E62B /* ShadowsocksX-NG */ = { 9B0BFFE71D0460A70040E62B /* ShadowsocksX-NG */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
9BB706A51D1B982300551F0E /* SWBApplication.m */,
9BB706A61D1B982300551F0E /* SWBApplication.h */,
9B3FFF511D09DBA20019A709 /* ShadowsocksX-NG-Bridging-Header.h */, 9B3FFF511D09DBA20019A709 /* ShadowsocksX-NG-Bridging-Header.h */,
9B3FFF151D072FDE0019A709 /* LaunchAtLoginController.h */, 9B3FFF151D072FDE0019A709 /* LaunchAtLoginController.h */,
9B3FFF161D072FDE0019A709 /* LaunchAtLoginController.m */, 9B3FFF161D072FDE0019A709 /* LaunchAtLoginController.m */,
@@ -267,6 +285,8 @@
9B3FFF4D1D09D9D50019A709 /* ProxyConfHelper.h */, 9B3FFF4D1D09D9D50019A709 /* ProxyConfHelper.h */,
9B3FFF4E1D09D9D50019A709 /* ProxyConfHelper.m */, 9B3FFF4E1D09D9D50019A709 /* ProxyConfHelper.m */,
9B3FFF501D09DAEA0019A709 /* proxy_conf_helper_version.h */, 9B3FFF501D09DAEA0019A709 /* proxy_conf_helper_version.h */,
9BA04B211D23D5A5005AAD7F /* ProxyConfTool.h */,
9BA04B221D23D5A5005AAD7F /* ProxyConfTool.m */,
); );
path = "ShadowsocksX-NG"; path = "ShadowsocksX-NG";
sourceTree = "<group>"; sourceTree = "<group>";
@@ -290,6 +310,10 @@
9B2491B61D0ACC3A003BBECC /* PreferencesWindowController.xib */, 9B2491B61D0ACC3A003BBECC /* PreferencesWindowController.xib */,
9BEEF0791D05631500FC52B3 /* AdvPreferencesWindowController.swift */, 9BEEF0791D05631500FC52B3 /* AdvPreferencesWindowController.swift */,
9B2491B91D0ACC3E003BBECC /* AdvPreferencesWindowController.xib */, 9B2491B91D0ACC3E003BBECC /* AdvPreferencesWindowController.xib */,
9BA04B241D24044D005AAD7F /* ProxyPreferencesController.swift */,
9B0D55481D2CC85400A4A8E2 /* ProxyPreferencesController.xib */,
C8E42A6A1D4F270A0074C7EA /* UserRulesController.swift */,
C8E42A701D4F2CAF0074C7EA /* UserRulesController.xib */,
); );
name = UI; name = UI;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -430,9 +454,10 @@
9BE8FBBF1D0B211600CAFD01 /* libcrypto.1.0.0.dylib in Resources */, 9BE8FBBF1D0B211600CAFD01 /* libcrypto.1.0.0.dylib in Resources */,
9B3FFF541D09E2D10019A709 /* proxy_conf_helper in Resources */, 9B3FFF541D09E2D10019A709 /* proxy_conf_helper in Resources */,
9BEEF0691D04D4D500FC52B3 /* install_ss_local.sh in Resources */, 9BEEF0691D04D4D500FC52B3 /* install_ss_local.sh in Resources */,
9B172A6A1D0ADDDD00B87B9A /* Localizable.strings in Resources */, 9B0D55461D2CC85400A4A8E2 /* ProxyPreferencesController.xib in Resources */,
9B2491B41D0ACC3A003BBECC /* PreferencesWindowController.xib in Resources */, 9B2491B41D0ACC3A003BBECC /* PreferencesWindowController.xib in Resources */,
9B3FFF291D08A1DF0019A709 /* user-rule.txt in Resources */, 9B3FFF291D08A1DF0019A709 /* user-rule.txt in Resources */,
C8E42A6E1D4F2CAF0074C7EA /* UserRulesController.xib in Resources */,
9BEEF06A1D04D4D500FC52B3 /* start_ss_local.sh in Resources */, 9BEEF06A1D04D4D500FC52B3 /* start_ss_local.sh in Resources */,
9B3FFF391D08CF110019A709 /* qrcode.min.js in Resources */, 9B3FFF391D08CF110019A709 /* qrcode.min.js in Resources */,
9B3FFF3A1D08CF110019A709 /* qrcode.htm in Resources */, 9B3FFF3A1D08CF110019A709 /* qrcode.htm in Resources */,
@@ -445,6 +470,7 @@
9B2491B71D0ACC3E003BBECC /* AdvPreferencesWindowController.xib in Resources */, 9B2491B71D0ACC3E003BBECC /* AdvPreferencesWindowController.xib in Resources */,
9B3FFF381D08CF110019A709 /* jquery.min.js in Resources */, 9B3FFF381D08CF110019A709 /* jquery.min.js in Resources */,
9B3FFF271D0898EB0019A709 /* gfwlist.txt in Resources */, 9B3FFF271D0898EB0019A709 /* gfwlist.txt in Resources */,
9BC70EDC1D2E3E3100EDA4CA /* Localizable.strings in Resources */,
9B0BFFEE1D0460A70040E62B /* MainMenu.xib in Resources */, 9B0BFFEE1D0460A70040E62B /* MainMenu.xib in Resources */,
9B3FFF4C1D09D8F70019A709 /* install_helper.sh in Resources */, 9B3FFF4C1D09D8F70019A709 /* install_helper.sh in Resources */,
9B07EFAC1D048E880052D9DF /* menu_icon@2x.png in Resources */, 9B07EFAC1D048E880052D9DF /* menu_icon@2x.png in Resources */,
@@ -593,9 +619,11 @@
files = ( files = (
9B3FFF171D072FDE0019A709 /* LaunchAtLoginController.m in Sources */, 9B3FFF171D072FDE0019A709 /* LaunchAtLoginController.m in Sources */,
9B3FFF4F1D09D9D50019A709 /* ProxyConfHelper.m in Sources */, 9B3FFF4F1D09D9D50019A709 /* ProxyConfHelper.m in Sources */,
9BB706A71D1B982300551F0E /* SWBApplication.m in Sources */,
9B3FFF1E1D0732660019A709 /* Utils.m in Sources */, 9B3FFF1E1D0732660019A709 /* Utils.m in Sources */,
9B3FFF321D08CEE40019A709 /* SWBQRCodeWindowController.m in Sources */, 9B3FFF321D08CEE40019A709 /* SWBQRCodeWindowController.m in Sources */,
9B3FFF211D08826E0019A709 /* PACUtils.swift in Sources */, 9B3FFF211D08826E0019A709 /* PACUtils.swift in Sources */,
9BA04B261D24044D005AAD7F /* ProxyPreferencesController.swift in Sources */,
9B3FFF141D0705810019A709 /* Notifications.swift in Sources */, 9B3FFF141D0705810019A709 /* Notifications.swift in Sources */,
9BEEF0701D04DDB100FC52B3 /* ServerProfileManager.swift in Sources */, 9BEEF0701D04DDB100FC52B3 /* ServerProfileManager.swift in Sources */,
9BEEF07B1D05631500FC52B3 /* AdvPreferencesWindowController.swift in Sources */, 9BEEF07B1D05631500FC52B3 /* AdvPreferencesWindowController.swift in Sources */,
@@ -603,7 +631,9 @@
9B3FFF0D1D05FEB30019A709 /* Utils.swift in Sources */, 9B3FFF0D1D05FEB30019A709 /* Utils.swift in Sources */,
9BEEF0751D04EF3E00FC52B3 /* PreferencesWindowController.swift in Sources */, 9BEEF0751D04EF3E00FC52B3 /* PreferencesWindowController.swift in Sources */,
9B0BFFE91D0460A70040E62B /* AppDelegate.swift in Sources */, 9B0BFFE91D0460A70040E62B /* AppDelegate.swift in Sources */,
9BA04B231D23D5A5005AAD7F /* ProxyConfTool.m in Sources */,
9BEEF0781D04FE8A00FC52B3 /* LaunchAgentUtils.swift in Sources */, 9BEEF0781D04FE8A00FC52B3 /* LaunchAgentUtils.swift in Sources */,
C8E42A6C1D4F270A0074C7EA /* UserRulesController.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -643,11 +673,20 @@
isa = PBXVariantGroup; isa = PBXVariantGroup;
children = ( children = (
9B0BFFED1D0460A70040E62B /* Base */, 9B0BFFED1D0460A70040E62B /* Base */,
9B2491BC1D0ACC49003BBECC /* zh-Hans */, 9B0D55451D2CC1B800A4A8E2 /* zh-Hans */,
); );
name = MainMenu.xib; name = MainMenu.xib;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
9B0D55481D2CC85400A4A8E2 /* ProxyPreferencesController.xib */ = {
isa = PBXVariantGroup;
children = (
9B0D554A1D2CC85E00A4A8E2 /* zh-Hans */,
9B0D554B1D2CC87400A4A8E2 /* Base */,
);
name = ProxyPreferencesController.xib;
sourceTree = "<group>";
};
9B172A6C1D0ADDDD00B87B9A /* Localizable.strings */ = { 9B172A6C1D0ADDDD00B87B9A /* Localizable.strings */ = {
isa = PBXVariantGroup; isa = PBXVariantGroup;
children = ( children = (
@@ -675,6 +714,15 @@
name = AdvPreferencesWindowController.xib; name = AdvPreferencesWindowController.xib;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
C8E42A701D4F2CAF0074C7EA /* UserRulesController.xib */ = {
isa = PBXVariantGroup;
children = (
C8E42A6F1D4F2CAF0074C7EA /* Base */,
C8E42A721D4F2CB10074C7EA /* zh-Hans */,
);
name = UserRulesController.xib;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */ /* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */ /* Begin XCBuildConfiguration section */
+55 -24
View File
@@ -15,7 +15,9 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
var qrcodeWinCtrl: SWBQRCodeWindowController! var qrcodeWinCtrl: SWBQRCodeWindowController!
var preferencesWinCtrl: PreferencesWindowController! var preferencesWinCtrl: PreferencesWindowController!
var advPreferencesWinCtrl: AdvPreferencesWindowController! var advPreferencesWinCtrl: AdvPreferencesWindowController!
var proxyPreferencesWinCtrl: ProxyPreferencesController!
var editUserRulesWinCtrl: UserRulesController!
var launchAtLoginController: LaunchAtLoginController = LaunchAtLoginController() var launchAtLoginController: LaunchAtLoginController = LaunchAtLoginController()
@IBOutlet weak var window: NSWindow! @IBOutlet weak var window: NSWindow!
@@ -23,11 +25,14 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
@IBOutlet weak var runningStatusMenuItem: NSMenuItem! @IBOutlet weak var runningStatusMenuItem: NSMenuItem!
@IBOutlet weak var toggleRunningMenuItem: NSMenuItem! @IBOutlet weak var toggleRunningMenuItem: NSMenuItem!
@IBOutlet weak var proxyMenuItem: NSMenuItem!
@IBOutlet weak var autoModeMenuItem: NSMenuItem! @IBOutlet weak var autoModeMenuItem: NSMenuItem!
@IBOutlet weak var globalModeMenuItem: NSMenuItem! @IBOutlet weak var globalModeMenuItem: NSMenuItem!
@IBOutlet weak var manualModeMenuItem: NSMenuItem! @IBOutlet weak var manualModeMenuItem: NSMenuItem!
@IBOutlet weak var serversMenuItem: NSMenuItem! @IBOutlet weak var serversMenuItem: NSMenuItem!
@IBOutlet var showQRCodeMenuItem: NSMenuItem!
@IBOutlet var scanQRCodeMenuItem: NSMenuItem!
@IBOutlet var serversPreferencesMenuItem: NSMenuItem! @IBOutlet var serversPreferencesMenuItem: NSMenuItem!
@IBOutlet weak var lanchAtLoginMenuItem: NSMenuItem! @IBOutlet weak var lanchAtLoginMenuItem: NSMenuItem!
@@ -48,10 +53,12 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
"ShadowsocksOn": true, "ShadowsocksOn": true,
"ShadowsocksRunningMode": "auto", "ShadowsocksRunningMode": "auto",
"LocalSocks5.ListenPort": NSNumber(unsignedShort: 1086), "LocalSocks5.ListenPort": NSNumber(unsignedShort: 1086),
"LocalSocks5.ListenAddress": "localhost", "LocalSocks5.ListenAddress": "127.0.0.1",
"LocalSocks5.Timeout": NSNumber(unsignedInteger: 60), "LocalSocks5.Timeout": NSNumber(unsignedInteger: 60),
"LocalSocks5.EnableUDPRelay": NSNumber(bool: false), "LocalSocks5.EnableUDPRelay": NSNumber(bool: false),
"GFWListURL": "https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt" "LocalSocks5.EnableVerboseMode": NSNumber(bool: false),
"GFWListURL": "https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt",
"AutoConfigureNetworkServices": NSNumber(bool: true)
]) ])
statusItem = NSStatusBar.systemStatusBar().statusItemWithLength(20) statusItem = NSStatusBar.systemStatusBar().statusItemWithLength(20)
@@ -62,6 +69,12 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
let notifyCenter = NSNotificationCenter.defaultCenter() 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 notifyCenter.addObserverForName(NOTIFY_SERVER_PROFILES_CHANGED, object: nil, queue: nil
, usingBlock: { , usingBlock: {
(note) in (note) in
@@ -80,7 +93,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
if let userInfo = note.userInfo { if let userInfo = note.userInfo {
let urls: [NSURL] = userInfo["urls"] as! [NSURL] let urls: [NSURL] = userInfo["urls"] as! [NSURL]
let mgr = ServerProfileManager() let mgr = ServerProfileManager.instance
var isChanged = false var isChanged = false
for url in urls { for url in urls {
@@ -169,29 +182,20 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
} }
@IBAction func editUserRulesForPAC(sender: NSMenuItem) { @IBAction func editUserRulesForPAC(sender: NSMenuItem) {
let url = NSURL(fileURLWithPath: PACUserRuleFilePath) if editUserRulesWinCtrl != nil {
NSWorkspace.sharedWorkspace().openURL(url) editUserRulesWinCtrl.close()
}
@IBAction func applyUserRulesForPAC(sender: NSMenuItem) {
if GeneratePACFile() {
// Popup a user notification
let notification = NSUserNotification()
notification.title = "PAC has been updated by User Rules.".localized
NSUserNotificationCenter.defaultUserNotificationCenter()
.deliverNotification(notification)
} else {
let notification = NSUserNotification()
notification.title = "It's failed to update PAC by User Rules.".localized
NSUserNotificationCenter.defaultUserNotificationCenter()
.deliverNotification(notification)
} }
let ctrl = UserRulesController(windowNibName: "UserRulesController")
editUserRulesWinCtrl = ctrl
ctrl.showWindow(self)
NSApp.activateIgnoringOtherApps(true)
ctrl.window?.makeKeyAndOrderFront(self)
} }
@IBAction func showQRCodeForCurrentServer(sender: NSMenuItem) { @IBAction func showQRCodeForCurrentServer(sender: NSMenuItem) {
var errMsg: String? var errMsg: String?
let mgr = ServerProfileManager() if let profile = ServerProfileManager.instance.getActiveProfile() {
if let profile = mgr.getActiveProfile() {
if profile.isValid() { if profile.isValid() {
// Show window // Show window
if qrcodeWinCtrl != nil{ if qrcodeWinCtrl != nil{
@@ -272,9 +276,19 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
ctrl.window?.makeKeyAndOrderFront(self) 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) { @IBAction func selectServer(sender: NSMenuItem) {
let index = sender.tag let index = sender.tag
let spMgr = ServerProfileManager() let spMgr = ServerProfileManager.instance
let newProfile = spMgr.profiles[index] let newProfile = spMgr.profiles[index]
if newProfile.uuid != spMgr.activeProfileId { if newProfile.uuid != spMgr.activeProfileId {
spMgr.setActiveProfiledId(newProfile.uuid) spMgr.setActiveProfiledId(newProfile.uuid)
@@ -283,6 +297,15 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
} }
} }
@IBAction func showLogs(sender: NSMenuItem) {
let ws = NSWorkspace.sharedWorkspace()
if let appUrl = ws.URLForApplicationWithBundleIdentifier("com.apple.Console") {
try! ws.launchApplicationAtURL(appUrl
,options: .Default
,configuration: [NSWorkspaceLaunchConfigurationArguments: "~/Library/Logs/ss-local.log"])
}
}
@IBAction func feedback(sender: NSMenuItem) { @IBAction func feedback(sender: NSMenuItem) {
NSWorkspace.sharedWorkspace().openURL(NSURL(string: "https://github.com/qiuyuzhou/ShadowsocksX-NG/issues")!) NSWorkspace.sharedWorkspace().openURL(NSURL(string: "https://github.com/qiuyuzhou/ShadowsocksX-NG/issues")!)
} }
@@ -304,14 +327,17 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
let defaults = NSUserDefaults.standardUserDefaults() let defaults = NSUserDefaults.standardUserDefaults()
let mode = defaults.stringForKey("ShadowsocksRunningMode") let mode = defaults.stringForKey("ShadowsocksRunningMode")
if mode == "auto" { if mode == "auto" {
proxyMenuItem.title = "Proxy - Auto By PAC".localized
autoModeMenuItem.state = 1 autoModeMenuItem.state = 1
globalModeMenuItem.state = 0 globalModeMenuItem.state = 0
manualModeMenuItem.state = 0 manualModeMenuItem.state = 0
} else if mode == "global" { } else if mode == "global" {
proxyMenuItem.title = "Proxy - Global".localized
autoModeMenuItem.state = 0 autoModeMenuItem.state = 0
globalModeMenuItem.state = 1 globalModeMenuItem.state = 1
manualModeMenuItem.state = 0 manualModeMenuItem.state = 0
} else if mode == "manual" { } else if mode == "manual" {
proxyMenuItem.title = "Proxy - Manual".localized
autoModeMenuItem.state = 0 autoModeMenuItem.state = 0
globalModeMenuItem.state = 0 globalModeMenuItem.state = 0
manualModeMenuItem.state = 1 manualModeMenuItem.state = 1
@@ -335,8 +361,10 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
} }
func updateServersMenu() { func updateServersMenu() {
let mgr = ServerProfileManager() let mgr = ServerProfileManager.instance
serversMenuItem.submenu?.removeAllItems() serversMenuItem.submenu?.removeAllItems()
let showQRItem = showQRCodeMenuItem
let scanQRItem = scanQRCodeMenuItem
let preferencesItem = serversPreferencesMenuItem let preferencesItem = serversPreferencesMenuItem
var i = 0 var i = 0
@@ -362,6 +390,9 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
if !mgr.profiles.isEmpty { if !mgr.profiles.isEmpty {
serversMenuItem.submenu?.addItem(NSMenuItem.separatorItem()) serversMenuItem.submenu?.addItem(NSMenuItem.separatorItem())
} }
serversMenuItem.submenu?.addItem(showQRItem)
serversMenuItem.submenu?.addItem(scanQRItem)
serversMenuItem.submenu?.addItem(NSMenuItem.separatorItem())
serversMenuItem.submenu?.addItem(preferencesItem) serversMenuItem.submenu?.addItem(preferencesItem)
} }
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 927 B

After

Width:  |  Height:  |  Size: 798 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 124 KiB

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 342 KiB

After

Width:  |  Height:  |  Size: 195 KiB

@@ -14,14 +14,63 @@
<window title="Advance Preferences" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" animationBehavior="default" id="F0z-JX-Cv5"> <window title="Advance Preferences" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" animationBehavior="default" id="F0z-JX-Cv5">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/> <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/> <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="469" y="456" width="480" height="288"/> <rect key="contentRect" x="469" y="456" width="480" height="336"/>
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/> <rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
<view key="contentView" id="se5-gp-TjO"> <view key="contentView" id="se5-gp-TjO">
<rect key="frame" x="0.0" y="0.0" width="480" height="288"/> <rect key="frame" x="0.0" y="0.0" width="480" height="336"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<box verticalHuggingPriority="750" title="Box" boxType="separator" titlePosition="noTitle" translatesAutoresizingMaskIntoConstraints="NO" id="ayu-Tb-kmf">
<rect key="frame" x="38" y="120" width="405" height="5"/>
<color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/>
<color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<font key="titleFont" metaFont="system"/>
</box>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="I4a-N9-Tkv">
<rect key="frame" x="48" y="97" width="192" height="17"/>
<constraints>
<constraint firstAttribute="width" constant="188" id="Tny-lh-gfo"/>
</constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="left" title="GFW List URL:" id="dg0-gS-z5V">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="6MD-Ry-R5P">
<rect key="frame" x="49" y="20" width="378" height="69"/>
<constraints>
<constraint firstAttribute="height" constant="69" id="NVe-Ir-JCv"/>
</constraints>
<textFieldCell key="cell" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="fS7-It-ERD">
<font key="font" metaFont="system"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<binding destination="pR1-Bo-AWz" name="value" keyPath="values.GFWListURL" id="49j-JU-amO">
<dictionary key="options">
<bool key="NSContinuouslyUpdatesValue" value="YES"/>
</dictionary>
</binding>
</connections>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="wCp-nB-dda">
<rect key="frame" x="18" y="299" width="439" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Don't change these preferences if you have no idea what are they." id="8wL-qv-5nD">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<box verticalHuggingPriority="750" title="Box" boxType="separator" titlePosition="noTitle" translatesAutoresizingMaskIntoConstraints="NO" id="JBW-8M-eHP">
<rect key="frame" x="36" y="288" width="405" height="5"/>
<color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/>
<color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<font key="titleFont" metaFont="system"/>
</box>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="S5h-Xx-HUG"> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="S5h-Xx-HUG">
<rect key="frame" x="35" y="212" width="204" height="17"/> <rect key="frame" x="27" y="226" width="204" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Local Socks5 Listen Port:" id="qRs-ow-vVB"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Local Socks5 Listen Port:" id="qRs-ow-vVB">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@@ -29,7 +78,7 @@
</textFieldCell> </textFieldCell>
</textField> </textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="xWv-tc-lQe"> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="xWv-tc-lQe">
<rect key="frame" x="35" y="249" width="204" height="17"/> <rect key="frame" x="27" y="263" width="204" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Local Socks5 Listen Address:" id="cwr-n0-zwn"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Local Socks5 Listen Address:" id="cwr-n0-zwn">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@@ -37,10 +86,7 @@
</textFieldCell> </textFieldCell>
</textField> </textField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Q2L-Fh-TW1"> <textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Q2L-Fh-TW1">
<rect key="frame" x="245" y="246" width="160" height="22"/> <rect key="frame" x="237" y="260" width="160" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="160" id="uGY-R1-1K3"/>
</constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="iRm-V5-3gu"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="iRm-V5-3gu">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
@@ -55,7 +101,7 @@
</connections> </connections>
</textField> </textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="e3S-m6-k5Y"> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="e3S-m6-k5Y">
<rect key="frame" x="35" y="176" width="204" height="17"/> <rect key="frame" x="27" y="190" width="204" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Timeout:" id="i4l-2S-gOQ"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Timeout:" id="i4l-2S-gOQ">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@@ -63,7 +109,7 @@
</textFieldCell> </textFieldCell>
</textField> </textField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="sRP-xs-alR"> <textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="sRP-xs-alR">
<rect key="frame" x="245" y="171" width="60" height="22"/> <rect key="frame" x="237" y="185" width="60" height="22"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" alignment="right" drawsBackground="YES" id="wjv-Nc-tjX"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" alignment="right" drawsBackground="YES" id="wjv-Nc-tjX">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
@@ -79,7 +125,7 @@
</connections> </connections>
</textField> </textField>
<button translatesAutoresizingMaskIntoConstraints="NO" id="DiD-K0-Y43"> <button translatesAutoresizingMaskIntoConstraints="NO" id="DiD-K0-Y43">
<rect key="frame" x="243" y="141" width="219" height="18"/> <rect key="frame" x="235" y="155" width="219" height="18"/>
<buttonCell key="cell" type="check" title="Enable Udp Replay" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="1C3-4s-Apd"> <buttonCell key="cell" type="check" title="Enable Udp Replay" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="1C3-4s-Apd">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/> <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
@@ -88,45 +134,10 @@
<binding destination="pR1-Bo-AWz" name="value" keyPath="values.LocalSocks5.EnableUDPRelay" id="fuM-ii-maJ"/> <binding destination="pR1-Bo-AWz" name="value" keyPath="values.LocalSocks5.EnableUDPRelay" id="fuM-ii-maJ"/>
</connections> </connections>
</button> </button>
<box verticalHuggingPriority="750" title="Box" boxType="separator" titlePosition="noTitle" translatesAutoresizingMaskIntoConstraints="NO" id="ayu-Tb-kmf">
<rect key="frame" x="38" y="125" width="405" height="5"/>
<color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/>
<color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<font key="titleFont" metaFont="system"/>
</box>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="I4a-N9-Tkv">
<rect key="frame" x="48" y="97" width="192" height="17"/>
<constraints>
<constraint firstAttribute="width" constant="188" id="bNe-tm-zZy"/>
</constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="left" title="GFW List URL:" id="dg0-gS-z5V">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="6MD-Ry-R5P">
<rect key="frame" x="49" y="20" width="378" height="69"/>
<constraints>
<constraint firstAttribute="height" constant="69" id="xFK-oi-GjS"/>
</constraints>
<textFieldCell key="cell" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="fS7-It-ERD">
<font key="font" metaFont="system"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<binding destination="pR1-Bo-AWz" name="value" keyPath="values.GFWListURL" id="49j-JU-amO">
<dictionary key="options">
<bool key="NSContinuouslyUpdatesValue" value="YES"/>
</dictionary>
</binding>
</connections>
</textField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="XQ5-fw-o8t"> <textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="XQ5-fw-o8t">
<rect key="frame" x="245" y="209" width="60" height="22"/> <rect key="frame" x="237" y="223" width="60" height="22"/>
<constraints> <constraints>
<constraint firstAttribute="width" constant="60" id="PaY-Mh-CcY"/> <constraint firstAttribute="width" constant="60" id="reo-ha-VKi"/>
</constraints> </constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" alignment="right" drawsBackground="YES" id="rfR-7k-cS8"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" alignment="right" drawsBackground="YES" id="rfR-7k-cS8">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
@@ -142,49 +153,74 @@
<outlet property="formatter" destination="uE9-0u-CJW" id="QsO-5H-MYE"/> <outlet property="formatter" destination="uE9-0u-CJW" id="QsO-5H-MYE"/>
</connections> </connections>
</textField> </textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="eoD-7r-Q85"> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="eoD-7r-Q85">
<rect key="frame" x="311" y="174" width="96" height="17"/> <rect key="frame" x="303" y="188" width="96" height="17"/>
<constraints>
<constraint firstAttribute="width" constant="92" id="xw1-XT-mjQ"/>
</constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Seconds" id="Gd3-Fm-sWh"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Seconds" id="Gd3-Fm-sWh">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell> </textFieldCell>
</textField> </textField>
<button translatesAutoresizingMaskIntoConstraints="NO" id="qVQ-tJ-cO6">
<rect key="frame" x="235" y="129" width="219" height="18"/>
<buttonCell key="cell" type="check" title="Enable Verbose Mode" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="dCD-gg-I2i">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<binding destination="pR1-Bo-AWz" name="value" keyPath="values.LocalSocks5.EnableVerboseMode" id="Nu9-zu-vUE"/>
</connections>
</button>
</subviews> </subviews>
<constraints> <constraints>
<constraint firstAttribute="trailing" secondItem="DiD-K0-Y43" secondAttribute="trailing" constant="20" symbolic="YES" id="0z7-Ju-oVR"/> <constraint firstItem="xWv-tc-lQe" firstAttribute="baseline" secondItem="Q2L-Fh-TW1" secondAttribute="baseline" id="0ub-69-rbe"/>
<constraint firstItem="e3S-m6-k5Y" firstAttribute="top" secondItem="sRP-xs-alR" secondAttribute="top" id="1Fm-xH-FIR"/> <constraint firstAttribute="bottom" secondItem="6MD-Ry-R5P" secondAttribute="bottom" constant="20" symbolic="YES" id="1VT-Fs-nNp"/>
<constraint firstAttribute="trailing" secondItem="6MD-Ry-R5P" secondAttribute="trailing" constant="53" id="7FK-kf-MHq"/> <constraint firstItem="S5h-Xx-HUG" firstAttribute="leading" secondItem="e3S-m6-k5Y" secondAttribute="leading" id="1Y0-Oh-Ev4"/>
<constraint firstItem="S5h-Xx-HUG" firstAttribute="baseline" secondItem="XQ5-fw-o8t" secondAttribute="baseline" id="7hh-hY-Tfd"/> <constraint firstItem="wCp-nB-dda" firstAttribute="top" secondItem="se5-gp-TjO" secondAttribute="top" constant="20" symbolic="YES" id="4af-lJ-vAL"/>
<constraint firstItem="sRP-xs-alR" firstAttribute="leading" secondItem="DiD-K0-Y43" secondAttribute="leading" id="872-50-MM1"/> <constraint firstItem="xWv-tc-lQe" firstAttribute="leading" secondItem="S5h-Xx-HUG" secondAttribute="leading" id="7E0-aW-12T"/>
<constraint firstAttribute="bottom" secondItem="6MD-Ry-R5P" secondAttribute="bottom" constant="20" symbolic="YES" id="BPk-0m-XoP"/> <constraint firstItem="6MD-Ry-R5P" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="49" id="8CU-pQ-jDz"/>
<constraint firstItem="sRP-xs-alR" firstAttribute="leading" secondItem="e3S-m6-k5Y" secondAttribute="trailing" constant="8" symbolic="YES" id="Eq2-ED-0fQ"/> <constraint firstItem="xWv-tc-lQe" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="29" id="8oq-65-XGK"/>
<constraint firstAttribute="trailing" secondItem="Q2L-Fh-TW1" secondAttribute="trailing" constant="75" id="Hdj-d1-9pH"/> <constraint firstItem="eoD-7r-Q85" firstAttribute="leading" secondItem="sRP-xs-alR" secondAttribute="trailing" constant="8" symbolic="YES" id="GhL-we-2co"/>
<constraint firstItem="xWv-tc-lQe" firstAttribute="baseline" secondItem="Q2L-Fh-TW1" secondAttribute="baseline" id="LWx-qI-dhr"/> <constraint firstItem="sRP-xs-alR" firstAttribute="leading" secondItem="DiD-K0-Y43" secondAttribute="leading" id="H7k-Nh-YHo"/>
<constraint firstItem="XQ5-fw-o8t" firstAttribute="top" secondItem="Q2L-Fh-TW1" secondAttribute="bottom" constant="15" id="OfP-2a-r64"/> <constraint firstAttribute="trailing" secondItem="DiD-K0-Y43" secondAttribute="trailing" constant="28" id="H8a-Jg-72h"/>
<constraint firstItem="XQ5-fw-o8t" firstAttribute="leading" secondItem="sRP-xs-alR" secondAttribute="leading" id="OqF-he-dHW"/> <constraint firstItem="XQ5-fw-o8t" firstAttribute="leading" secondItem="sRP-xs-alR" secondAttribute="leading" id="Ij2-mo-WRt"/>
<constraint firstItem="ayu-Tb-kmf" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="38" id="Qfz-zi-PYT"/> <constraint firstItem="DiD-K0-Y43" firstAttribute="leading" secondItem="qVQ-tJ-cO6" secondAttribute="leading" id="J5O-DE-8O9"/>
<constraint firstItem="XQ5-fw-o8t" firstAttribute="trailing" secondItem="sRP-xs-alR" secondAttribute="trailing" id="V4b-j8-HQ5"/> <constraint firstItem="Q2L-Fh-TW1" firstAttribute="top" secondItem="JBW-8M-eHP" secondAttribute="bottom" constant="8" symbolic="YES" id="Jkq-uJ-Wv4"/>
<constraint firstItem="I4a-N9-Tkv" firstAttribute="top" secondItem="ayu-Tb-kmf" secondAttribute="bottom" constant="13" id="ZgK-is-AYc"/> <constraint firstAttribute="trailing" secondItem="wCp-nB-dda" secondAttribute="trailing" constant="25" id="Mod-B8-1Yl"/>
<constraint firstItem="ayu-Tb-kmf" firstAttribute="centerX" secondItem="se5-gp-TjO" secondAttribute="centerX" id="Zo5-QG-fZQ"/> <constraint firstItem="wCp-nB-dda" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="20" symbolic="YES" id="R3i-gt-6zg"/>
<constraint firstItem="xWv-tc-lQe" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="37" id="e40-q4-KNz"/> <constraint firstItem="DiD-K0-Y43" firstAttribute="trailing" secondItem="qVQ-tJ-cO6" secondAttribute="trailing" id="WaY-S9-VQ2"/>
<constraint firstItem="xWv-tc-lQe" firstAttribute="leading" secondItem="S5h-Xx-HUG" secondAttribute="leading" id="elC-xb-XO6"/> <constraint firstItem="I4a-N9-Tkv" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="50" id="Wd9-qu-Mx8"/>
<constraint firstItem="6MD-Ry-R5P" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="49" id="nOv-LT-qf9"/> <constraint firstItem="e3S-m6-k5Y" firstAttribute="top" secondItem="sRP-xs-alR" secondAttribute="top" id="Xmc-dV-VXv"/>
<constraint firstItem="I4a-N9-Tkv" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="50" id="q5f-wo-sYs"/> <constraint firstItem="JBW-8M-eHP" firstAttribute="top" secondItem="wCp-nB-dda" secondAttribute="bottom" constant="8" symbolic="YES" id="Ysd-52-5Fn"/>
<constraint firstItem="Q2L-Fh-TW1" firstAttribute="leading" secondItem="xWv-tc-lQe" secondAttribute="trailing" constant="8" symbolic="YES" id="qbL-5M-6Ax"/> <constraint firstAttribute="trailing" secondItem="Q2L-Fh-TW1" secondAttribute="trailing" constant="83" id="ZoL-73-xKa"/>
<constraint firstItem="ayu-Tb-kmf" firstAttribute="top" secondItem="DiD-K0-Y43" secondAttribute="bottom" constant="15" id="rw7-kk-nln"/> <constraint firstItem="sRP-xs-alR" firstAttribute="leading" secondItem="e3S-m6-k5Y" secondAttribute="trailing" constant="8" symbolic="YES" id="ZvN-ZN-EVZ"/>
<constraint firstItem="Q2L-Fh-TW1" firstAttribute="leading" secondItem="XQ5-fw-o8t" secondAttribute="leading" id="soD-hL-lP6"/> <constraint firstItem="sRP-xs-alR" firstAttribute="baseline" secondItem="eoD-7r-Q85" secondAttribute="baseline" id="aXC-g0-ZpB"/>
<constraint firstItem="S5h-Xx-HUG" firstAttribute="leading" secondItem="e3S-m6-k5Y" secondAttribute="leading" id="vby-t7-6tr"/> <constraint firstItem="qVQ-tJ-cO6" firstAttribute="top" secondItem="DiD-K0-Y43" secondAttribute="bottom" constant="12" id="ccj-Fd-7z7"/>
<constraint firstItem="DiD-K0-Y43" firstAttribute="top" secondItem="sRP-xs-alR" secondAttribute="bottom" constant="14" id="xJE-NF-5ev"/> <constraint firstItem="6MD-Ry-R5P" firstAttribute="top" secondItem="I4a-N9-Tkv" secondAttribute="bottom" constant="8" symbolic="YES" id="dPZ-gY-1am"/>
<constraint firstItem="XQ5-fw-o8t" firstAttribute="leading" secondItem="S5h-Xx-HUG" secondAttribute="trailing" constant="8" symbolic="YES" id="zIv-Fb-eXM"/> <constraint firstItem="JBW-8M-eHP" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="36" id="dSL-lu-CVv"/>
<constraint firstItem="Q2L-Fh-TW1" firstAttribute="top" secondItem="se5-gp-TjO" secondAttribute="top" constant="20" symbolic="YES" id="zT7-pM-0HD"/> <constraint firstItem="XQ5-fw-o8t" firstAttribute="top" secondItem="Q2L-Fh-TW1" secondAttribute="bottom" constant="15" id="e6i-xd-BD3"/>
<constraint firstItem="6MD-Ry-R5P" firstAttribute="top" secondItem="I4a-N9-Tkv" secondAttribute="bottom" constant="8" symbolic="YES" id="znh-1L-Nbo"/> <constraint firstItem="ayu-Tb-kmf" firstAttribute="centerX" secondItem="se5-gp-TjO" secondAttribute="centerX" id="edi-Ij-cuc"/>
<constraint firstItem="Q2L-Fh-TW1" firstAttribute="leading" secondItem="XQ5-fw-o8t" secondAttribute="leading" id="g40-g1-s29"/>
<constraint firstItem="Q2L-Fh-TW1" firstAttribute="trailing" secondItem="eoD-7r-Q85" secondAttribute="trailing" id="g4n-5J-iDi"/>
<constraint firstItem="Q2L-Fh-TW1" firstAttribute="leading" secondItem="xWv-tc-lQe" secondAttribute="trailing" constant="8" symbolic="YES" id="hoH-Lm-ihP"/>
<constraint firstItem="XQ5-fw-o8t" firstAttribute="leading" secondItem="S5h-Xx-HUG" secondAttribute="trailing" constant="8" symbolic="YES" id="ibP-Bc-Xhg"/>
<constraint firstItem="ayu-Tb-kmf" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="38" id="kkG-sj-u3Y"/>
<constraint firstItem="ayu-Tb-kmf" firstAttribute="top" secondItem="qVQ-tJ-cO6" secondAttribute="bottom" constant="8" symbolic="YES" id="lza-Z7-YaI"/>
<constraint firstItem="XQ5-fw-o8t" firstAttribute="trailing" secondItem="sRP-xs-alR" secondAttribute="trailing" id="pfd-Yd-goI"/>
<constraint firstItem="JBW-8M-eHP" firstAttribute="centerX" secondItem="6MD-Ry-R5P" secondAttribute="centerX" id="qbH-5m-epu"/>
<constraint firstItem="I4a-N9-Tkv" firstAttribute="top" secondItem="ayu-Tb-kmf" secondAttribute="bottom" constant="8" symbolic="YES" id="u7y-6r-Vj5"/>
<constraint firstItem="DiD-K0-Y43" firstAttribute="top" secondItem="sRP-xs-alR" secondAttribute="bottom" constant="14" id="xlZ-UD-qns"/>
<constraint firstItem="S5h-Xx-HUG" firstAttribute="baseline" secondItem="XQ5-fw-o8t" secondAttribute="baseline" id="y3b-k3-eBU"/>
<constraint firstItem="wCp-nB-dda" firstAttribute="centerX" secondItem="6MD-Ry-R5P" secondAttribute="centerX" id="yNP-ab-DmI"/>
</constraints> </constraints>
</view> </view>
<connections> <connections>
<outlet property="delegate" destination="-2" id="0bl-1N-AYu"/> <outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
</connections> </connections>
<point key="canvasLocation" x="382" y="364"/> <point key="canvasLocation" x="346" y="288"/>
</window> </window>
<numberFormatter formatterBehavior="default10_4" usesGroupingSeparator="NO" groupingSize="0" minimumIntegerDigits="0" maximumIntegerDigits="42" id="uE9-0u-CJW" userLabel="Port Number Formatter"> <numberFormatter formatterBehavior="default10_4" usesGroupingSeparator="NO" groupingSize="0" minimumIntegerDigits="0" maximumIntegerDigits="42" id="uE9-0u-CJW" userLabel="Port Number Formatter">
<real key="minimum" value="128"/> <real key="minimum" value="128"/>
@@ -39,3 +39,9 @@
"Shadowsocks: Off" = "Shadowsocks: Off"; "Shadowsocks: Off" = "Shadowsocks: Off";
"Turn Shadowsocks On" = "Turn Shadowsocks On"; "Turn Shadowsocks On" = "Turn Shadowsocks On";
"Proxy - Auto By PAC" = "Proxy - Auto By PAC";
"Proxy - Global" = "Proxy - Global";
"Proxy - Manual" = "Proxy - Manual";
+69 -55
View File
@@ -14,19 +14,22 @@
<customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModule="ShadowsocksX_NG" customModuleProvider="target"> <customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModule="ShadowsocksX_NG" customModuleProvider="target">
<connections> <connections>
<outlet property="RunningStatusMenuItem" destination="fzk-mE-CEV" id="R4x-gK-Qcw"/> <outlet property="RunningStatusMenuItem" destination="fzk-mE-CEV" id="R4x-gK-Qcw"/>
<outlet property="autoModeMenuItem" destination="hOa-5N-3ik" id="en3-ni-jqC"/> <outlet property="autoModeMenuItem" destination="r07-Gu-aEz" id="9aH-pQ-Rgi"/>
<outlet property="globalModeMenuItem" destination="3Sa-e9-VXX" id="UKI-yu-DEK"/> <outlet property="globalModeMenuItem" destination="Mw3-Jm-eXA" id="ar5-Yx-3ze"/>
<outlet property="lanchAtLoginMenuItem" destination="eUq-p7-ICK" id="w4p-0c-DZn"/> <outlet property="lanchAtLoginMenuItem" destination="eUq-p7-ICK" id="w4p-0c-DZn"/>
<outlet property="manualModeMenuItem" destination="vRc-N6-z1e" id="jp0-vj-pTX"/> <outlet property="manualModeMenuItem" destination="8PR-gs-c5N" id="9qz-mU-5kt"/>
<outlet property="proxyMenuItem" destination="diI-fB-Rss" id="Qjk-9U-3Qy"/>
<outlet property="runningStatusMenuItem" destination="fzk-mE-CEV" id="Vwm-Rg-Ykn"/> <outlet property="runningStatusMenuItem" destination="fzk-mE-CEV" id="Vwm-Rg-Ykn"/>
<outlet property="scanQRCodeMenuItem" destination="Qe6-bF-paT" id="XHa-pa-nCa"/>
<outlet property="serversMenuItem" destination="u5M-hQ-VSc" id="8gp-SY-Y4U"/> <outlet property="serversMenuItem" destination="u5M-hQ-VSc" id="8gp-SY-Y4U"/>
<outlet property="serversPreferencesMenuItem" destination="M5r-E7-44f" id="voe-SX-k6a"/> <outlet property="serversPreferencesMenuItem" destination="M5r-E7-44f" id="voe-SX-k6a"/>
<outlet property="showQRCodeMenuItem" destination="R6A-96-Zcb" id="XHz-pz-nCz"/>
<outlet property="statusMenu" destination="Hob-KD-bx9" id="clA-ZW-0pT"/> <outlet property="statusMenu" destination="Hob-KD-bx9" id="clA-ZW-0pT"/>
<outlet property="toggleRunningMenuItem" destination="GSu-Tf-StS" id="XHw-pU-nCa"/> <outlet property="toggleRunningMenuItem" destination="GSu-Tf-StS" id="XHw-pU-nCa"/>
</connections> </connections>
</customObject> </customObject>
<customObject id="YLy-65-1bz" customClass="NSFontManager"/> <customObject id="YLy-65-1bz" customClass="NSFontManager"/>
<menu title="ShadowsocksX-NE" id="Hob-KD-bx9"> <menu title="ShadowsocksX-NG" id="Hob-KD-bx9">
<items> <items>
<menuItem title="Showsocks: On" enabled="NO" id="fzk-mE-CEV"> <menuItem title="Showsocks: On" enabled="NO" id="fzk-mE-CEV">
<modifierMask key="keyEquivalentModifierMask"/> <modifierMask key="keyEquivalentModifierMask"/>
@@ -38,29 +41,68 @@
</connections> </connections>
</menuItem> </menuItem>
<menuItem isSeparatorItem="YES" id="LXP-yK-yQu"/> <menuItem isSeparatorItem="YES" id="LXP-yK-yQu"/>
<menuItem title="Auto Mode By PAC" id="hOa-5N-3ik"> <menuItem title="Proxy" id="diI-fB-Rss">
<modifierMask key="keyEquivalentModifierMask"/> <modifierMask key="keyEquivalentModifierMask"/>
<connections> <menu key="submenu" title="Proxy" id="YZp-bf-L40">
<action selector="selectPACMode:" target="Voe-Tx-rLC" id="OwN-Md-pIC"/> <items>
</connections> <menuItem title="Auto Mode By PAC" id="r07-Gu-aEz">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="selectPACMode:" target="Voe-Tx-rLC" id="l36-cd-xl7"/>
</connections>
</menuItem>
<menuItem title="Global Mode" id="Mw3-Jm-eXA">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="selectGlobalMode:" target="Voe-Tx-rLC" id="7QH-HB-B2e"/>
</connections>
</menuItem>
<menuItem title="Manual Mode" id="8PR-gs-c5N">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="selectManualMode:" target="Voe-Tx-rLC" id="Xxb-28-6fi"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="V92-VH-Agn"/>
<menuItem title="Update PAC from GFW List" id="TFc-Ec-duM">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="updateGFWList:" target="Voe-Tx-rLC" id="Ztt-PS-F3T"/>
</connections>
</menuItem>
<menuItem title="Edit User Rules For PAC..." id="rms-p0-CvB">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="editUserRulesForPAC:" target="Voe-Tx-rLC" id="ZtK-2d-Pcl"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="bMX-qn-Qwi"/>
<menuItem title="Advance Proxy Preference..." id="sbx-yz-3lO">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="editProxyPreferences:" target="Voe-Tx-rLC" id="Jji-Ea-Sy8"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem> </menuItem>
<menuItem title="Global Mode" id="3Sa-e9-VXX">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="selectGlobalMode:" target="Voe-Tx-rLC" id="l4X-GP-hlH"/>
</connections>
</menuItem>
<menuItem title="Manual Mode" id="vRc-N6-z1e">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="selectManualMode:" target="Voe-Tx-rLC" id="vNk-P9-UQj"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="kkf-gh-O8t"/>
<menuItem title="Servers" id="u5M-hQ-VSc"> <menuItem title="Servers" id="u5M-hQ-VSc">
<modifierMask key="keyEquivalentModifierMask" shift="YES"/> <modifierMask key="keyEquivalentModifierMask" shift="YES"/>
<menu key="submenu" title="Servers" id="9Y1-db-3HK"> <menu key="submenu" title="Servers" id="9Y1-db-3HK">
<items> <items>
<menuItem title="Show QR Code For Current Server..." id="R6A-96-Zcb">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="showQRCodeForCurrentServer:" target="Voe-Tx-rLC" id="t45-Zk-cai"/>
</connections>
</menuItem>
<menuItem title="Scan QR Code From Screen ..." id="Qe6-bF-paT">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="scanQRCodeFromScreen:" target="Voe-Tx-rLC" id="zQZ-IT-H4a"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="6sL-A4-S7N"/>
<menuItem title="Server Preferences..." id="M5r-E7-44f"> <menuItem title="Server Preferences..." id="M5r-E7-44f">
<modifierMask key="keyEquivalentModifierMask"/> <modifierMask key="keyEquivalentModifierMask"/>
<connections> <connections>
@@ -70,46 +112,12 @@
</items> </items>
</menu> </menu>
</menuItem> </menuItem>
<menuItem isSeparatorItem="YES" id="eLu-uz-b4H"/>
<menuItem title="Advance Preference ..." id="bZ3-fy-34d"> <menuItem title="Advance Preference ..." id="bZ3-fy-34d">
<modifierMask key="keyEquivalentModifierMask"/> <modifierMask key="keyEquivalentModifierMask"/>
<connections> <connections>
<action selector="editAdvPreferences:" target="Voe-Tx-rLC" id="mEF-XS-HJE"/> <action selector="editAdvPreferences:" target="Voe-Tx-rLC" id="mEF-XS-HJE"/>
</connections> </connections>
</menuItem> </menuItem>
<menuItem isSeparatorItem="YES" id="V92-VH-Agn"/>
<menuItem title="Update PAC from GFW List" id="TFc-Ec-duM">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="updateGFWList:" target="Voe-Tx-rLC" id="Ztt-PS-F3T"/>
</connections>
</menuItem>
<menuItem title="Edit User Rules For PAC..." id="rms-p0-CvB">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="editUserRulesForPAC:" target="Voe-Tx-rLC" id="ZtK-2d-Pcl"/>
</connections>
</menuItem>
<menuItem title="Apply User Rules For PAC" id="6qf-cg-HXc">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="applyUserRulesForPAC:" target="Voe-Tx-rLC" id="iAp-Ae-0zV"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="6sL-A4-S7N"/>
<menuItem title="Show QR Code For Current Server..." id="R6A-96-Zcb">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="showQRCodeForCurrentServer:" target="Voe-Tx-rLC" id="t45-Zk-cai"/>
</connections>
</menuItem>
<menuItem title="Scan QR Code From Screen ..." id="Qe6-bF-paT">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="scanQRCodeFromScreen:" target="Voe-Tx-rLC" id="zQZ-IT-H4a"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="wcA-9q-cxa"/>
<menuItem title="Launch At Login" id="eUq-p7-ICK"> <menuItem title="Launch At Login" id="eUq-p7-ICK">
<modifierMask key="keyEquivalentModifierMask"/> <modifierMask key="keyEquivalentModifierMask"/>
<connections> <connections>
@@ -117,6 +125,12 @@
</connections> </connections>
</menuItem> </menuItem>
<menuItem isSeparatorItem="YES" id="DTJ-NF-Wxr"/> <menuItem isSeparatorItem="YES" id="DTJ-NF-Wxr"/>
<menuItem title="Show Logs..." id="Jfy-sf-Fhl">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="showLogs:" target="Voe-Tx-rLC" id="5FZ-Xo-DGb"/>
</connections>
</menuItem>
<menuItem title="Feedback" id="W7u-7g-Gv4"> <menuItem title="Feedback" id="W7u-7g-Gv4">
<modifierMask key="keyEquivalentModifierMask"/> <modifierMask key="keyEquivalentModifierMask"/>
<connections> <connections>
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct"> <document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="10117" systemVersion="15G31" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies> <dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10117"/> <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10117"/>
<capability name="box content view" minToolsVersion="7.0"/> <capability name="box content view" minToolsVersion="7.0"/>
@@ -24,16 +24,16 @@
<window title="Server Preferences" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" oneShot="NO" animationBehavior="default" id="F0z-JX-Cv5"> <window title="Server Preferences" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" oneShot="NO" animationBehavior="default" id="F0z-JX-Cv5">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/> <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/> <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="423" y="365" width="544" height="330"/> <rect key="contentRect" x="423" y="365" width="590" height="330"/>
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/> <rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
<view key="contentView" id="se5-gp-TjO"> <view key="contentView" id="se5-gp-TjO">
<rect key="frame" x="0.0" y="0.0" width="544" height="330"/> <rect key="frame" x="0.0" y="0.0" width="590" height="330"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<scrollView focusRingType="none" autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="u4U-Ju-FJV"> <scrollView focusRingType="none" autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="u4U-Ju-FJV">
<rect key="frame" x="20" y="80" width="165" height="230"/> <rect key="frame" x="20" y="80" width="223" height="230"/>
<clipView key="contentView" focusRingType="none" id="1oC-7s-16v"> <clipView key="contentView" focusRingType="none" id="1oC-7s-16v">
<rect key="frame" x="1" y="1" width="163" height="228"/> <rect key="frame" x="1" y="1" width="221" height="228"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<tableView focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" columnSelection="YES" multipleSelection="NO" emptySelection="NO" autosaveColumns="NO" id="r91-ho-Lum"> <tableView focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" columnSelection="YES" multipleSelection="NO" emptySelection="NO" autosaveColumns="NO" id="r91-ho-Lum">
@@ -84,7 +84,7 @@
</scroller> </scroller>
</scrollView> </scrollView>
<box borderType="line" titlePosition="noTitle" translatesAutoresizingMaskIntoConstraints="NO" id="oZ5-85-pwY"> <box borderType="line" titlePosition="noTitle" translatesAutoresizingMaskIntoConstraints="NO" id="oZ5-85-pwY">
<rect key="frame" x="202" y="57" width="325" height="255"/> <rect key="frame" x="248" y="57" width="325" height="255"/>
<view key="contentView" id="a3z-VL-3xV"> <view key="contentView" id="a3z-VL-3xV">
<rect key="frame" x="1" y="1" width="323" height="253"/> <rect key="frame" x="1" y="1" width="323" height="253"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
@@ -241,39 +241,10 @@
<color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/> <color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/>
<color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/> <color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</box> </box>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="yyD-qq-aSk">
<rect key="frame" x="449" y="13" width="81" height="32"/>
<constraints>
<constraint firstAttribute="width" constant="69" id="GvX-GM-8n5"/>
</constraints>
<buttonCell key="cell" type="push" title="OK" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="zPE-oD-PwK">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<string key="keyEquivalent" base64-UTF8="YES">
DQ
</string>
</buttonCell>
<connections>
<action selector="ok:" target="-2" id="ifI-e4-Htf"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="kGm-Zm-ipY">
<rect key="frame" x="368" y="13" width="81" height="32"/>
<constraints>
<constraint firstAttribute="width" constant="69" id="7s5-Pr-Tlv"/>
</constraints>
<buttonCell key="cell" type="push" title="Cacnel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="j03-9E-uHW">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="cancel:" target="-2" id="514-4D-a6S"/>
</connections>
</button>
<box title="Box" boxType="custom" borderType="none" titlePosition="noTitle" translatesAutoresizingMaskIntoConstraints="NO" id="Gqv-5O-Wwf"> <box title="Box" boxType="custom" borderType="none" titlePosition="noTitle" translatesAutoresizingMaskIntoConstraints="NO" id="Gqv-5O-Wwf">
<rect key="frame" x="20" y="61" width="165" height="19"/> <rect key="frame" x="20" y="61" width="223" height="19"/>
<view key="contentView" id="MbP-FS-YEs"> <view key="contentView" id="MbP-FS-YEs">
<rect key="frame" x="0.0" y="0.0" width="165" height="19"/> <rect key="frame" x="0.0" y="0.0" width="223" height="19"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="4ig-lF-m2R"> <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="4ig-lF-m2R">
@@ -313,33 +284,62 @@ DQ
<color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/> <color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/>
<color key="fillColor" red="1" green="1" blue="1" alpha="0.59999999999999998" colorSpace="calibratedRGB"/> <color key="fillColor" red="1" green="1" blue="1" alpha="0.59999999999999998" colorSpace="calibratedRGB"/>
</box> </box>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="yyD-qq-aSk">
<rect key="frame" x="495" y="13" width="81" height="32"/>
<constraints>
<constraint firstAttribute="width" constant="69" id="uKT-xu-yvV"/>
</constraints>
<buttonCell key="cell" type="push" title="OK" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="zPE-oD-PwK">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<string key="keyEquivalent" base64-UTF8="YES">
DQ
</string>
</buttonCell>
<connections>
<action selector="ok:" target="-2" id="ifI-e4-Htf"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="kGm-Zm-ipY">
<rect key="frame" x="414" y="13" width="81" height="32"/>
<constraints>
<constraint firstAttribute="width" constant="69" id="s2I-cF-RJc"/>
</constraints>
<buttonCell key="cell" type="push" title="Cacnel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="j03-9E-uHW">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="cancel:" target="-2" id="514-4D-a6S"/>
</connections>
</button>
</subviews> </subviews>
<constraints> <constraints>
<constraint firstItem="u4U-Ju-FJV" firstAttribute="leading" secondItem="Gqv-5O-Wwf" secondAttribute="leading" id="00T-SU-dGV"/> <constraint firstItem="oZ5-85-pwY" firstAttribute="leading" secondItem="u4U-Ju-FJV" secondAttribute="trailing" constant="8" symbolic="YES" id="C6R-wI-MlZ"/>
<constraint firstItem="u4U-Ju-FJV" firstAttribute="trailing" secondItem="Gqv-5O-Wwf" secondAttribute="trailing" id="1d8-Yd-ErO"/> <constraint firstItem="kGm-Zm-ipY" firstAttribute="baseline" secondItem="yyD-qq-aSk" secondAttribute="baseline" id="CYq-KM-MIh"/>
<constraint firstAttribute="trailing" secondItem="oZ5-85-pwY" secondAttribute="trailing" constant="20" symbolic="YES" id="6n4-pw-ssp"/> <constraint firstItem="yyD-qq-aSk" firstAttribute="leading" secondItem="kGm-Zm-ipY" secondAttribute="trailing" constant="12" symbolic="YES" id="EGq-gP-YUt"/>
<constraint firstItem="oZ5-85-pwY" firstAttribute="trailing" secondItem="yyD-qq-aSk" secondAttribute="trailing" id="9rk-Gp-QMb"/> <constraint firstAttribute="bottom" secondItem="kGm-Zm-ipY" secondAttribute="bottom" constant="20" symbolic="YES" id="FYH-8M-te7"/>
<constraint firstItem="kGm-Zm-ipY" firstAttribute="baseline" secondItem="yyD-qq-aSk" secondAttribute="baseline" id="DUP-eE-HPu"/> <constraint firstItem="oZ5-85-pwY" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="251" id="JxK-S6-yOS"/>
<constraint firstItem="yyD-qq-aSk" firstAttribute="leading" secondItem="kGm-Zm-ipY" secondAttribute="trailing" constant="12" symbolic="YES" id="E8m-6c-pKH"/> <constraint firstItem="Gqv-5O-Wwf" firstAttribute="top" secondItem="u4U-Ju-FJV" secondAttribute="bottom" id="LJq-QU-Vhw"/>
<constraint firstItem="Gqv-5O-Wwf" firstAttribute="bottom" secondItem="oZ5-85-pwY" secondAttribute="bottom" id="RCW-Hm-rKr"/> <constraint firstItem="Gqv-5O-Wwf" firstAttribute="top" secondItem="se5-gp-TjO" secondAttribute="top" constant="250" id="PxF-wu-Hfs"/>
<constraint firstItem="oZ5-85-pwY" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="205" id="SqM-gs-OUV"/> <constraint firstAttribute="trailing" secondItem="oZ5-85-pwY" secondAttribute="trailing" constant="20" symbolic="YES" id="RnM-Z9-kYW"/>
<constraint firstItem="oZ5-85-pwY" firstAttribute="leading" secondItem="Gqv-5O-Wwf" secondAttribute="trailing" constant="20" symbolic="YES" id="UMl-Hs-ZsE"/> <constraint firstItem="u4U-Ju-FJV" firstAttribute="top" secondItem="oZ5-85-pwY" secondAttribute="top" id="YHq-MK-f01"/>
<constraint firstItem="u4U-Ju-FJV" firstAttribute="top" secondItem="se5-gp-TjO" secondAttribute="top" constant="20" symbolic="YES" id="Uds-5g-kRr"/> <constraint firstItem="Gqv-5O-Wwf" firstAttribute="bottom" secondItem="oZ5-85-pwY" secondAttribute="bottom" id="Z3L-Aj-b7H"/>
<constraint firstItem="u4U-Ju-FJV" firstAttribute="top" secondItem="oZ5-85-pwY" secondAttribute="top" id="VFr-Bp-q4w"/> <constraint firstItem="u4U-Ju-FJV" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="20" symbolic="YES" id="bVO-t4-Ptw"/>
<constraint firstItem="Gqv-5O-Wwf" firstAttribute="top" secondItem="u4U-Ju-FJV" secondAttribute="bottom" id="aVt-un-Nac"/> <constraint firstItem="kGm-Zm-ipY" firstAttribute="top" secondItem="oZ5-85-pwY" secondAttribute="bottom" constant="20" symbolic="YES" id="bxj-ww-w1a"/>
<constraint firstItem="kGm-Zm-ipY" firstAttribute="top" secondItem="oZ5-85-pwY" secondAttribute="bottom" constant="20" symbolic="YES" id="fEN-vq-93f"/> <constraint firstItem="u4U-Ju-FJV" firstAttribute="top" secondItem="se5-gp-TjO" secondAttribute="top" constant="20" symbolic="YES" id="f6j-0J-c14"/>
<constraint firstItem="u4U-Ju-FJV" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="20" symbolic="YES" id="mxl-v4-OJS"/> <constraint firstItem="u4U-Ju-FJV" firstAttribute="trailing" secondItem="Gqv-5O-Wwf" secondAttribute="trailing" id="kGk-iB-pW3"/>
<constraint firstItem="Gqv-5O-Wwf" firstAttribute="top" secondItem="se5-gp-TjO" secondAttribute="top" constant="250" id="xor-Fa-hnd"/> <constraint firstItem="yyD-qq-aSk" firstAttribute="trailing" secondItem="oZ5-85-pwY" secondAttribute="trailing" id="nGi-Tj-4Ev"/>
<constraint firstAttribute="bottom" secondItem="kGm-Zm-ipY" secondAttribute="bottom" constant="20" symbolic="YES" id="xy9-yv-p9u"/> <constraint firstItem="u4U-Ju-FJV" firstAttribute="leading" secondItem="Gqv-5O-Wwf" secondAttribute="leading" id="oo8-zB-YmU"/>
</constraints> </constraints>
</view> </view>
<connections> <connections>
<outlet property="delegate" destination="-2" id="0bl-1N-AYu"/> <outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
</connections> </connections>
<point key="canvasLocation" x="391" y="222"/> <point key="canvasLocation" x="412" y="222"/>
</window> </window>
<numberFormatter formatterBehavior="default10_4" usesGroupingSeparator="NO" groupingSize="0" minimumIntegerDigits="0" maximumIntegerDigits="42" id="QZc-kt-D7Z" userLabel="Port Number Formatter"> <numberFormatter formatterBehavior="default10_4" usesGroupingSeparator="NO" groupingSize="0" minimumIntegerDigits="0" maximumIntegerDigits="42" id="QZc-kt-D7Z" userLabel="Port Number Formatter">
<real key="minimum" value="128"/> <real key="minimum" value="1"/>
<real key="maximum" value="65535"/> <real key="maximum" value="65535"/>
</numberFormatter> </numberFormatter>
</objects> </objects>
@@ -0,0 +1,119 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10117"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="ProxyPreferencesController" customModule="ShadowsocksX_NG" customModuleProvider="target">
<connections>
<outlet property="autoConfigCheckBox" destination="al4-wo-BVS" id="y3x-oN-Wn7"/>
<outlet property="tableView" destination="tdp-Lr-L64" id="yJ0-tP-gVw"/>
<outlet property="window" destination="F0z-JX-Cv5" id="gIp-Ho-8D9"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="Advance Proxy Preferences" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" animationBehavior="default" id="F0z-JX-Cv5">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<rect key="contentRect" x="503" y="308" width="298" height="311"/>
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
<view key="contentView" id="se5-gp-TjO">
<rect key="frame" x="0.0" y="0.0" width="298" height="311"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="al4-wo-BVS">
<rect key="frame" x="18" y="275" width="262" height="18"/>
<buttonCell key="cell" type="check" title="Auto Configure" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="FLv-D9-CRw">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<binding destination="-2" name="value" keyPath="autoConfigureNetworkServices" id="SgV-RH-wUe"/>
</connections>
</button>
<scrollView fixedFrame="YES" autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="657-dv-Val">
<rect key="frame" x="20" y="61" width="258" height="199"/>
<clipView key="contentView" ambiguous="YES" id="i6C-d3-Rpb">
<rect key="frame" x="1" y="1" width="256" height="197"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnSelection="YES" multipleSelection="NO" autosaveColumns="NO" id="tdp-Lr-L64">
<rect key="frame" x="0.0" y="0.0" width="256" height="197"/>
<autoresizingMask key="autoresizingMask"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
<tableColumns>
<tableColumn width="253" minWidth="40" maxWidth="1000" id="26S-Kb-zSc">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
<buttonCell key="dataCell" type="check" title="Check" bezelStyle="regularSquare" imagePosition="left" inset="2" id="ucF-02-bm8">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<connections>
<binding destination="-2" name="enabled" keyPath="autoConfigureNetworkServices" id="XkV-FH-93a">
<dictionary key="options">
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
</connections>
</tableColumn>
</tableColumns>
<connections>
<outlet property="dataSource" destination="-2" id="e18-9E-A4F"/>
<outlet property="delegate" destination="-2" id="8UX-DB-agU"/>
</connections>
</tableView>
</subviews>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</clipView>
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="3sC-hI-IvB">
<rect key="frame" x="-7" y="-14" width="0.0" height="15"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
<scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="6OR-N8-MXx">
<rect key="frame" x="-14" y="-7" width="15" height="0.0"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
</scrollView>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ulk-V7-E4w">
<rect key="frame" x="203" y="13" width="81" height="32"/>
<buttonCell key="cell" type="push" title="OK" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="rWE-M6-TvV">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<string key="keyEquivalent" base64-UTF8="YES">
DQ
</string>
</buttonCell>
<connections>
<action selector="ok:" target="-2" id="GTx-sb-ino"/>
</connections>
</button>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="NVO-zo-7QI">
<rect key="frame" x="122" y="13" width="81" height="32"/>
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="lsQ-1C-OhG">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<string key="keyEquivalent" base64-UTF8="YES">
Gw
</string>
</buttonCell>
<connections>
<action selector="cancel:" target="-2" id="bId-aB-i6V"/>
</connections>
</button>
</subviews>
</view>
<connections>
<outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
</connections>
<point key="canvasLocation" x="360" y="335.5"/>
</window>
<userDefaultsController representsSharedInstance="YES" id="vMm-BK-U3M"/>
</objects>
</document>
@@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="10117" systemVersion="15G31" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10117"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="UserRulesController" customModule="ShadowsocksX_NG" customModuleProvider="target">
<connections>
<outlet property="didCancel" destination="2bi-hW-nd9" id="wKx-Nb-7Kt"/>
<outlet property="userRulesView" destination="4yV-hS-knY" id="HF3-TH-oBY"/>
<outlet property="window" destination="F0z-JX-Cv5" id="gIp-Ho-8D9"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="User Rules" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" animationBehavior="default" id="F0z-JX-Cv5">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<rect key="contentRect" x="196" y="240" width="480" height="270"/>
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1057"/>
<view key="contentView" id="se5-gp-TjO">
<rect key="frame" x="0.0" y="0.0" width="480" height="270"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="N2T-OG-SO9">
<rect key="frame" x="385" y="13" width="81" height="32"/>
<buttonCell key="cell" type="push" title="OK" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="0Sc-cm-Vyu">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<string key="keyEquivalent" base64-UTF8="YES">
DQ
</string>
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</buttonCell>
<connections>
<action selector="didOK:" target="-2" id="216-18-SFI"/>
</connections>
</button>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2bi-hW-nd9">
<rect key="frame" x="304" y="13" width="81" height="32"/>
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="QAR-9i-kmv">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<string key="keyEquivalent" base64-UTF8="YES">
Gw
</string>
</buttonCell>
<connections>
<action selector="didCancel:" target="-2" id="SFh-eD-YLV"/>
</connections>
</button>
<scrollView fixedFrame="YES" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="J3L-MK-p8I">
<rect key="frame" x="20" y="61" width="440" height="189"/>
<clipView key="contentView" ambiguous="YES" id="fO6-Dc-ZUL">
<rect key="frame" x="1" y="1" width="423" height="187"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textView ambiguous="YES" importsGraphics="NO" findStyle="panel" continuousSpellChecking="YES" allowsUndo="YES" usesRuler="YES" usesFontPanel="YES" verticallyResizable="YES" allowsNonContiguousLayout="YES" quoteSubstitution="YES" dashSubstitution="YES" spellingCorrection="YES" smartInsertDelete="YES" id="4yV-hS-knY">
<rect key="frame" x="0.0" y="0.0" width="423" height="187"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<size key="minSize" width="423" height="187"/>
<size key="maxSize" width="463" height="10000000"/>
<color key="insertionPointColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<size key="minSize" width="423" height="187"/>
<size key="maxSize" width="463" height="10000000"/>
</textView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</clipView>
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="YES" id="z0Z-PW-muW">
<rect key="frame" x="-100" y="-100" width="87" height="18"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
<scroller key="verticalScroller" verticalHuggingPriority="750" horizontal="NO" id="Us9-yx-gj4">
<rect key="frame" x="424" y="1" width="15" height="187"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
</scrollView>
</subviews>
</view>
<connections>
<outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
</connections>
<point key="canvasLocation" x="343" y="474"/>
</window>
</objects>
</document>
+2 -2
View File
@@ -17,7 +17,7 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>1.0</string> <string>1.2</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleURLTypes</key> <key>CFBundleURLTypes</key>
@@ -48,6 +48,6 @@
<key>NSMainNibFile</key> <key>NSMainNibFile</key>
<string>MainMenu</string> <string>MainMenu</string>
<key>NSPrincipalClass</key> <key>NSPrincipalClass</key>
<string>NSApplication</string> <string>SWBApplication</string>
</dict> </dict>
</plist> </plist>
+18 -6
View File
@@ -9,9 +9,9 @@
import Foundation import Foundation
let SS_LOCAL_VERSION = "2.4.6" 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_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 { func getFileSHA1Sum(filepath: String) -> String {
@@ -26,20 +26,32 @@ func getFileSHA1Sum(filepath: String) -> String {
func generateSSLocalLauchAgentPlist() -> Bool { func generateSSLocalLauchAgentPlist() -> Bool {
let sslocalPath = NSHomeDirectory() + APP_SUPPORT_DIR + "ss-local" let sslocalPath = NSHomeDirectory() + APP_SUPPORT_DIR + "ss-local"
let logFilePath = NSHomeDirectory() + "/Library/Logs/ss-local.log" let logFilePath = NSHomeDirectory() + "/Library/Logs/ss-local.log"
let plistFilepath = NSHomeDirectory() + LAUNCH_AGENT_DIR + LAUNCH_AGENT_CONF_NAME let launchAgentDirPath = NSHomeDirectory() + LAUNCH_AGENT_DIR
let plistFilepath = launchAgentDirPath + LAUNCH_AGENT_CONF_NAME
// Ensure launch agent directory is existed.
let fileMgr = NSFileManager.defaultManager()
if !fileMgr.fileExistsAtPath(launchAgentDirPath) {
try! fileMgr.createDirectoryAtPath(launchAgentDirPath, withIntermediateDirectories: true, attributes: nil)
}
let oldSha1Sum = getFileSHA1Sum(plistFilepath) let oldSha1Sum = getFileSHA1Sum(plistFilepath)
let enableUdpRelay = NSUserDefaults.standardUserDefaults().boolForKey("LocalSocks5.EnableUDPRelay") let defaults = NSUserDefaults.standardUserDefaults()
let enableUdpRelay = defaults.boolForKey("LocalSocks5.EnableUDPRelay")
let enableVerboseMode = defaults.boolForKey("LocalSocks5.EnableVerboseMode")
var arguments = [sslocalPath, "-c", "ss-local-config.json"] var arguments = [sslocalPath, "-c", "ss-local-config.json"]
if enableUdpRelay { if enableUdpRelay {
arguments.append("-u") arguments.append("-u")
} }
if enableVerboseMode {
arguments.append("-v")
}
// For a complete listing of the keys, see the launchd.plist manual page. // For a complete listing of the keys, see the launchd.plist manual page.
let dict: NSMutableDictionary = [ let dict: NSMutableDictionary = [
"Label": "com.qiuyuzhou.shadowsocksX-NE.local", "Label": "com.qiuyuzhou.shadowsocksX-NG.local",
"WorkingDirectory": NSHomeDirectory() + APP_SUPPORT_DIR, "WorkingDirectory": NSHomeDirectory() + APP_SUPPORT_DIR,
"KeepAlive": true, "KeepAlive": true,
"StandardOutPath": logFilePath, "StandardOutPath": logFilePath,
@@ -142,7 +154,7 @@ func removeSSLocalConfFile() {
func SyncSSLocal() { func SyncSSLocal() {
var changed: Bool = false var changed: Bool = false
changed = changed || generateSSLocalLauchAgentPlist() changed = changed || generateSSLocalLauchAgentPlist()
let mgr = ServerProfileManager() let mgr = ServerProfileManager.instance
if mgr.activeProfileId != nil { if mgr.activeProfileId != nil {
changed = changed || writeSSLocalConfFile((mgr.getActiveProfile()?.toJsonConfig())!) changed = changed || writeSSLocalConfFile((mgr.getActiveProfile()?.toJsonConfig())!)
+1
View File
@@ -9,4 +9,5 @@
import Foundation import Foundation
let NOTIFY_SERVER_PROFILES_CHANGED = "NOTIFY_SERVER_PROFILES_CHANGED" 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" let NOTIFY_ADV_CONF_CHANGED = "NOTIFY_ADV_CONF_CHANGED"
+22 -5
View File
@@ -9,7 +9,9 @@
import Foundation import Foundation
import Alamofire import Alamofire
let PACRulesDirPath = NSHomeDirectory() + "/.ShadowsocksX-NE/" let OldErrorPACRulesDirPath = NSHomeDirectory() + "/.ShadowsocksX-NE/"
let PACRulesDirPath = NSHomeDirectory() + "/.ShadowsocksX-NG/"
let PACUserRuleFilePath = PACRulesDirPath + "user-rule.txt" let PACUserRuleFilePath = PACRulesDirPath + "user-rule.txt"
let PACFilePath = PACRulesDirPath + "gfwlist.js" let PACFilePath = PACRulesDirPath + "gfwlist.js"
let GFWListFilePath = PACRulesDirPath + "gfwlist.txt" let GFWListFilePath = PACRulesDirPath + "gfwlist.txt"
@@ -17,12 +19,23 @@ let GFWListFilePath = PACRulesDirPath + "gfwlist.txt"
// Because of LocalSocks5.ListenPort may be changed // Because of LocalSocks5.ListenPort may be changed
func SyncPac() { func SyncPac() {
var needGenerate = false
let nowSocks5Port = NSUserDefaults.standardUserDefaults().integerForKey("LocalSocks5.ListenPort") let nowSocks5Port = NSUserDefaults.standardUserDefaults().integerForKey("LocalSocks5.ListenPort")
let oldSocks5Port = NSUserDefaults.standardUserDefaults().integerForKey("LocalSocks5.ListenPort.Old") let oldSocks5Port = NSUserDefaults.standardUserDefaults().integerForKey("LocalSocks5.ListenPort.Old")
if nowSocks5Port != oldSocks5Port { if nowSocks5Port != oldSocks5Port {
GeneratePACFile() needGenerate = true
NSUserDefaults.standardUserDefaults().setInteger(nowSocks5Port, forKey: "LocalSocks5.ListenPort.Old") 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() let fileMgr = NSFileManager.defaultManager()
// Maker the dir if rulesDirPath is not exesited. // Maker the dir if rulesDirPath is not exesited.
if !fileMgr.fileExistsAtPath(PACRulesDirPath) { if !fileMgr.fileExistsAtPath(PACRulesDirPath) {
try! fileMgr.createDirectoryAtPath(PACRulesDirPath if fileMgr.fileExistsAtPath(OldErrorPACRulesDirPath) {
, withIntermediateDirectories: true, attributes: nil) try! fileMgr.moveItemAtPath(OldErrorPACRulesDirPath, toPath: PACRulesDirPath)
} else {
try! fileMgr.createDirectoryAtPath(PACRulesDirPath
, withIntermediateDirectories: true, attributes: nil)
}
} }
// If gfwlist.txt is not exsited, copy from bundle // If gfwlist.txt is not exsited, copy from bundle
@@ -40,7 +57,7 @@ func GeneratePACFile() -> Bool {
try! fileMgr.copyItemAtPath(src!, toPath: GFWListFilePath) 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) { if !fileMgr.fileExistsAtPath(PACUserRuleFilePath) {
let src = NSBundle.mainBundle().pathForResource("user-rule", ofType: "txt") let src = NSBundle.mainBundle().pathForResource("user-rule", ofType: "txt")
try! fileMgr.copyItemAtPath(src!, toPath: PACUserRuleFilePath) try! fileMgr.copyItemAtPath(src!, toPath: PACUserRuleFilePath)
@@ -26,6 +26,8 @@ class PreferencesWindowController: NSWindowController
@IBOutlet weak var copyURLBtn: NSButton! @IBOutlet weak var copyURLBtn: NSButton!
let tableViewDragType: String = "ss.server.profile.data"
var defaults: NSUserDefaults! var defaults: NSUserDefaults!
var profileMgr: ServerProfileManager! var profileMgr: ServerProfileManager!
@@ -36,7 +38,7 @@ class PreferencesWindowController: NSWindowController
// Implement this method to handle any initialization after your window controller's window has been loaded from its nib file. // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
defaults = NSUserDefaults.standardUserDefaults() defaults = NSUserDefaults.standardUserDefaults()
profileMgr = ServerProfileManager() profileMgr = ServerProfileManager.instance
methodTextField.addItemsWithObjectValues([ methodTextField.addItemsWithObjectValues([
"aes-128-cfb", "aes-128-cfb",
@@ -56,6 +58,10 @@ class PreferencesWindowController: NSWindowController
updateProfileBoxVisible() updateProfileBoxVisible()
} }
override func awakeFromNib() {
profilesTableView.registerForDraggedTypes([tableViewDragType])
}
@IBAction func addProfile(sender: NSButton) { @IBAction func addProfile(sender: NSButton) {
if editingProfile != nil && !editingProfile.isValid(){ if editingProfile != nil && !editingProfile.isValid(){
return return
@@ -203,6 +209,58 @@ class PreferencesWindowController: NSWindowController
return "" return ""
} }
// Drag & Drop reorder rows
func tableView(tableView: NSTableView, pasteboardWriterForRow row: Int) -> NSPasteboardWriting? {
let item = NSPasteboardItem()
item.setString(String(row), forType: tableViewDragType)
return item
}
func tableView(tableView: NSTableView, validateDrop info: NSDraggingInfo, proposedRow row: Int
, proposedDropOperation dropOperation: NSTableViewDropOperation) -> NSDragOperation {
if dropOperation == .Above {
return .Move
}
return .None
}
func tableView(tableView: NSTableView, acceptDrop info: NSDraggingInfo
, row: Int, dropOperation: NSTableViewDropOperation) -> Bool {
if let mgr = profileMgr {
var oldIndexes = [Int]()
info.enumerateDraggingItemsWithOptions([], forView: tableView, classes: [NSPasteboardItem.self], searchOptions: [:]) {
if let str = ($0.0.item as! NSPasteboardItem).stringForType(self.tableViewDragType), index = Int(str) {
oldIndexes.append(index)
}
}
var oldIndexOffset = 0
var newIndexOffset = 0
// For simplicity, the code below uses `tableView.moveRowAtIndex` to move rows around directly.
// You may want to move rows in your content array and then call `tableView.reloadData()` instead.
tableView.beginUpdates()
for oldIndex in oldIndexes {
if oldIndex < row {
let o = mgr.profiles.removeAtIndex(oldIndex + oldIndexOffset)
mgr.profiles.insert(o, atIndex:row - 1)
tableView.moveRowAtIndex(oldIndex + oldIndexOffset, toIndex: row - 1)
oldIndexOffset -= 1
} else {
let o = mgr.profiles.removeAtIndex(oldIndex)
mgr.profiles.insert(o, atIndex:row + newIndexOffset)
tableView.moveRowAtIndex(oldIndex, toIndex: row + newIndexOffset)
newIndexOffset += 1
}
}
tableView.endUpdates()
return true
}
return false
}
//-------------------------------------------------- //--------------------------------------------------
// For NSTableViewDelegate // For NSTableViewDelegate
+39 -4
View File
@@ -99,19 +99,54 @@
} }
} }
+ (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 { + (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]; 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 { + (void)enableGlobalProxy {
NSUInteger port = [[NSUserDefaults standardUserDefaults]integerForKey:@"LocalSocks5.ListenPort"]; 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 { + (void)disableProxy {
[self callHelper:@[@"--mode", @"off"]]; // 带上所有参数是为了判断是否原有代理设置是否由ssx-ng设置的。如果是用户手工设置的其他配置,则不进行清空。
NSString* urlString = [NSString stringWithFormat:@"%@/.ShadowsocksX-NG/gfwlist.js", NSHomeDirectory()];
NSURL* url = [NSURL fileURLWithPath:urlString];
NSUInteger port = [[NSUserDefaults standardUserDefaults]integerForKey:@"LocalSocks5.ListenPort"];
NSMutableArray* args = [@[@"--mode", @"off"
, @"--port", [NSString stringWithFormat:@"%lu", (unsigned long)port]
, @"--pac-url", [url absoluteString]
]mutableCopy];
[self addArguments4ManualSpecifyNetworkServices:args];
[self callHelper:args];
} }
@end @end
+16
View File
@@ -0,0 +1,16 @@
//
// ProxyConfTool.h
// ShadowsocksX-NG
//
// Created by 邱宇舟 on 16/6/29.
// Copyright © 2016年 qiuyuzhou. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface ProxyConfTool : NSObject
+(NSArray*)networkServicesList;
@end
+52
View File
@@ -0,0 +1,52 @@
//
// ProxyConfTool.m
// ShadowsocksX-NG
//
// Created by 邱宇舟 on 16/6/29.
// Copyright © 2016年 qiuyuzhou. All rights reserved.
//
#import "ProxyConfTool.h"
#import <SystemConfiguration/SystemConfiguration.h>
//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
@@ -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)
}
}
}
+11
View File
@@ -0,0 +1,11 @@
//
// Created by clowwindy on 3/1/14.
// Copyright (c) 2014 clowwindy. All rights reserved.
//
#import <Foundation/Foundation.h>
@import AppKit;
@interface SWBApplication : NSApplication
@end
+49
View File
@@ -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
+3 -1
View File
@@ -10,10 +10,12 @@ import Cocoa
class ServerProfileManager: NSObject { class ServerProfileManager: NSObject {
static let instance:ServerProfileManager = ServerProfileManager()
var profiles:[ServerProfile] var profiles:[ServerProfile]
var activeProfileId: String? var activeProfileId: String?
override init() { private override init() {
profiles = [ServerProfile]() profiles = [ServerProfile]()
let defaults = NSUserDefaults.standardUserDefaults() let defaults = NSUserDefaults.standardUserDefaults()
@@ -7,4 +7,5 @@
#import "LaunchAtLoginController.h" #import "LaunchAtLoginController.h"
#import "SWBQRCodeWindowController.h" #import "SWBQRCodeWindowController.h"
#import "Utils.h" #import "Utils.h"
#import "ProxyConfHelper.h" #import "ProxyConfHelper.h"
#import "ProxyConfTool.h"
+53
View File
@@ -0,0 +1,53 @@
//
// UserRulesController.swift
// ShadowsocksX-NG
//
// Created by 周斌佳 on 16/8/1.
// Copyright © 2016年 qiuyuzhou. All rights reserved.
//
import Cocoa
class UserRulesController: NSWindowController {
@IBOutlet var userRulesView: NSTextView!
override func windowDidLoad() {
super.windowDidLoad()
let fileMgr = NSFileManager.defaultManager()
if !fileMgr.fileExistsAtPath(PACUserRuleFilePath) {
let src = NSBundle.mainBundle().pathForResource("user-rule", ofType: "txt")
try! fileMgr.copyItemAtPath(src!, toPath: PACUserRuleFilePath)
}
let str = try? String(contentsOfFile: PACUserRuleFilePath, encoding: NSUTF8StringEncoding)
userRulesView.string = str
}
@IBAction func didCancel(sender: AnyObject) {
window?.performClose(self)
}
@IBAction func didOK(sender: AnyObject) {
if let str = userRulesView.string {
do {
try str.dataUsingEncoding(NSUTF8StringEncoding)?.writeToFile(PACUserRuleFilePath, options: .DataWritingAtomic)
if GeneratePACFile() {
// Popup a user notification
let notification = NSUserNotification()
notification.title = "PAC has been updated by User Rules.".localized
NSUserNotificationCenter.defaultUserNotificationCenter()
.deliverNotification(notification)
} else {
let notification = NSUserNotification()
notification.title = "It's failed to update PAC by User Rules.".localized
NSUserNotificationCenter.defaultUserNotificationCenter()
.deliverNotification(notification)
}
} catch {}
}
window?.performClose(self)
}
}
+5 -5
View File
@@ -8,11 +8,11 @@
cd `dirname "${BASH_SOURCE[0]}"` cd `dirname "${BASH_SOURCE[0]}"`
mkdir -p "$HOME/Library/Application Support/ShadowsocksX-NE/ss-local-2.4.6" mkdir -p "$HOME/Library/Application Support/ShadowsocksX-NG/ss-local-2.4.6"
cp -f ss-local "$HOME/Library/Application Support/ShadowsocksX-NE/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-NE/ss-local" rm -f "$HOME/Library/Application Support/ShadowsocksX-NG/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" 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 echo done
+1 -1
View File
@@ -9,6 +9,6 @@
#ifndef proxy_conf_helper_version_h #ifndef proxy_conf_helper_version_h
#define proxy_conf_helper_version_h #define proxy_conf_helper_version_h
#define kProxyConfHelperVersion @"1.1.0" #define kProxyConfHelperVersion @"1.3.1"
#endif /* proxy_conf_helper_version_h */ #endif /* proxy_conf_helper_version_h */
+3 -3
View File
@@ -6,7 +6,7 @@
# Created by 邱宇舟 on 16/6/6. # Created by 邱宇舟 on 16/6/6.
# Copyright © 2016年 qiuyuzhou. All rights reserved. # 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 unload "$HOME/Library/LaunchAgents/com.qiuyuzhou.shadowsocksX-NG.local.plist"
launchctl load "$HOME/Library/LaunchAgents/com.qiuyuzhou.shadowsocksX-NE.local.plist" launchctl load "$HOME/Library/LaunchAgents/com.qiuyuzhou.shadowsocksX-NG.local.plist"
+1 -1
View File
@@ -6,4 +6,4 @@
# Created by 邱宇舟 on 16/6/6. # Created by 邱宇舟 on 16/6/6.
# Copyright © 2016年 qiuyuzhou. All rights reserved. # Copyright © 2016年 qiuyuzhou. All rights reserved.
launchctl load "$HOME/Library/LaunchAgents/com.qiuyuzhou.shadowsocksX-NE.local.plist" launchctl load "$HOME/Library/LaunchAgents/com.qiuyuzhou.shadowsocksX-NG.local.plist"
+1 -1
View File
@@ -8,4 +8,4 @@
launchctl unload "$HOME/Library/LaunchAgents/com.qiuyuzhou.shadowsocksX-NE.local.plist" launchctl unload "$HOME/Library/LaunchAgents/com.qiuyuzhou.shadowsocksX-NG.local.plist"
@@ -2,6 +2,9 @@
/* Class = "NSButtonCell"; title = "启用 Udp Replay"; ObjectID = "1C3-4s-Apd"; */ /* Class = "NSButtonCell"; title = "启用 Udp Replay"; ObjectID = "1C3-4s-Apd"; */
"1C3-4s-Apd.title" = "启用 Udp Replay"; "1C3-4s-Apd.title" = "启用 Udp Replay";
/* Class = "NSTextFieldCell"; title = "Don't change these preferences if you have no idea what are they."; ObjectID = "8wL-qv-5nD"; */
"8wL-qv-5nD.title" = "如果你不明白这些选项是什么,请不要修改";
/* Class = "NSWindow"; title = "高级设置"; ObjectID = "F0z-JX-Cv5"; */ /* Class = "NSWindow"; title = "高级设置"; ObjectID = "F0z-JX-Cv5"; */
"F0z-JX-Cv5.title" = "高级设置"; "F0z-JX-Cv5.title" = "高级设置";
@@ -44,3 +44,9 @@
"Turn Shadowsocks On" = "打开 Shadowsocks"; "Turn Shadowsocks On" = "打开 Shadowsocks";
"Proxy - Auto By PAC" = "代理 - PAC自动";
"Proxy - Global" = "代理 - 全局";
"Proxy - Manual" = "代理 - 手动";
+36 -24
View File
@@ -1,57 +1,69 @@
/* Class = "NSMenuItem"; title = "Global Mode"; ObjectID = "3Sa-e9-VXX"; */ /* Class = "NSMenuItem"; title = "应用用户自定规则到 PAC"; ObjectID = "6qf-cg-HXc"; */
"3Sa-e9-VXX.title" = "全局模式";
/* Class = "NSMenuItem"; title = "Apply User Rules For PAC"; ObjectID = "6qf-cg-HXc"; */
"6qf-cg-HXc.title" = "应用用户自定规则到 PAC"; "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" = "服务器"; "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"; "GSu-Tf-StS.title" = "打开 ShadowsocksX";
/* Class = "NSMenu"; title = "ShadowsocksX-NE"; ObjectID = "Hob-KD-bx9"; */ /* Class = "NSMenu"; title = "ShadowsocksX-NG"; ObjectID = "Hob-KD-bx9"; */
"Hob-KD-bx9.title" = "ShadowsocksX-NE"; "Hob-KD-bx9.title" = "ShadowsocksX-NG";
/* Class = "NSMenuItem"; title = "About"; ObjectID = "LgB-6g-Gba"; */ /* Class = "NSMenuItem"; title = "显示日志..."; ObjectID = "Jfy-sf-Fhl"; */
"Jfy-sf-Fhl.title" = "显示日志...";
/* Class = "NSMenuItem"; title = "关于"; ObjectID = "LgB-6g-Gba"; */
"LgB-6g-Gba.title" = "关于"; "LgB-6g-Gba.title" = "关于";
/* Class = "NSMenuItem"; title = "Server Preferences..."; ObjectID = "M5r-E7-44f"; */ /* Class = "NSMenuItem"; title = "服务器设置..."; ObjectID = "M5r-E7-44f"; */
"M5r-E7-44f.title" = "服务器设置..."; "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" = "扫描屏幕上的二维码..."; "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" = "显示当前服务器的二维码..."; "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"; "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" = "反馈"; "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" = "高级设置..."; "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" = "登录时自动启动"; "eUq-p7-ICK.title" = "登录时自动启动";
/* Class = "NSMenuItem"; title = "Showsocks: On"; ObjectID = "fzk-mE-CEV"; */ /* Class = "NSMenuItem"; title = "Showsocks: On"; ObjectID = "fzk-mE-CEV"; */
"fzk-mE-CEV.title" = "Showsocks: On"; "fzk-mE-CEV.title" = "Showsocks: On";
/* Class = "NSMenuItem"; title = "Auto Mode By PAC"; ObjectID = "hOa-5N-3ik"; */ /* Class = "NSMenuItem"; title = "PAC自动模式"; ObjectID = "r07-Gu-aEz"; */
"hOa-5N-3ik.title" = "PAC自动模式"; "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用户自定规则..."; "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" = "服务器"; "u5M-hQ-VSc.title" = "服务器";
/* Class = "NSMenuItem"; title = "Quit"; ObjectID = "vJS-JW-byz"; */ /* Class = "NSMenuItem"; title = "退出"; ObjectID = "vJS-JW-byz"; */
"vJS-JW-byz.title" = "退出"; "vJS-JW-byz.title" = "退出";
/* Class = "NSMenuItem"; title = "Manual Mode"; ObjectID = "vRc-N6-z1e"; */
"vRc-N6-z1e.title" = "手动模式";
@@ -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" = "确定";
@@ -0,0 +1,9 @@
/* Class = "NSButtonCell"; title = "OK"; ObjectID = "0Sc-cm-Vyu"; */
"0Sc-cm-Vyu.title" = "确定";
/* Class = "NSWindow"; title = "User Rules"; ObjectID = "F0z-JX-Cv5"; */
"F0z-JX-Cv5.title" = "用户规则";
/* Class = "NSButtonCell"; title = "Cancel"; ObjectID = "QAR-9i-kmv"; */
"QAR-9i-kmv.title" = "取消";
+50 -7
View File
@@ -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:"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]; [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; NSError *error = nil;
if (![options parseArgc:argc argv:argv error:&error]) { if (![options parseArgc:argc argv:argv error:&error]) {
const char * message = error.localizedDescription.UTF8String; const char * message = error.localizedDescription.UTF8String;
@@ -62,10 +67,6 @@ int main(int argc, const char * argv[])
if (!portString) { if (!portString) {
return 1; return 1;
} }
port = [portString integerValue];
if (0 == port) {
return 1;
}
} else if (![@"off" isEqualToString:mode]) { } else if (![@"off" isEqualToString:mode]) {
return 1; return 1;
} }
@@ -74,6 +75,12 @@ int main(int argc, const char * argv[])
return 0; return 0;
} }
if (portString) {
port = [portString integerValue];
if (0 == port) {
return 1;
}
}
static AuthorizationRef authRef; static AuthorizationRef authRef;
static AuthorizationFlags authFlags; static AuthorizationFlags authFlags;
@@ -108,13 +115,29 @@ int main(int argc, const char * argv[])
NSMutableDictionary *dict = [sets objectForKey:key]; NSMutableDictionary *dict = [sets objectForKey:key];
NSString *hardware = [dict valueForKeyPath:@"Interface.Hardware"]; NSString *hardware = [dict valueForKeyPath:@"Interface.Hardware"];
// NSLog(@"%@", 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) {
NSString* prefPath = [NSString stringWithFormat:@"/%@/%@/%@", kSCPrefNetworkServices
, key, kSCEntNetProxies];
if ([mode isEqualToString:@"auto"]) { if ([mode isEqualToString:@"auto"]) {
[proxies setObject:pacURL forKey:(NSString *)kCFNetworkProxiesProxyAutoConfigURLString]; [proxies setObject:pacURL forKey:(NSString *)kCFNetworkProxiesProxyAutoConfigURLString];
[proxies setObject:[NSNumber numberWithInt:1] forKey:(NSString *)kCFNetworkProxiesProxyAutoConfigEnable]; [proxies setObject:[NSNumber numberWithInt:1] forKey:(NSString *)kCFNetworkProxiesProxyAutoConfigEnable];
SCPreferencesPathSetValue(prefRef, (__bridge CFStringRef)prefPath
, (__bridge CFDictionaryRef)proxies);
} else if ([mode isEqualToString:@"global"]) { } else if ([mode isEqualToString:@"global"]) {
@@ -126,9 +149,29 @@ int main(int argc, const char * argv[])
kCFNetworkProxiesSOCKSEnable]; kCFNetworkProxiesSOCKSEnable];
[proxies setObject:@[@"127.0.0.1", @"localhost"] forKey:(NSString *)kCFNetworkProxiesExceptionsList]; [proxies setObject:@[@"127.0.0.1", @"localhost"] forKey:(NSString *)kCFNetworkProxiesExceptionsList];
SCPreferencesPathSetValue(prefRef, (__bridge CFStringRef)prefPath
, (__bridge CFDictionaryRef)proxies);
} else if ([mode isEqualToString:@"off"]) {
if (pacURL != nil && portString != nil) {
// 取原来的配置,判断是否为shadowsocksX-NG设置的
NSDictionary* oldProxies
= (__bridge NSDictionary*)SCPreferencesPathGetValue(prefRef
, (__bridge CFStringRef)prefPath);
if (([oldProxies[(NSString *)kCFNetworkProxiesProxyAutoConfigURLString] isEqualToString:pacURL]
&&[oldProxies[(NSString *)kCFNetworkProxiesProxyAutoConfigEnable] isEqual:[NSNumber numberWithInt:1]])
||([oldProxies[(NSString*)kCFNetworkProxiesSOCKSProxy] isEqualToString:@"127.0.0.1"]
&&[oldProxies[(NSString*)kCFNetworkProxiesSOCKSPort] isEqualTo:[NSNumber numberWithInteger:port]]
&&[oldProxies[(NSString*)kCFNetworkProxiesSOCKSEnable] isEqual:[NSNumber numberWithInt:1]])
) {
SCPreferencesPathSetValue(prefRef, (__bridge CFStringRef)prefPath
, (__bridge CFDictionaryRef)proxies);
}
} else {
SCPreferencesPathSetValue(prefRef, (__bridge CFStringRef)prefPath
, (__bridge CFDictionaryRef)proxies);
}
} }
SCPreferencesPathSetValue(prefRef, (__bridge CFStringRef)[NSString stringWithFormat:@"/%@/%@/%@", kSCPrefNetworkServices, key, kSCEntNetProxies], (__bridge CFDictionaryRef)proxies);
} }
} }