Compare commits

...
34 Commits
Author SHA1 Message Date
Charlie Qiu 9e231a7b34 Merge branch 'release/1.3.2' 2016-11-01 11:36:46 +08:00
Charlie Qiu 381b9ce634 Update version number to 1.3.2 2016-10-21 23:37:23 +08:00
Charlie Qiu cf2f5d1a9c Fix bug #106 by workaround. 2016-10-21 23:36:05 +08:00
Charlie Qiu d2b8ca1c97 Fix bug #104.
Implement show qrcode by core image generator instead of embed a web view.
2016-10-21 23:27:30 +08:00
Charlie Qiu 082c25f5e2 Fix bug. http preferences 输入框bind需要启用:continuously updates value 2016-10-20 10:58:26 +08:00
Charlie Qiu 969c94eaff Merge branch 'pr/100' into develop 2016-10-20 08:31:33 +08:00
Julien Schmidt e4236f21a1 Corrected Spellings 2016-10-20 01:14:47 +08:00
Charlie Qiu 299abfee7b Fix #98, Don't turn off when app Terminate. 2016-10-19 23:59:52 +08:00
Charlie Qiu 713bcae7b1 Merge branch 'release/1.3.1' 2016-10-19 14:32:40 +08:00
Charlie Qiu 3c77fc9fe9 Fix the project file. 2016-10-19 00:30:53 +08:00
Charlie Qiu 53d41ad27b Update version number to 1.3.1 2016-10-19 00:30:21 +08:00
Charlie Qiu a85fc4e3b4 Disable the rich text attribute of the user pac fule edit control. 2016-10-19 00:26:16 +08:00
Charlie Qiu e5b342c134 Monitor PAC file. Disable then enable the system pac configure after it has been modified. 2016-10-19 00:24:45 +08:00
Charlie Qiu d0ad272198 Refactor pac proxy. 2016-10-18 23:35:17 +08:00
Charlie Qiu 7ad9dc42a0 Fix bug caused by pr #97 2016-10-18 22:18:54 +08:00
Charlie Qiu 5ed5789c31 Merge branch 'pr/97' into develop
# Conflicts:
#	ShadowsocksX-NG/AppDelegate.swift
2016-10-18 22:11:04 +08:00
Charlie Qiu c7211ceb19 Merge commit 'fc11cc78fd9ad96d026485e07e643c751ad4669b' into develop 2016-10-18 16:07:05 +08:00
Qiu Yuzhou fc11cc78fd Merge pull request #92 from linuxbelletian/master
defaults.array(forKey: "ServerProfiles")  would return nil ,but not h…
2016-10-18 16:04:10 +08:00
qinyuhang dd20ebda68 fix crash problem 2016-10-18 15:36:56 +08:00
田兵 22d654dd69 defaults.array(forKey: "ServerProfiles") would return nil ,but not handle 2016-10-17 16:13:42 +08:00
Qiu Yuzhou 8fa7f76faa Add a download link in readme. 2016-10-15 00:33:53 +08:00
Charlie Qiu 8ba816300c Merge branch 'release/1.3' 2016-10-15 00:02:18 +08:00
Charlie Qiu 54ad13ec08 Some UI fixes.
- Center all dialogs.
- Fix pac listen port input field format.
2016-10-14 23:44:14 +08:00
Charlie Qiu 91124b9e90 Merge branch 'pr/85' into develop
# Conflicts:
#	ShadowsocksX-NG/AppDelegate.swift
2016-10-14 23:39:11 +08:00
Charlie Qiu 82de054b83 Merge branch 'pr/78' into develop 2016-10-13 14:46:58 +08:00
位敏 1eddfd48fa update recompiled privoxy 2016-10-10 23:01:13 +08:00
王晨 4c295965f2 增加 HTTP代理 跟随全局设置 2016-10-10 14:17:47 +08:00
王晨 3f7e433dd2 更新两处http开关,随ss开启和关闭 2016-10-10 14:17:30 +08:00
王晨 2ab6f95631 add privoxy 2016-10-10 14:17:02 +08:00
Charlie Qiu 5815c29003 Set deployment target from 10.10 to 10.11 2016-10-07 10:32:30 +08:00
Charlie Qiu e564405a8e Update travis ci status image to new link. 2016-10-06 15:05:35 +08:00
bestv b699d060af bug fix 2016-10-04 08:57:53 +08:00
bestv 20d76a0850 代理菜单内增加状态栏文本显示开关 2016-10-02 23:59:01 +08:00
Charlie Qiu f03287ec0e Merge branch 'release/1.2' 2016-08-04 16:48:03 +08:00
36 changed files with 896 additions and 302 deletions
+20 -16
View File
@@ -2,19 +2,19 @@
Current version is 1.3
[![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/shadowsocks/ShadowsocksX-NG.svg?branch=develop)](https://travis-ci.org/shadowsocks/ShadowsocksX-NG)
Next Generation of [ShadowsocksX](https://github.com/shadowsocks/shadowsocks-iOS)
## Why?
It's hard to maintain the original implement. There are too many unused code in it.
It also embed ss-local source. It's crazy to maintain depandences of ss-local.
So it's hard to update ss-local version.
It's hard to maintain the original implementation as there is too much unused code in it.
It also embeds the ss-local source. It's crazy to maintain dependencies of ss-local.
So it's hard to update the ss-local version.
Now I just copy the ss-local from home brew. Run ss-local executable as a Launch Agent in background.
Serve pac js file as a file url. So there are only some souce code related to GUI left.
Then I rewrite the GUI code by swift.
Now I just copied the ss-local from homebrew. Run ss-local executable as a Launch Agent in the background.
Serve PAC js file as a file URL. So there is only some source code related to GUI left.
Then I will rewrite the GUI code in Swift.
## Requirements
@@ -27,30 +27,34 @@ Then I rewrite the GUI code by swift.
- XCode 8.0+
- cocoapod 1.0.1+
## Download
From [here](https://github.com/shadowsocks/ShadowsocksX-NG/releases/)
## Fetures
- Use ss-local from shadowsocks-libev 2.4.6
- Update PAC by download GFW List from github.
- Update PAC by download GFW List from GitHub.
- Show QRCode for current server profile.
- Scan QRCode from screen.
- Auto launch at login.
- User rules for PAC.
- Support OTA
- An advance preferences panel to configure:
- An advanced preferences panel to configure:
- Local socks5 listen address.
- Local socks5 listen port.
- Local socks5 timeout.
- If enable UDP relay.
- GFW List url.
- Manual spesify network service profiles which would be configure the proxy.
- GFW List URL.
- Manual specify network service profiles which would be configure the proxy.
- Could reorder shadowsocks profiles by drag & drop in servers preferences panel.
## Different from orignal ShadowsocksX
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.
Run ss-local as a background service through launchd, not as an in-app process.
So after you quit the app, the ss-local maybe be still running.
Add a manual mode which won't configure the system proxy settings.
Added a manual mode which won't configure the system proxy settings.
Then you could configure your apps to use socks5 proxy manual.
## Contributing
@@ -61,9 +65,9 @@ ref: [GitFlow](http://nvie.com/posts/a-successful-git-branching-model/)
## TODO List
- [ ] Embed the http proxy server [privoxy](http://www.privoxy.org/).
- [x] Embed the http proxy server [privoxy](http://www.privoxy.org/), [get it](https://homebrew.bintray.com/bottles/privoxy-3.0.26.sierra.bottle.tar.gz).
## License
The project is released under the terms of GPLv3.
The project is released under the terms of the GPLv3.
+46 -14
View File
@@ -30,9 +30,6 @@
9B3FFF291D08A1DF0019A709 /* user-rule.txt in Resources */ = {isa = PBXBuildFile; fileRef = 9B3FFF281D08A1DF0019A709 /* user-rule.txt */; };
9B3FFF321D08CEE40019A709 /* SWBQRCodeWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B3FFF311D08CEE40019A709 /* SWBQRCodeWindowController.m */; };
9B3FFF341D08CEF70019A709 /* SWBQRCodeWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9B3FFF331D08CEF70019A709 /* SWBQRCodeWindowController.xib */; };
9B3FFF381D08CF110019A709 /* jquery.min.js in Resources */ = {isa = PBXBuildFile; fileRef = 9B3FFF351D08CF110019A709 /* jquery.min.js */; };
9B3FFF391D08CF110019A709 /* qrcode.min.js in Resources */ = {isa = PBXBuildFile; fileRef = 9B3FFF361D08CF110019A709 /* qrcode.min.js */; };
9B3FFF3A1D08CF110019A709 /* qrcode.htm in Resources */ = {isa = PBXBuildFile; fileRef = 9B3FFF371D08CF110019A709 /* qrcode.htm */; };
9B3FFF3E1D08D9910019A709 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9B3FFF3D1D08D9910019A709 /* SystemConfiguration.framework */; };
9B3FFF471D09CD3B0019A709 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B3FFF461D09CD3B0019A709 /* main.m */; };
9B3FFF4C1D09D8F70019A709 /* install_helper.sh in Resources */ = {isa = PBXBuildFile; fileRef = 9B3FFF4B1D09D8F70019A709 /* install_helper.sh */; };
@@ -52,6 +49,14 @@
9BEEF0751D04EF3E00FC52B3 /* PreferencesWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BEEF0731D04EF3E00FC52B3 /* PreferencesWindowController.swift */; };
9BEEF0781D04FE8A00FC52B3 /* LaunchAgentUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BEEF0771D04FE8A00FC52B3 /* LaunchAgentUtils.swift */; };
9BEEF07B1D05631500FC52B3 /* AdvPreferencesWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BEEF0791D05631500FC52B3 /* AdvPreferencesWindowController.swift */; };
C6D429931DA75988002A5711 /* install_privoxy.sh in Resources */ = {isa = PBXBuildFile; fileRef = C6D4298E1DA75988002A5711 /* install_privoxy.sh */; };
C6D429941DA75988002A5711 /* privoxy in Resources */ = {isa = PBXBuildFile; fileRef = C6D4298F1DA75988002A5711 /* privoxy */; };
C6D429951DA75988002A5711 /* reload_conf_privoxy.sh in Resources */ = {isa = PBXBuildFile; fileRef = C6D429901DA75988002A5711 /* reload_conf_privoxy.sh */; };
C6D429961DA75988002A5711 /* start_privoxy.sh in Resources */ = {isa = PBXBuildFile; fileRef = C6D429911DA75988002A5711 /* start_privoxy.sh */; };
C6D429971DA75988002A5711 /* stop_privoxy.sh in Resources */ = {isa = PBXBuildFile; fileRef = C6D429921DA75988002A5711 /* stop_privoxy.sh */; };
C6D429991DA76FBC002A5711 /* privoxy.config.example in Resources */ = {isa = PBXBuildFile; fileRef = C6D429981DA76FBC002A5711 /* privoxy.config.example */; };
C6E28E921DA79380004F8330 /* HTTPPreferencesWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6E28E911DA79380004F8330 /* HTTPPreferencesWindowController.swift */; };
C6E28E951DA79705004F8330 /* HTTPPreferencesWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = C6E28E971DA79705004F8330 /* HTTPPreferencesWindowController.xib */; };
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 */; };
@@ -132,9 +137,6 @@
9B3FFF301D08CEE40019A709 /* SWBQRCodeWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SWBQRCodeWindowController.h; sourceTree = "<group>"; };
9B3FFF311D08CEE40019A709 /* SWBQRCodeWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SWBQRCodeWindowController.m; sourceTree = "<group>"; };
9B3FFF331D08CEF70019A709 /* SWBQRCodeWindowController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SWBQRCodeWindowController.xib; sourceTree = "<group>"; };
9B3FFF351D08CF110019A709 /* jquery.min.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = jquery.min.js; sourceTree = "<group>"; };
9B3FFF361D08CF110019A709 /* qrcode.min.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = qrcode.min.js; sourceTree = "<group>"; };
9B3FFF371D08CF110019A709 /* qrcode.htm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = qrcode.htm; sourceTree = "<group>"; };
9B3FFF3B1D08D93B0019A709 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; };
9B3FFF3D1D08D9910019A709 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
9B3FFF441D09CD3B0019A709 /* proxy_conf_helper */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = proxy_conf_helper; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -161,6 +163,16 @@
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>"; };
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>"; };
C6D4298E1DA75988002A5711 /* install_privoxy.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = install_privoxy.sh; sourceTree = "<group>"; };
C6D4298F1DA75988002A5711 /* privoxy */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; path = privoxy; sourceTree = "<group>"; };
C6D429901DA75988002A5711 /* reload_conf_privoxy.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = reload_conf_privoxy.sh; sourceTree = "<group>"; };
C6D429911DA75988002A5711 /* start_privoxy.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = start_privoxy.sh; sourceTree = "<group>"; };
C6D429921DA75988002A5711 /* stop_privoxy.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = stop_privoxy.sh; sourceTree = "<group>"; };
C6D429981DA76FBC002A5711 /* privoxy.config.example */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = privoxy.config.example; sourceTree = "<group>"; };
C6E28E911DA79380004F8330 /* HTTPPreferencesWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HTTPPreferencesWindowController.swift; sourceTree = "<group>"; };
C6E28E961DA79705004F8330 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/HTTPPreferencesWindowController.xib; sourceTree = "<group>"; };
C6E28E991DA79709004F8330 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/HTTPPreferencesWindowController.strings"; sourceTree = "<group>"; };
C6E28E9B1DA79FB9004F8330 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/MainMenu.strings"; 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>"; };
@@ -215,12 +227,14 @@
9B07EFB01D048E900052D9DF /* Support Files */ = {
isa = PBXGroup;
children = (
C6D4298E1DA75988002A5711 /* install_privoxy.sh */,
C6D4298F1DA75988002A5711 /* privoxy */,
C6D429901DA75988002A5711 /* reload_conf_privoxy.sh */,
C6D429911DA75988002A5711 /* start_privoxy.sh */,
C6D429921DA75988002A5711 /* stop_privoxy.sh */,
9BE8FBBD1D0B1FB900CAFD01 /* libcrypto.1.0.0.dylib */,
9B172A6C1D0ADDDD00B87B9A /* Localizable.strings */,
9B3FFF4B1D09D8F70019A709 /* install_helper.sh */,
9B3FFF351D08CF110019A709 /* jquery.min.js */,
9B3FFF361D08CF110019A709 /* qrcode.min.js */,
9B3FFF371D08CF110019A709 /* qrcode.htm */,
9B3FFF281D08A1DF0019A709 /* user-rule.txt */,
9B3FFF261D0898EB0019A709 /* gfwlist.txt */,
9B3FFF221D088E8D0019A709 /* abp.js */,
@@ -233,6 +247,7 @@
9BEEF0661D04CE8D00FC52B3 /* start_ss_local.sh */,
9BEEF0671D04CE9A00FC52B3 /* stop_ss_local.sh */,
9BEEF0681D04CFE500FC52B3 /* reload_conf_ss_local.sh */,
C6D429981DA76FBC002A5711 /* privoxy.config.example */,
);
name = "Support Files";
sourceTree = "<group>";
@@ -314,6 +329,8 @@
9B0D55481D2CC85400A4A8E2 /* ProxyPreferencesController.xib */,
C8E42A6A1D4F270A0074C7EA /* UserRulesController.swift */,
C8E42A701D4F2CAF0074C7EA /* UserRulesController.xib */,
C6E28E911DA79380004F8330 /* HTTPPreferencesWindowController.swift */,
C6E28E971DA79705004F8330 /* HTTPPreferencesWindowController.xib */,
);
name = UI;
sourceTree = "<group>";
@@ -455,26 +472,30 @@
files = (
9BE8FBBF1D0B211600CAFD01 /* libcrypto.1.0.0.dylib in Resources */,
9B3FFF541D09E2D10019A709 /* proxy_conf_helper in Resources */,
C6E28E951DA79705004F8330 /* HTTPPreferencesWindowController.xib in Resources */,
9BEEF0691D04D4D500FC52B3 /* install_ss_local.sh in Resources */,
9B0D55461D2CC85400A4A8E2 /* ProxyPreferencesController.xib in Resources */,
9B2491B41D0ACC3A003BBECC /* PreferencesWindowController.xib in Resources */,
9B3FFF291D08A1DF0019A709 /* user-rule.txt in Resources */,
C6D429971DA75988002A5711 /* stop_privoxy.sh in Resources */,
C8E42A6E1D4F2CAF0074C7EA /* UserRulesController.xib in Resources */,
9BEEF06A1D04D4D500FC52B3 /* start_ss_local.sh in Resources */,
9B3FFF391D08CF110019A709 /* qrcode.min.js in Resources */,
9B3FFF3A1D08CF110019A709 /* qrcode.htm in Resources */,
C6D429941DA75988002A5711 /* privoxy in Resources */,
C6D429991DA76FBC002A5711 /* privoxy.config.example in Resources */,
9BEEF06B1D04D4D500FC52B3 /* stop_ss_local.sh in Resources */,
9B3FFF341D08CEF70019A709 /* SWBQRCodeWindowController.xib in Resources */,
9BEEF06C1D04D4D500FC52B3 /* reload_conf_ss_local.sh in Resources */,
9B3FFF231D088E8D0019A709 /* abp.js in Resources */,
9B07EFAD1D048E880052D9DF /* menu_icon.png in Resources */,
C6D429951DA75988002A5711 /* reload_conf_privoxy.sh in Resources */,
9B0BFFEB1D0460A70040E62B /* Assets.xcassets in Resources */,
9B2491B71D0ACC3E003BBECC /* AdvPreferencesWindowController.xib in Resources */,
9B3FFF381D08CF110019A709 /* jquery.min.js in Resources */,
9B3FFF271D0898EB0019A709 /* gfwlist.txt in Resources */,
C6D429931DA75988002A5711 /* install_privoxy.sh in Resources */,
9BC70EDC1D2E3E3100EDA4CA /* Localizable.strings in Resources */,
9B0BFFEE1D0460A70040E62B /* MainMenu.xib in Resources */,
9B3FFF4C1D09D8F70019A709 /* install_helper.sh in Resources */,
C6D429961DA75988002A5711 /* start_privoxy.sh in Resources */,
9B07EFAC1D048E880052D9DF /* menu_icon@2x.png in Resources */,
9B07EFA71D048BBB0052D9DF /* ss-local in Resources */,
9B07EFAF1D048E880052D9DF /* menu_icon_disabled@2x.png in Resources */,
@@ -635,6 +656,7 @@
9B0BFFE91D0460A70040E62B /* AppDelegate.swift in Sources */,
9BA04B231D23D5A5005AAD7F /* ProxyConfTool.m in Sources */,
9BEEF0781D04FE8A00FC52B3 /* LaunchAgentUtils.swift in Sources */,
C6E28E921DA79380004F8330 /* HTTPPreferencesWindowController.swift in Sources */,
C8E42A6C1D4F270A0074C7EA /* UserRulesController.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -676,6 +698,7 @@
children = (
9B0BFFED1D0460A70040E62B /* Base */,
9B0D55451D2CC1B800A4A8E2 /* zh-Hans */,
C6E28E9B1DA79FB9004F8330 /* zh-Hans */,
);
name = MainMenu.xib;
sourceTree = "<group>";
@@ -716,6 +739,15 @@
name = AdvPreferencesWindowController.xib;
sourceTree = "<group>";
};
C6E28E971DA79705004F8330 /* HTTPPreferencesWindowController.xib */ = {
isa = PBXVariantGroup;
children = (
C6E28E961DA79705004F8330 /* Base */,
C6E28E991DA79709004F8330 /* zh-Hans */,
);
name = HTTPPreferencesWindowController.xib;
sourceTree = "<group>";
};
C8E42A701D4F2CAF0074C7EA /* UserRulesController.xib */ = {
isa = PBXVariantGroup;
children = (
@@ -765,7 +797,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.10;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
@@ -804,7 +836,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.10;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
};
+86 -42
View File
@@ -17,7 +17,8 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
var advPreferencesWinCtrl: AdvPreferencesWindowController!
var proxyPreferencesWinCtrl: ProxyPreferencesController!
var editUserRulesWinCtrl: UserRulesController!
var httpPreferencesWinCtrl : HTTPPreferencesWindowController!
var launchAtLoginController: LaunchAtLoginController = LaunchAtLoginController()
@IBOutlet weak var window: NSWindow!
@@ -29,6 +30,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
@IBOutlet weak var autoModeMenuItem: NSMenuItem!
@IBOutlet weak var globalModeMenuItem: NSMenuItem!
@IBOutlet weak var manualModeMenuItem: NSMenuItem!
@IBOutlet weak var showRunningModeMenuItem: NSMenuItem!
@IBOutlet weak var serversMenuItem: NSMenuItem!
@IBOutlet var showQRCodeMenuItem: NSMenuItem!
@@ -39,6 +41,8 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
var statusItem: NSStatusItem!
static let StatusItemIconWidth:CGFloat = 20
func applicationDidFinishLaunching(_ aNotification: Notification) {
// Insert code here to initialize your application
@@ -46,7 +50,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
// Prepare ss-local
InstallSSLocal()
InstallPrivoxy()
// Prepare defaults
let defaults = UserDefaults.standard
defaults.register(defaults: [
@@ -54,16 +58,19 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
"ShadowsocksRunningMode": "auto",
"LocalSocks5.ListenPort": NSNumber(value: 1086 as UInt16),
"LocalSocks5.ListenAddress": "127.0.0.1",
"PacServer.ListenAddress": "127.0.0.1",
"PacServer.ListenPort":NSNumber(value: 8090 as UInt16),
"LocalSocks5.Timeout": NSNumber(value: 60 as UInt),
"LocalSocks5.EnableUDPRelay": NSNumber(value: false as Bool),
"LocalSocks5.EnableVerboseMode": NSNumber(value: false as Bool),
"GFWListURL": "https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt",
"AutoConfigureNetworkServices": NSNumber(value: true as Bool)
])
"AutoConfigureNetworkServices": NSNumber(value: true as Bool),
"LocalHTTP.ListenAddress": "127.0.0.1",
"LocalHTTP.ListenPort": NSNumber(value: 1087 as UInt16),
"LocalHTTPOn": true,
"LocalHTTP.FollowGlobel": true
])
statusItem = NSStatusBar.system().statusItem(withLength: 20)
statusItem = NSStatusBar.system().statusItem(withLength: AppDelegate.StatusItemIconWidth)
let image = NSImage(named: "menu_icon")
image?.isTemplate = true
statusItem.image = image
@@ -73,13 +80,13 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
let notifyCenter = NotificationCenter.default
notifyCenter.addObserver(forName: NSNotification.Name(rawValue: NOTIFY_ADV_PROXY_CONF_CHANGED), object: nil, queue: nil
, using: {
(note) in
(note) in
self.applyConfig()
}
)
notifyCenter.addObserver(forName: NSNotification.Name(rawValue: NOTIFY_SERVER_PROFILES_CHANGED), object: nil, queue: nil
, using: {
(note) in
(note) in
let profileMgr = ServerProfileManager.instance
if profileMgr.activeProfileId == nil &&
profileMgr.profiles.count > 0{
@@ -93,11 +100,18 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
)
notifyCenter.addObserver(forName: NSNotification.Name(rawValue: NOTIFY_ADV_CONF_CHANGED), object: nil, queue: nil
, using: {
(note) in
(note) in
SyncSSLocal()
self.applyConfig()
}
)
notifyCenter.addObserver(forName: NSNotification.Name(rawValue: NOTIFY_HTTP_CONF_CHANGED), object: nil, queue: nil
, using: {
(note) in
SyncPrivoxy()
self.applyConfig()
}
)
notifyCenter.addObserver(forName: NSNotification.Name(rawValue: "NOTIFY_FOUND_SS_URL"), object: nil, queue: nil) {
(note: Notification) in
if let userInfo = (note as NSNotification).userInfo {
@@ -148,17 +162,16 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
updateLaunchAtLoginMenu()
ProxyConfHelper.install()
ProxyConfHelper.startMonitorPAC()
applyConfig()
SyncSSLocal()
}
func applicationWillTerminate(_ aNotification: Notification) {
// Insert code here to tear down your application
StopSSLocal()
ProxyConfHelper.disableProxy("hi")
let defaults = UserDefaults.standard
defaults.set(false, forKey: "ShadowsocksOn")
ProxyConfHelper.stopPACServer()
StopPrivoxy()
ProxyConfHelper.disableProxy()
}
func applyConfig() {
@@ -168,16 +181,18 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
if isOn {
StartSSLocal()
StartPrivoxy()
if mode == "auto" {
ProxyConfHelper.enablePACProxy("hi")
ProxyConfHelper.enablePACProxy()
} else if mode == "global" {
ProxyConfHelper.enableGlobalProxy()
} else if mode == "manual" {
ProxyConfHelper.disableProxy("hi")
ProxyConfHelper.disableProxy()
}
} else {
StopSSLocal()
ProxyConfHelper.disableProxy("hi")
StopPrivoxy()
ProxyConfHelper.disableProxy()
}
}
@@ -191,7 +206,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
applyConfig()
}
@IBAction func updateGFWList(_ sender: NSMenuItem) {
UpdatePACFromGFWList()
}
@@ -202,7 +217,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
}
let ctrl = UserRulesController(windowNibName: "UserRulesController")
editUserRulesWinCtrl = ctrl
ctrl.showWindow(self)
NSApp.activate(ignoringOtherApps: true)
ctrl.window?.makeKeyAndOrderFront(self)
@@ -240,7 +255,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
@IBAction func scanQRCodeFromScreen(_ sender: NSMenuItem) {
ScanQRCodeOnScreen()
}
@IBAction func toggleLaunghAtLogin(_ sender: NSMenuItem) {
launchAtLoginController.launchAtLogin = !launchAtLoginController.launchAtLogin;
updateLaunchAtLoginMenu()
@@ -291,6 +306,18 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
ctrl.window?.makeKeyAndOrderFront(self)
}
@IBAction func editHTTPPreferences(_ sender: NSMenuItem) {
if httpPreferencesWinCtrl != nil {
httpPreferencesWinCtrl.close()
}
let ctrl = HTTPPreferencesWindowController(windowNibName: "HTTPPreferencesWindowController")
httpPreferencesWinCtrl = ctrl
ctrl.showWindow(self)
NSApp.activate(ignoringOtherApps: true)
ctrl.window?.makeKeyAndOrderFront(self)
}
@IBAction func editProxyPreferences(_ sender: NSObject) {
if proxyPreferencesWinCtrl != nil {
proxyPreferencesWinCtrl.close()
@@ -331,6 +358,14 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
NSApp.activate(ignoringOtherApps: true)
}
@IBAction func showRunningMode(_ sender: NSMenuItem) {
sender.state = sender.state == 1 ? 0 : 1
let defaults = UserDefaults.standard
let isShown = (sender.state == 1)
defaults.set(isShown, forKey: "ShowRunningModeOnStatusBar")
updateStatusItemUI(isShownnRunningMode: isShown)
}
func updateLaunchAtLoginMenu() {
if launchAtLoginController.launchAtLogin {
lanchAtLoginMenuItem.state = 1
@@ -342,22 +377,26 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
func updateRunningModeMenu() {
let defaults = UserDefaults.standard
let mode = defaults.string(forKey: "ShadowsocksRunningMode")
showRunningModeMenuItem.title = "Show Running Mode On Status Bar".localized
showRunningModeMenuItem.state = defaults.bool(forKey: "ShowRunningModeOnStatusBar") ? 1 : 0
var serverMenuText = "Servers".localized
for v in defaults.array(forKey: "ServerProfiles")! {
let profile = v as! [String:Any]
if profile["Id"] as! String == defaults.string(forKey: "ActiveServerProfileId")! {
let mgr = ServerProfileManager.instance
for p in mgr.profiles {
if mgr.activeProfileId == p.uuid {
var profileName :String
if profile["Remark"] as! String != "" {
profileName = profile["Remark"] as! String
if !p.remark.isEmpty {
profileName = p.remark
} else {
profileName = profile["ServerHost"] as! String
profileName = p.serverHost
}
serverMenuText = "\(serverMenuText) - \(profileName)"
}
}
serversMenuItem.title = serverMenuText
if mode == "auto" {
proxyMenuItem.title = "Proxy - Auto By PAC".localized
autoModeMenuItem.state = 1
@@ -374,22 +413,27 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
globalModeMenuItem.state = 0
manualModeMenuItem.state = 1
}
updateStatusItemUI()
let isShown = defaults.bool(forKey: "ShowRunningModeOnStatusBar")
updateStatusItemUI(isShownnRunningMode: isShown)
}
func updateStatusItemUI() {
let defaults = UserDefaults.standard
let mode = defaults.string(forKey: "ShadowsocksRunningMode")
if mode == "auto" {
statusItem.title = "Auto".localized
} else if mode == "global" {
statusItem.title = "Global".localized
} else if mode == "manual" {
statusItem.title = "Manual".localized
func updateStatusItemUI(isShownnRunningMode: Bool) {
if isShownnRunningMode {
let defaults = UserDefaults.standard
let mode = defaults.string(forKey: "ShadowsocksRunningMode")
if mode == "auto" {
statusItem.title = "Auto".localized
} else if mode == "global" {
statusItem.title = "Global".localized
} else if mode == "manual" {
statusItem.title = "Manual".localized
}
let titleWidth = statusItem.title!.size(withAttributes: [NSFontAttributeName: statusItem.button!.font!]).width
let imageWidth:CGFloat = AppDelegate.StatusItemIconWidth
statusItem.length = titleWidth + imageWidth + 2
} else {
statusItem.length = AppDelegate.StatusItemIconWidth
}
let titleWidth = statusItem.title!.size(withAttributes: [NSFontAttributeName: statusItem.button!.font!]).width
let imageWidth:CGFloat = 22
statusItem.length = titleWidth + imageWidth
}
func updateMainMenu() {
@@ -452,7 +496,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
, userInfo: [
"ruls": [url],
"source": "url",
])
])
}
}
}
@@ -1,7 +1,8 @@
<?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">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11201" systemVersion="16A323" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10117"/>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11201"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="AdvPreferencesWindowController" customModule="ShadowsocksX_NG" customModuleProvider="target">
@@ -11,36 +12,21 @@
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="Advance Preferences" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" animationBehavior="default" id="F0z-JX-Cv5">
<window title="Advanced Preferences" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" animationBehavior="default" id="F0z-JX-Cv5">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="469" y="456" width="480" height="416"/>
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
<rect key="contentRect" x="562" y="415" width="480" height="345"/>
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
<view key="contentView" id="se5-gp-TjO">
<rect key="frame" x="0.0" y="0.0" width="480" height="416"/>
<rect key="frame" x="0.0" y="0.0" width="480" height="345"/>
<autoresizingMask key="autoresizingMask"/>
<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 verticalHuggingPriority="750" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="ayu-Tb-kmf">
<rect key="frame" x="41" y="120" width="405" height="5"/>
</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"/>
<rect key="frame" x="54" y="20" width="378" height="69"/>
<constraints>
<constraint firstAttribute="height" constant="69" id="NVe-Ir-JCv"/>
<constraint firstAttribute="height" constant="69" id="yzO-2D-eTT"/>
</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"/>
@@ -56,21 +42,18 @@
</connections>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="wCp-nB-dda">
<rect key="frame" x="18" y="379" width="439" height="17"/>
<rect key="frame" x="18" y="308" 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="368" 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 verticalHuggingPriority="750" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="JBW-8M-eHP">
<rect key="frame" x="36" y="297" width="403" height="5"/>
</box>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="S5h-Xx-HUG">
<rect key="frame" x="27" y="306" width="204" height="17"/>
<rect key="frame" x="27" y="239" width="204" height="17"/>
<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"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@@ -78,7 +61,7 @@
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="xWv-tc-lQe">
<rect key="frame" x="27" y="343" width="204" height="17"/>
<rect key="frame" x="27" y="272" width="204" height="17"/>
<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"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@@ -86,7 +69,7 @@
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Q2L-Fh-TW1">
<rect key="frame" x="237" y="340" width="160" height="22"/>
<rect key="frame" x="237" y="269" width="160" height="22"/>
<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"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
@@ -101,7 +84,7 @@
</connections>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="e3S-m6-k5Y">
<rect key="frame" x="27" y="190" width="204" height="17"/>
<rect key="frame" x="27" y="175" width="204" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Timeout:" id="i4l-2S-gOQ">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@@ -109,7 +92,7 @@
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="sRP-xs-alR">
<rect key="frame" x="237" y="185" width="60" height="22"/>
<rect key="frame" x="237" y="173" 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">
<font key="font" metaFont="system"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
@@ -125,7 +108,7 @@
</connections>
</textField>
<button translatesAutoresizingMaskIntoConstraints="NO" id="DiD-K0-Y43">
<rect key="frame" x="235" y="155" width="219" height="18"/>
<rect key="frame" x="235" y="149" 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">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
@@ -135,9 +118,9 @@
</connections>
</button>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="XQ5-fw-o8t">
<rect key="frame" x="237" y="303" width="60" height="22"/>
<rect key="frame" x="237" y="237" width="60" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="60" id="reo-ha-VKi"/>
<constraint firstAttribute="width" constant="60" id="S9f-Rp-2gz"/>
</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">
<font key="font" metaFont="system"/>
@@ -154,10 +137,7 @@
</connections>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="eoD-7r-Q85">
<rect key="frame" x="303" y="188" width="96" height="17"/>
<constraints>
<constraint firstAttribute="width" constant="92" id="xw1-XT-mjQ"/>
</constraints>
<rect key="frame" x="303" y="175" width="96" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Seconds" id="Gd3-Fm-sWh">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@@ -174,16 +154,16 @@
<binding destination="pR1-Bo-AWz" name="value" keyPath="values.LocalSocks5.EnableVerboseMode" id="Nu9-zu-vUE"/>
</connections>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Wsf-gl-dkY">
<rect key="frame" x="90" y="230" width="141" height="17"/>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Wsf-gl-dkY">
<rect key="frame" x="90" y="207" width="141" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Local PAC Listien Port:" id="DiO-6B-ALO">
<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" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="FoE-i9-Rfb">
<rect key="frame" x="237" y="227" width="60" height="22"/>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="FoE-i9-Rfb">
<rect key="frame" x="237" y="205" 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="XhZ-XN-MoS">
<font key="font" metaFont="system"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
@@ -195,22 +175,15 @@
<bool key="NSContinuouslyUpdatesValue" value="YES"/>
</dictionary>
</binding>
<outlet property="formatter" destination="uE9-0u-CJW" id="YNn-yx-cWk"/>
</connections>
</textField>
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8Co-1p-O4m">
<rect key="frame" x="237" y="265" width="160" height="22"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="Z9Z-Tz-7l4">
<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.PacServer.ListenAddress" id="MkH-lr-4Q7"/>
</connections>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="agk-yO-9kp">
<rect key="frame" x="73" y="268" width="158" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Local PAC listen Address:" id="tIW-Xu-BJd">
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="I4a-N9-Tkv">
<rect key="frame" x="52" y="97" width="192" height="17"/>
<constraints>
<constraint firstAttribute="width" constant="188" id="mcl-Uv-Y6n"/>
</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"/>
@@ -218,51 +191,57 @@
</textField>
</subviews>
<constraints>
<constraint firstItem="xWv-tc-lQe" firstAttribute="baseline" secondItem="Q2L-Fh-TW1" secondAttribute="baseline" id="0ub-69-rbe"/>
<constraint firstAttribute="bottom" secondItem="6MD-Ry-R5P" secondAttribute="bottom" constant="20" symbolic="YES" id="1VT-Fs-nNp"/>
<constraint firstItem="S5h-Xx-HUG" firstAttribute="leading" secondItem="e3S-m6-k5Y" secondAttribute="leading" id="1Y0-Oh-Ev4"/>
<constraint firstItem="wCp-nB-dda" firstAttribute="top" secondItem="se5-gp-TjO" secondAttribute="top" constant="20" symbolic="YES" id="4af-lJ-vAL"/>
<constraint firstItem="xWv-tc-lQe" firstAttribute="leading" secondItem="S5h-Xx-HUG" secondAttribute="leading" id="7E0-aW-12T"/>
<constraint firstItem="6MD-Ry-R5P" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="49" id="8CU-pQ-jDz"/>
<constraint firstItem="xWv-tc-lQe" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="29" id="8oq-65-XGK"/>
<constraint firstItem="eoD-7r-Q85" firstAttribute="leading" secondItem="sRP-xs-alR" secondAttribute="trailing" constant="8" symbolic="YES" id="GhL-we-2co"/>
<constraint firstItem="sRP-xs-alR" firstAttribute="leading" secondItem="DiD-K0-Y43" secondAttribute="leading" id="H7k-Nh-YHo"/>
<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="Ij2-mo-WRt"/>
<constraint firstItem="DiD-K0-Y43" firstAttribute="leading" secondItem="qVQ-tJ-cO6" secondAttribute="leading" id="J5O-DE-8O9"/>
<constraint firstItem="Q2L-Fh-TW1" firstAttribute="top" secondItem="JBW-8M-eHP" secondAttribute="bottom" constant="8" symbolic="YES" id="Jkq-uJ-Wv4"/>
<constraint firstAttribute="trailing" secondItem="wCp-nB-dda" secondAttribute="trailing" constant="25" id="Mod-B8-1Yl"/>
<constraint firstItem="wCp-nB-dda" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="20" symbolic="YES" id="R3i-gt-6zg"/>
<constraint firstItem="DiD-K0-Y43" firstAttribute="trailing" secondItem="qVQ-tJ-cO6" secondAttribute="trailing" id="WaY-S9-VQ2"/>
<constraint firstItem="I4a-N9-Tkv" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="50" id="Wd9-qu-Mx8"/>
<constraint firstItem="e3S-m6-k5Y" firstAttribute="top" secondItem="sRP-xs-alR" secondAttribute="top" id="Xmc-dV-VXv"/>
<constraint firstItem="JBW-8M-eHP" firstAttribute="top" secondItem="wCp-nB-dda" secondAttribute="bottom" constant="8" symbolic="YES" id="Ysd-52-5Fn"/>
<constraint firstAttribute="trailing" secondItem="Q2L-Fh-TW1" secondAttribute="trailing" constant="83" id="ZoL-73-xKa"/>
<constraint firstItem="sRP-xs-alR" firstAttribute="leading" secondItem="e3S-m6-k5Y" secondAttribute="trailing" constant="8" symbolic="YES" id="ZvN-ZN-EVZ"/>
<constraint firstItem="sRP-xs-alR" firstAttribute="baseline" secondItem="eoD-7r-Q85" secondAttribute="baseline" id="aXC-g0-ZpB"/>
<constraint firstItem="qVQ-tJ-cO6" firstAttribute="top" secondItem="DiD-K0-Y43" secondAttribute="bottom" constant="12" id="ccj-Fd-7z7"/>
<constraint firstItem="6MD-Ry-R5P" firstAttribute="top" secondItem="I4a-N9-Tkv" secondAttribute="bottom" constant="8" symbolic="YES" id="dPZ-gY-1am"/>
<constraint firstItem="JBW-8M-eHP" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="36" id="dSL-lu-CVv"/>
<constraint firstItem="XQ5-fw-o8t" firstAttribute="top" secondItem="Q2L-Fh-TW1" secondAttribute="bottom" constant="15" id="e6i-xd-BD3"/>
<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"/>
<constraint firstItem="wCp-nB-dda" firstAttribute="top" secondItem="se5-gp-TjO" secondAttribute="top" constant="20" symbolic="YES" id="1TH-Y5-EN7"/>
<constraint firstItem="Q2L-Fh-TW1" firstAttribute="leading" secondItem="xWv-tc-lQe" secondAttribute="trailing" constant="8" symbolic="YES" id="3JQ-t1-YfQ"/>
<constraint firstItem="FoE-i9-Rfb" firstAttribute="trailing" secondItem="sRP-xs-alR" secondAttribute="trailing" id="5DW-3A-T38"/>
<constraint firstAttribute="trailing" secondItem="DiD-K0-Y43" secondAttribute="trailing" constant="28" id="5Ss-aV-lwl"/>
<constraint firstAttribute="trailing" secondItem="wCp-nB-dda" secondAttribute="trailing" constant="25" id="8Sj-oS-ug5"/>
<constraint firstItem="ayu-Tb-kmf" firstAttribute="centerX" secondItem="6MD-Ry-R5P" secondAttribute="centerX" id="9JX-AU-p9u"/>
<constraint firstItem="sRP-xs-alR" firstAttribute="leading" secondItem="e3S-m6-k5Y" secondAttribute="trailing" constant="8" symbolic="YES" id="9Ln-JB-XKl"/>
<constraint firstItem="Q2L-Fh-TW1" firstAttribute="trailing" secondItem="eoD-7r-Q85" secondAttribute="trailing" id="Ddi-cI-3P7"/>
<constraint firstItem="Wsf-gl-dkY" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="92" id="Drm-DE-zR4"/>
<constraint firstItem="DiD-K0-Y43" firstAttribute="leading" secondItem="qVQ-tJ-cO6" secondAttribute="leading" id="FEU-T2-r8S"/>
<constraint firstItem="xWv-tc-lQe" firstAttribute="leading" secondItem="S5h-Xx-HUG" secondAttribute="leading" id="HDG-YV-pnR"/>
<constraint firstItem="I4a-N9-Tkv" firstAttribute="top" secondItem="ayu-Tb-kmf" secondAttribute="bottom" constant="8" symbolic="YES" id="IFN-Y7-dx7"/>
<constraint firstItem="FoE-i9-Rfb" firstAttribute="top" secondItem="XQ5-fw-o8t" secondAttribute="bottom" constant="10" symbolic="YES" id="Kmf-cm-gih"/>
<constraint firstAttribute="trailing" secondItem="ayu-Tb-kmf" secondAttribute="trailing" constant="34" id="LVk-Xo-yXp"/>
<constraint firstItem="sRP-xs-alR" firstAttribute="centerY" secondItem="eoD-7r-Q85" secondAttribute="centerY" id="Li6-iE-6AU"/>
<constraint firstItem="6MD-Ry-R5P" firstAttribute="top" secondItem="I4a-N9-Tkv" secondAttribute="bottom" constant="8" symbolic="YES" id="M7l-Nl-fbE"/>
<constraint firstItem="sRP-xs-alR" firstAttribute="top" secondItem="FoE-i9-Rfb" secondAttribute="bottom" constant="10" symbolic="YES" id="Nf3-lQ-J7p"/>
<constraint firstItem="FoE-i9-Rfb" firstAttribute="leading" secondItem="Wsf-gl-dkY" secondAttribute="trailing" constant="8" symbolic="YES" id="Q1J-Od-oEq"/>
<constraint firstItem="S5h-Xx-HUG" firstAttribute="leading" secondItem="e3S-m6-k5Y" secondAttribute="leading" id="Rp8-TE-LBs"/>
<constraint firstItem="wCp-nB-dda" firstAttribute="centerX" secondItem="JBW-8M-eHP" secondAttribute="centerX" id="Uf5-d8-VAG"/>
<constraint firstItem="ayu-Tb-kmf" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="41" id="Ujd-dM-d4B"/>
<constraint firstItem="qVQ-tJ-cO6" firstAttribute="top" secondItem="DiD-K0-Y43" secondAttribute="bottom" constant="6" symbolic="YES" id="WUJ-KS-sHp"/>
<constraint firstItem="xWv-tc-lQe" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="29" id="WsH-Rq-EQo"/>
<constraint firstItem="I4a-N9-Tkv" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="54" id="Y5c-vH-Bvw"/>
<constraint firstItem="XQ5-fw-o8t" firstAttribute="top" secondItem="Q2L-Fh-TW1" secondAttribute="bottom" constant="10" symbolic="YES" id="YJa-4z-USU"/>
<constraint firstItem="e3S-m6-k5Y" firstAttribute="baseline" secondItem="eoD-7r-Q85" secondAttribute="baseline" id="Yfx-Hf-red"/>
<constraint firstItem="XQ5-fw-o8t" firstAttribute="leading" secondItem="S5h-Xx-HUG" secondAttribute="trailing" constant="8" symbolic="YES" id="ZSX-Wf-s3b"/>
<constraint firstItem="sRP-xs-alR" firstAttribute="leading" secondItem="DiD-K0-Y43" secondAttribute="leading" id="cP0-4c-2tD"/>
<constraint firstItem="xWv-tc-lQe" firstAttribute="baseline" secondItem="Q2L-Fh-TW1" secondAttribute="baseline" id="cjH-5Y-BPd"/>
<constraint firstItem="I4a-N9-Tkv" firstAttribute="leading" secondItem="6MD-Ry-R5P" secondAttribute="leading" id="fGN-nB-Tp7"/>
<constraint firstItem="Q2L-Fh-TW1" firstAttribute="top" secondItem="JBW-8M-eHP" secondAttribute="bottom" constant="8" symbolic="YES" id="fIf-uU-Dis"/>
<constraint firstItem="Wsf-gl-dkY" firstAttribute="centerY" secondItem="FoE-i9-Rfb" secondAttribute="centerY" id="fSm-ZO-WGT"/>
<constraint firstItem="DiD-K0-Y43" firstAttribute="trailing" secondItem="qVQ-tJ-cO6" secondAttribute="trailing" id="i1K-yN-yvs"/>
<constraint firstItem="S5h-Xx-HUG" firstAttribute="centerY" secondItem="XQ5-fw-o8t" secondAttribute="centerY" id="iv1-8j-dpK"/>
<constraint firstItem="Q2L-Fh-TW1" firstAttribute="leading" secondItem="XQ5-fw-o8t" secondAttribute="leading" id="m95-qm-v0W"/>
<constraint firstItem="XQ5-fw-o8t" firstAttribute="leading" secondItem="FoE-i9-Rfb" secondAttribute="leading" id="q1D-Uw-c6k"/>
<constraint firstItem="JBW-8M-eHP" firstAttribute="top" secondItem="wCp-nB-dda" secondAttribute="bottom" constant="8" symbolic="YES" id="r2h-9S-EeW"/>
<constraint firstItem="JBW-8M-eHP" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="36" id="si5-nv-pTq"/>
<constraint firstItem="DiD-K0-Y43" firstAttribute="top" secondItem="sRP-xs-alR" secondAttribute="bottom" constant="8" symbolic="YES" id="vty-s2-Oei"/>
<constraint firstItem="FoE-i9-Rfb" firstAttribute="leading" secondItem="sRP-xs-alR" secondAttribute="leading" id="xbo-Fv-kdo"/>
<constraint firstItem="wCp-nB-dda" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="20" symbolic="YES" id="xxa-Zo-EGP"/>
<constraint firstItem="XQ5-fw-o8t" firstAttribute="trailing" secondItem="FoE-i9-Rfb" secondAttribute="trailing" id="yOU-d6-kg2"/>
<constraint firstAttribute="trailing" secondItem="Q2L-Fh-TW1" secondAttribute="trailing" constant="83" id="yly-wy-CHR"/>
<constraint firstItem="eoD-7r-Q85" firstAttribute="leading" secondItem="sRP-xs-alR" secondAttribute="trailing" constant="8" symbolic="YES" id="ywe-Ph-kz3"/>
<constraint firstItem="ayu-Tb-kmf" firstAttribute="top" secondItem="qVQ-tJ-cO6" secondAttribute="bottom" constant="8" symbolic="YES" id="zH1-MR-VHw"/>
</constraints>
</view>
<connections>
<outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
</connections>
<point key="canvasLocation" x="346" y="328"/>
<point key="canvasLocation" x="346" y="292.5"/>
</window>
<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"/>
@@ -0,0 +1,115 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11201" systemVersion="16A323" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11201"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="HTTPPreferencesWindowController" customModule="ShadowsocksX_NG" customModuleProvider="target"/>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="HTTP Proxy Preferences" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" frameAutosaveName="" animationBehavior="default" id="vS3-DL-Nq3">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<rect key="contentRect" x="109" y="131" width="209" height="197"/>
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1057"/>
<view key="contentView" id="Qef-Mj-9z1">
<rect key="frame" x="0.0" y="0.0" width="209" height="197"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<button translatesAutoresizingMaskIntoConstraints="NO" id="hgn-81-fsH">
<rect key="frame" x="18" y="161" width="138" height="18"/>
<buttonCell key="cell" type="check" title="HTTP Proxy Enable" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="dqU-MG-Sum">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<binding destination="Adn-6l-wm4" name="value" keyPath="values.LocalHTTPOn" id="Oey-LL-A84"/>
</connections>
</button>
<button translatesAutoresizingMaskIntoConstraints="NO" id="P4f-0N-7JI">
<rect key="frame" x="18" y="133" width="141" height="18"/>
<buttonCell key="cell" type="check" title="Follow Globel Mode" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="ofk-Pc-c8f">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<binding destination="Adn-6l-wm4" name="value" keyPath="values.LocalHTTP.FollowGlobel" id="mwB-AA-WgF"/>
</connections>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="CKF-K9-m8X">
<rect key="frame" x="18" y="103" width="173" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="HTTP Proxy Listen Address:" id="qd0-kc-ttB">
<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 horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Ecd-cS-zUI">
<rect key="frame" x="18" y="50" width="149" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="HTTP Proxy Listen Port:" id="2Sd-yn-gdY">
<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" translatesAutoresizingMaskIntoConstraints="NO" id="vsw-6L-eh3">
<rect key="frame" x="20" y="73" width="169" height="22"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="chf-Id-e5F">
<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="Adn-6l-wm4" name="value" keyPath="values.LocalHTTP.ListenAddress" id="TLb-4n-tsg">
<dictionary key="options">
<bool key="NSContinuouslyUpdatesValue" value="YES"/>
</dictionary>
</binding>
</connections>
</textField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="lD1-xm-Qy3">
<rect key="frame" x="20" y="20" width="169" height="22"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="KR0-Ey-wq8">
<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="Adn-6l-wm4" name="value" keyPath="values.LocalHTTP.ListenPort" id="bVc-jE-7Ve">
<dictionary key="options">
<bool key="NSContinuouslyUpdatesValue" value="YES"/>
</dictionary>
</binding>
<outlet property="formatter" destination="ji3-e7-HNW" id="xWV-vJ-7eq"/>
</connections>
</textField>
</subviews>
<constraints>
<constraint firstItem="hgn-81-fsH" firstAttribute="leading" secondItem="P4f-0N-7JI" secondAttribute="leading" id="1R6-Zi-ctk"/>
<constraint firstItem="P4f-0N-7JI" firstAttribute="top" secondItem="hgn-81-fsH" secondAttribute="bottom" constant="14" id="45x-uF-HIp"/>
<constraint firstItem="vsw-6L-eh3" firstAttribute="leading" secondItem="Ecd-cS-zUI" secondAttribute="leading" id="5Fh-yR-UAH"/>
<constraint firstItem="CKF-K9-m8X" firstAttribute="trailing" secondItem="vsw-6L-eh3" secondAttribute="trailing" id="7Y3-mK-KBC"/>
<constraint firstItem="hgn-81-fsH" firstAttribute="top" secondItem="Qef-Mj-9z1" secondAttribute="top" constant="20" symbolic="YES" id="Frc-hf-qrH"/>
<constraint firstItem="vsw-6L-eh3" firstAttribute="trailing" secondItem="lD1-xm-Qy3" secondAttribute="trailing" id="How-c9-yLj"/>
<constraint firstItem="vsw-6L-eh3" firstAttribute="top" secondItem="CKF-K9-m8X" secondAttribute="bottom" constant="8" symbolic="YES" id="JrQ-Uu-Dpf"/>
<constraint firstItem="Ecd-cS-zUI" firstAttribute="top" secondItem="vsw-6L-eh3" secondAttribute="bottom" constant="6" id="Pcx-Pb-Am7"/>
<constraint firstItem="Ecd-cS-zUI" firstAttribute="leading" secondItem="lD1-xm-Qy3" secondAttribute="leading" id="VkT-8o-eV5"/>
<constraint firstItem="hgn-81-fsH" firstAttribute="leading" secondItem="Qef-Mj-9z1" secondAttribute="leading" constant="20" symbolic="YES" id="Ybz-LX-Dja"/>
<constraint firstItem="P4f-0N-7JI" firstAttribute="leading" secondItem="CKF-K9-m8X" secondAttribute="leading" id="Zgf-bS-WDG"/>
<constraint firstItem="lD1-xm-Qy3" firstAttribute="top" secondItem="Ecd-cS-zUI" secondAttribute="bottom" constant="8" symbolic="YES" id="g09-v2-V3P"/>
<constraint firstAttribute="bottom" secondItem="lD1-xm-Qy3" secondAttribute="bottom" constant="20" symbolic="YES" id="hSP-RV-6f4"/>
<constraint firstItem="CKF-K9-m8X" firstAttribute="leading" secondItem="vsw-6L-eh3" secondAttribute="leading" id="imf-dG-QVW"/>
</constraints>
</view>
<connections>
<outlet property="delegate" destination="-2" id="mD3-X9-VEN"/>
</connections>
<point key="canvasLocation" x="-19.5" y="109.5"/>
</window>
<userDefaultsController representsSharedInstance="YES" id="Adn-6l-wm4"/>
<numberFormatter formatterBehavior="default10_4" usesGroupingSeparator="NO" groupingSize="0" minimumIntegerDigits="0" maximumIntegerDigits="42" id="ji3-e7-HNW" userLabel="Port Number Formatter">
<real key="minimum" value="128"/>
<real key="maximum" value="65535"/>
</numberFormatter>
</objects>
</document>
+8
View File
@@ -47,3 +47,11 @@
"Proxy - Manual" = "Proxy - Manual";
"Servers" = "Servers";
"Auto" = "PAC";
"Global" = "Global";
"Manual" = "Manual";
"Show Running Mode On Status Bar" = "Show Running Mode On Status Bar";
+33 -5
View File
@@ -1,7 +1,8 @@
<?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">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11201" systemVersion="16A323" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10117"/>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11201"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
@@ -24,6 +25,7 @@
<outlet property="serversMenuItem" destination="u5M-hQ-VSc" id="8gp-SY-Y4U"/>
<outlet property="serversPreferencesMenuItem" destination="M5r-E7-44f" id="voe-SX-k6a"/>
<outlet property="showQRCodeMenuItem" destination="R6A-96-Zcb" id="XHz-pz-nCz"/>
<outlet property="showRunningModeMenuItem" destination="CCV-hX-fVA" id="AU2-hH-w8F"/>
<outlet property="statusMenu" destination="Hob-KD-bx9" id="clA-ZW-0pT"/>
<outlet property="toggleRunningMenuItem" destination="GSu-Tf-StS" id="XHw-pU-nCa"/>
</connections>
@@ -77,7 +79,13 @@
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="bMX-qn-Qwi"/>
<menuItem title="Advance Proxy Preference..." id="sbx-yz-3lO">
<menuItem title="Show Running Mode In Status Bar" id="CCV-hX-fVA">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="showRunningMode:" target="Voe-Tx-rLC" id="PxO-ut-PEx"/>
</connections>
</menuItem>
<menuItem title="Advanced Proxy Preferences..." id="sbx-yz-3lO">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="editProxyPreferences:" target="Voe-Tx-rLC" id="Jji-Ea-Sy8"/>
@@ -112,12 +120,18 @@
</items>
</menu>
</menuItem>
<menuItem title="Advance Preference ..." id="bZ3-fy-34d">
<menuItem title="Advanced Preferences ..." id="bZ3-fy-34d">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="editAdvPreferences:" target="Voe-Tx-rLC" id="mEF-XS-HJE"/>
</connections>
</menuItem>
<menuItem title="HTTP Proxy Preferences ..." id="uEp-Gz-cu0">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="editHTTPPreferences:" target="Voe-Tx-rLC" id="tkC-e3-PH9"/>
</connections>
</menuItem>
<menuItem title="Launch At Login" id="eUq-p7-ICK">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
@@ -150,6 +164,20 @@
</connections>
</menuItem>
</items>
<point key="canvasLocation" x="22" y="89"/>
</menu>
<menu id="2oY-e9-q1Z">
<items>
<menuItem title="Item 1" id="oR3-cT-RTC">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem title="Item 2" id="lay-XB-0oV">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem title="Item 3" id="m00-ru-6Po">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
</items>
</menu>
</objects>
</document>
@@ -1,7 +1,8 @@
<?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">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11201" systemVersion="16A323" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10117"/>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11201"/>
<capability name="box content view" minToolsVersion="7.0"/>
</dependencies>
<objects>
@@ -24,9 +25,8 @@
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<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"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<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="1680" height="1027"/>
<view key="contentView" id="se5-gp-TjO">
<rect key="frame" x="0.0" y="0.0" width="590" height="330"/>
<autoresizingMask key="autoresizingMask"/>
@@ -38,7 +38,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" columnSelection="YES" multipleSelection="NO" emptySelection="NO" autosaveColumns="NO" id="r91-ho-Lum">
<rect key="frame" x="0.0" y="0.0" width="161" height="19"/>
<rect key="frame" x="0.0" y="0.0" width="221" height="228"/>
<autoresizingMask key="autoresizingMask"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
@@ -73,7 +73,6 @@
</connections>
</tableView>
</subviews>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</clipView>
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="jTp-ja-h3t">
<rect key="frame" x="1" y="206" width="163" height="15"/>
@@ -239,10 +238,8 @@
<constraint firstItem="q3C-S0-iNn" firstAttribute="trailing" secondItem="6mK-sY-xoH" secondAttribute="trailing" id="yiB-Nj-00X"/>
</constraints>
</view>
<color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/>
<color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</box>
<box title="Box" boxType="custom" borderType="none" titlePosition="noTitle" translatesAutoresizingMaskIntoConstraints="NO" id="Gqv-5O-Wwf">
<box boxType="custom" borderType="none" title="Box" titlePosition="noTitle" translatesAutoresizingMaskIntoConstraints="NO" id="Gqv-5O-Wwf">
<rect key="frame" x="20" y="61" width="223" height="19"/>
<view key="contentView" id="MbP-FS-YEs">
<rect key="frame" x="0.0" y="0.0" width="223" height="19"/>
@@ -282,7 +279,6 @@
<constraint firstItem="4ig-lF-m2R" firstAttribute="top" secondItem="MbP-FS-YEs" secondAttribute="top" id="xee-9x-wEB"/>
</constraints>
</view>
<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"/>
</box>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="yyD-qq-aSk">
@@ -13,7 +13,7 @@
</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">
<window title="Advanced 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"/>
@@ -1,7 +1,8 @@
<?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">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11201" systemVersion="16A323" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10117"/>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11201"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="UserRulesController" customModule="ShadowsocksX_NG" customModuleProvider="target">
@@ -16,13 +17,14 @@
<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="1440" height="877"/>
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
<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"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<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"/>
@@ -37,6 +39,7 @@ DQ
</button>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2bi-hW-nd9">
<rect key="frame" x="304" y="13" width="81" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<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"/>
@@ -50,19 +53,18 @@ Gw
</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"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<clipView key="contentView" ambiguous="YES" id="fO6-Dc-ZUL">
<rect key="frame" x="1" y="1" width="438" height="187"/>
<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="438" height="187"/>
<textView ambiguous="YES" importsGraphics="NO" richText="NO" usesFontPanel="YES" findStyle="panel" continuousSpellChecking="YES" allowsUndo="YES" usesRuler="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="438" height="187"/>
<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="438" height="187"/>
<size key="maxSize" width="463" height="10000000"/>
</textView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
@@ -72,7 +74,7 @@ Gw
<autoresizingMask key="autoresizingMask"/>
</scroller>
<scroller key="verticalScroller" verticalHuggingPriority="750" horizontal="NO" id="Us9-yx-gj4">
<rect key="frame" x="423" y="1" width="16" height="187"/>
<rect key="frame" x="424" y="1" width="15" height="187"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
</scrollView>
@@ -0,0 +1,27 @@
//
// HTTPPreferencesWindowController.swift
// ShadowsocksX-NG
//
// Created by 王晨 on 2016/10/7.
// Copyright © 2016年 qiuyuzhou. All rights reserved.
//
import Cocoa
class HTTPPreferencesWindowController: NSWindowController, NSWindowDelegate {
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.
self.window?.delegate = self
}
//------------------------------------------------------------
// NSWindowDelegate
func windowWillClose(_ notification: Notification) {
NotificationCenter.default
.post(name: Notification.Name(rawValue: NOTIFY_HTTP_CONF_CHANGED), object: nil)
}
}
+1 -1
View File
@@ -17,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.3</string>
<string>1.3.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>
+153 -2
View File
@@ -9,9 +9,11 @@
import Foundation
let SS_LOCAL_VERSION = "2.4.6"
let PRIVOXY_VERSION = "3.0.26.static"
let APP_SUPPORT_DIR = "/Library/Application Support/ShadowsocksX-NG/"
let LAUNCH_AGENT_DIR = "/Library/LaunchAgents/"
let LAUNCH_AGENT_CONF_NAME = "com.qiuyuzhou.shadowsocksX-NG.local.plist"
let LAUNCH_AGENT_CONF_SSLOCAL_NAME = "com.qiuyuzhou.shadowsocksX-NG.local.plist"
let LAUNCH_AGENT_CONF_PRIVOXY_NAME = "com.qiuyuzhou.shadowsocksX-NG.http.plist"
func getFileSHA1Sum(_ filepath: String) -> String {
@@ -23,11 +25,14 @@ func getFileSHA1Sum(_ filepath: String) -> String {
// Ref: https://developer.apple.com/library/mac/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html
// Genarate the mac launch agent service plist
// MARK: sslocal
func generateSSLocalLauchAgentPlist() -> Bool {
let sslocalPath = NSHomeDirectory() + APP_SUPPORT_DIR + "ss-local"
let logFilePath = NSHomeDirectory() + "/Library/Logs/ss-local.log"
let launchAgentDirPath = NSHomeDirectory() + LAUNCH_AGENT_DIR
let plistFilepath = launchAgentDirPath + LAUNCH_AGENT_CONF_NAME
let plistFilepath = launchAgentDirPath + LAUNCH_AGENT_CONF_SSLOCAL_NAME
// Ensure launch agent directory is existed.
let fileMgr = FileManager.default
@@ -168,4 +173,150 @@ func SyncSSLocal() {
StopSSLocal()
}
SyncPac()
SyncPrivoxy()
}
// MARK: privoxy
func generatePrivoxyLauchAgentPlist() -> Bool {
let privoxyPath = NSHomeDirectory() + APP_SUPPORT_DIR + "privoxy"
let logFilePath = NSHomeDirectory() + "/Library/Logs/privoxy.log"
let launchAgentDirPath = NSHomeDirectory() + LAUNCH_AGENT_DIR
let plistFilepath = launchAgentDirPath + LAUNCH_AGENT_CONF_PRIVOXY_NAME
// Ensure launch agent directory is existed.
let fileMgr = FileManager.default
if !fileMgr.fileExists(atPath: launchAgentDirPath) {
try! fileMgr.createDirectory(atPath: launchAgentDirPath, withIntermediateDirectories: true, attributes: nil)
}
let oldSha1Sum = getFileSHA1Sum(plistFilepath)
let arguments = [privoxyPath, "--no-daemon", "privoxy.config"]
// For a complete listing of the keys, see the launchd.plist manual page.
let dict: NSMutableDictionary = [
"Label": "com.qiuyuzhou.shadowsocksX-NG.http",
"WorkingDirectory": NSHomeDirectory() + APP_SUPPORT_DIR,
"KeepAlive": true,
"StandardOutPath": logFilePath,
"StandardErrorPath": logFilePath,
"ProgramArguments": arguments
]
dict.write(toFile: plistFilepath, atomically: true)
let Sha1Sum = getFileSHA1Sum(plistFilepath)
if oldSha1Sum != Sha1Sum {
return true
} else {
return false
}
}
func ReloadConfPrivoxy() {
let bundle = Bundle.main
let installerPath = bundle.path(forResource: "reload_conf_privoxy.sh", ofType: nil)
let task = Process.launchedProcess(launchPath: installerPath!, arguments: [""])
task.waitUntilExit()
if task.terminationStatus == 0 {
NSLog("reload privoxy succeeded.")
} else {
NSLog("reload privoxy failed.")
}
}
func StartPrivoxy() {
let bundle = Bundle.main
let installerPath = bundle.path(forResource: "start_privoxy.sh", ofType: nil)
let task = Process.launchedProcess(launchPath: installerPath!, arguments: [""])
task.waitUntilExit()
if task.terminationStatus == 0 {
NSLog("Start privoxy succeeded.")
} else {
NSLog("Start privoxy failed.")
}
}
func StopPrivoxy() {
let bundle = Bundle.main
let installerPath = bundle.path(forResource: "stop_privoxy.sh", ofType: nil)
let task = Process.launchedProcess(launchPath: installerPath!, arguments: [""])
task.waitUntilExit()
if task.terminationStatus == 0 {
NSLog("Stop privoxy succeeded.")
} else {
NSLog("Stop privoxy failed.")
}
}
func InstallPrivoxy() {
let fileMgr = FileManager.default
let homeDir = NSHomeDirectory()
let appSupportDir = homeDir+APP_SUPPORT_DIR
if !fileMgr.fileExists(atPath: appSupportDir + "privoxy-\(PRIVOXY_VERSION)/privoxy") {
let bundle = Bundle.main
let installerPath = bundle.path(forResource: "install_privoxy.sh", ofType: nil)
let task = Process.launchedProcess(launchPath: installerPath!, arguments: [""])
task.waitUntilExit()
if task.terminationStatus == 0 {
NSLog("Install privoxy succeeded.")
} else {
NSLog("Install privoxy failed.")
}
}
}
func writePrivoxyConfFile() -> Bool {
do {
let defaults = UserDefaults.standard
let bundle = Bundle.main
let examplePath = bundle.path(forResource: "privoxy.config.example", ofType: nil)
var example = try String(contentsOfFile: examplePath!, encoding: .utf8)
example = example.replacingOccurrences(of: "{http}", with: defaults.string(forKey: "LocalHTTP.ListenAddress")! + ":" + String(defaults.integer(forKey: "LocalHTTP.ListenPort")))
example = example.replacingOccurrences(of: "{socks5}", with: defaults.string(forKey: "LocalSocks5.ListenAddress")! + ":" + String(defaults.integer(forKey: "LocalSocks5.ListenPort")))
let data = example.data(using: .utf8)
let filepath = NSHomeDirectory() + APP_SUPPORT_DIR + "privoxy.config"
let oldSum = getFileSHA1Sum(filepath)
try data?.write(to: URL(fileURLWithPath: filepath), options: .atomic)
let newSum = getFileSHA1Sum(filepath)
if oldSum == newSum {
return false
}
return true
} catch {
NSLog("Write privoxy file failed.")
}
return false
}
func removePrivoxyConfFile() {
do {
let filepath = NSHomeDirectory() + APP_SUPPORT_DIR + "privoxy.config"
try FileManager.default.removeItem(atPath: filepath)
} catch {
}
}
func SyncPrivoxy() {
var changed: Bool = false
changed = changed || generatePrivoxyLauchAgentPlist()
let mgr = ServerProfileManager.instance
if mgr.activeProfileId != nil {
changed = changed || writePrivoxyConfFile()
let on = UserDefaults.standard.bool(forKey: "LocalHTTPOn")
if on {
// StartPrivoxy()
ReloadConfPrivoxy()
}
else {
removePrivoxyConfFile()
StopPrivoxy()
}
}
}
+3 -1
View File
@@ -10,4 +10,6 @@ import Foundation
let NOTIFY_SERVER_PROFILES_CHANGED = "NOTIFY_SERVER_PROFILES_CHANGED"
let NOTIFY_ADV_PROXY_CONF_CHANGED = "NOTIFY_ADV_PROXY_CONF_CHANGED"
let NOTIFY_ADV_CONF_CHANGED = "NOTIFY_ADV_CONF_CHANGED"
let NOTIFY_ADV_CONF_CHANGED = "NOTIFY_ADV_CONF_CHANGED"
let NOTIFY_HTTP_CONF_CHANGED = "NOTIFY_HTTP_CONF_CHANGED"
let NOTIFY_INVALIDE_QR = "NOTIFY_INVALIDE_QR"
+3 -5
View File
@@ -14,14 +14,12 @@
+ (void)install;
+ (void)enablePACProxy:(NSString*) PACFilePath;
+ (void)enablePACProxy;
+ (void)enableGlobalProxy;
+ (void)disableProxy:(NSString*) PACFilePath;
+ (void)disableProxy;
+ (NSString*)startPACServer:(NSString*) PACFilePath;
+ (void)stopPACServer;
+ (void)startMonitorPAC;
@end
+91 -26
View File
@@ -14,6 +14,7 @@
@implementation ProxyConfHelper
GCDWebServer *webServer =nil;
FSEventStreamRef fsEventStream;
+ (BOOL)isVersionOk {
NSTask *task;
@@ -114,14 +115,18 @@ GCDWebServer *webServer =nil;
}
}
+ (void)enablePACProxy:(NSString*) PACFilePath {
+ (NSString*)getPACFilePath {
return [NSString stringWithFormat:@"%@/%@", NSHomeDirectory(), @".ShadowsocksX-NG/gfwlist.js"];
}
+ (void)enablePACProxy {
//start server here and then using the string next line
//next two lines can open gcdwebserver and work around pac file
NSString *PACURLString = [self startPACServer: PACFilePath];//hi 可以切换成定制pac文件路径来达成使用定制文件路径
NSURL* url = [NSURL URLWithString: PACURLString];
// NSString* urlString = [NSString stringWithFormat:@"%@/.ShadowsocksX-NG/gfwlist.js", NSHomeDirectory()];
// NSURL* url = [NSURL fileURLWithPath:urlString];
NSString* PACFilePath = [self getPACFilePath];
[self startPACServer: PACFilePath];
NSURL* url = [NSURL URLWithString: [self getHttpPACUrl]];
NSMutableArray* args = [@[@"--mode", @"auto", @"--pac-url", [url absoluteString]]mutableCopy];
[self addArguments4ManualSpecifyNetworkServices:args];
@@ -134,17 +139,23 @@ GCDWebServer *webServer =nil;
NSMutableArray* args = [@[@"--mode", @"global", @"--port"
, [NSString stringWithFormat:@"%lu", (unsigned long)port]]mutableCopy];
// Because issue #106 https://github.com/shadowsocks/ShadowsocksX-NG/issues/106
// Comment below out.
// if ([[NSUserDefaults standardUserDefaults] boolForKey:@"LocalHTTPOn"] && [[NSUserDefaults standardUserDefaults] boolForKey:@"LocalHTTP.FollowGlobel"]) {
// NSUInteger privoxyPort = [[NSUserDefaults standardUserDefaults]integerForKey:@"LocalHTTP.ListenPort"];
//
// [args addObject:@"--privoxy-port"];
// [args addObject:[NSString stringWithFormat:@"%lu", (unsigned long)privoxyPort]];
// }
[self addArguments4ManualSpecifyNetworkServices:args];
[self callHelper:args];
[self stopPACServer];
}
+ (void)disableProxy:(NSString*) PACFilePath {
// 带上所有参数是为了判断是否原有代理设置是否由ssx-ng设置的。如果是用户手工设置的其他配置,则不进行清空。
// NSString* urlString = [NSString stringWithFormat:@"%@/.ShadowsocksX-NG/gfwlist.js", NSHomeDirectory()];
// NSURL* url = [NSURL fileURLWithPath:urlString];
NSString *PACURLString = [self startPACServer: PACFilePath];//hi 可以切换成定制pac文件路径来达成使用定制文件路径
NSURL* url = [NSURL URLWithString: PACURLString];
+ (void)disableProxy {
// 带上所有参数是为了判断是否原有代理设置是否由ssx-ng设置的。如果是用户手工设置的其他配置,则不进行清空。
NSURL* url = [NSURL URLWithString: [self getHttpPACUrl]];
NSUInteger port = [[NSUserDefaults standardUserDefaults]integerForKey:@"LocalSocks5.ListenPort"];
NSMutableArray* args = [@[@"--mode", @"off"
@@ -156,28 +167,41 @@ GCDWebServer *webServer =nil;
[self stopPACServer];
}
+ (NSString*)startPACServer:(NSString*) PACFilePath {
//接受参数为以后使用定制PAC文件
NSData * originalPACData;
+ (NSString*)getHttpPACUrl {
NSString * routerPath = @"/proxy.pac";
if ([PACFilePath isEqual: @"hi"]) {//用默认路径来代替
PACFilePath = [NSString stringWithFormat:@"%@/%@", NSHomeDirectory(), @".ShadowsocksX-NG/gfwlist.js"];
originalPACData = [NSData dataWithContentsOfFile: [NSString stringWithFormat:@"%@/%@", NSHomeDirectory(), @".ShadowsocksX-NG/gfwlist.js"]];
}else{//用定制路径来代替
originalPACData = [NSData dataWithContentsOfFile: [NSString stringWithFormat:@"%@/%@/%@", NSHomeDirectory(), @".ShadowsocksX-NG", PACFilePath]];
routerPath = [NSString stringWithFormat:@"/%@",PACFilePath];
}
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString * address = @"127.0.0.1";
int port = (short)[defaults integerForKey:@"PacServer.ListenPort"];
return [NSString stringWithFormat:@"%@%@:%d%@",@"http://",address,port,routerPath];
}
+ (void)startPACServer:(NSString*) PACFilePath {
[self stopPACServer];
NSString * routerPath = @"/proxy.pac";
NSData* originalPACData = [NSData dataWithContentsOfFile:PACFilePath];
webServer = [[GCDWebServer alloc] init];
[webServer addHandlerForMethod:@"GET" path:routerPath requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest *request) {
return [GCDWebServerDataResponse responseWithData: originalPACData contentType:@"application/x-ns-proxy-autoconfig"];
[webServer addHandlerForMethod:@"GET"
path:routerPath
requestClass:[GCDWebServerRequest class]
processBlock:^GCDWebServerResponse *(GCDWebServerRequest *request)
{
GCDWebServerDataResponse* resp = [GCDWebServerDataResponse responseWithData:originalPACData
contentType:@"application/x-ns-proxy-autoconfig"];
return resp;
}
];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString * address = [defaults stringForKey:@"PacServer.ListenAddress"];
int port = (short)[defaults integerForKey:@"PacServer.ListenPort"];
[webServer startWithOptions:@{@"BindToLocalhost":@YES, @"Port":@(port)} error:nil];
return [NSString stringWithFormat:@"%@%@:%d%@",@"http://",address,port,routerPath];
}
+ (void)stopPACServer {
@@ -187,4 +211,45 @@ GCDWebServer *webServer =nil;
}
}
void onPACChange(
ConstFSEventStreamRef streamRef,
void *clientCallBackInfo,
size_t numEvents,
void *eventPaths,
const FSEventStreamEventFlags eventFlags[],
const FSEventStreamEventId eventIds[])
{
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
if ([defaults boolForKey:@"ShadowsocksOn"]) {
if ([[defaults stringForKey:@"ShadowsocksRunningMode"] isEqualToString:@"auto"]) {
[ProxyConfHelper disableProxy];
[ProxyConfHelper enablePACProxy];
}
}
}
+ (void)startMonitorPAC {
NSString* PACFilePath = [self getPACFilePath];
if (fsEventStream) {
return;
}
CFStringRef mypath = (__bridge CFStringRef)(PACFilePath);
CFArrayRef pathsToWatch = CFArrayCreate(NULL, (const void **)&mypath, 1, NULL);
void *callbackInfo = NULL; // could put stream-specific data here.
CFAbsoluteTime latency = 3.0; /* Latency in seconds */
/* Create the stream, passing in a callback */
fsEventStream = FSEventStreamCreate(NULL,
&onPACChange,
callbackInfo,
pathsToWatch,
kFSEventStreamEventIdSinceNow, /* Or a previous event ID */
latency,
kFSEventStreamCreateFlagNone /* Flags explained in reference */
);
FSEventStreamScheduleWithRunLoop(fsEventStream, [[NSRunLoop mainRunLoop] getCFRunLoop], (__bridge CFStringRef)NSDefaultRunLoopMode);
FSEventStreamStart(fsEventStream);
}
@end
@@ -37,7 +37,7 @@ class ProxyPreferencesController: NSWindowController, NSTableViewDataSource, NST
}
@IBAction func ok(_ sender: NSObject){
ProxyConfHelper.disableProxy("hi")
ProxyConfHelper.disableProxy()
let defaults = UserDefaults.standard
defaults.setValue(selectedNetworkServices.allObjects, forKeyPath: "Proxy4NetworkServices")
+2 -2
View File
@@ -9,9 +9,9 @@
#import <Cocoa/Cocoa.h>
#import <WebKit/WebKit.h>
@interface SWBQRCodeWindowController : NSWindowController <WebFrameLoadDelegate>
@interface SWBQRCodeWindowController : NSWindowController
@property (nonatomic, strong) IBOutlet WebView *webView;
@property (nonatomic, copy) NSString *qrCode;
@property (nonatomic, weak) NSImageView *imageView;
@end
+47 -8
View File
@@ -7,6 +7,7 @@
//
#import "SWBQRCodeWindowController.h"
@import CoreImage;
@interface SWBQRCodeWindowController ()
@@ -18,18 +19,56 @@
[super windowDidLoad];
// Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
[self.webView.mainFrame loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"qrcode" withExtension:@"htm"]]];
self.webView.frameLoadDelegate = self;
[self setQRCode:self.qrCode];
}
-(void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame {
if (self.qrCode) {
[self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"genCode('%@')", _qrCode]];
}
- (void)setQRCode:(NSString*) qrCode {
CGImageRef cgImgRef = [self createQRImageForString:qrCode size:CGSizeMake(250, 250)];
NSImage *image = [[NSImage alloc]initWithCGImage:cgImgRef size:CGSizeMake(250, 250)];
self.imageView.image = image;
}
-(void)dealloc {
self.webView.frameLoadDelegate = nil;
- (CGImageRef)createQRImageForString:(NSString *)string size:(CGSize)size {
// Setup the QR filter with our string
CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
[filter setDefaults];
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
[filter setValue:data forKey:@"inputMessage"];
CIImage *image = [filter valueForKey:@"outputImage"];
// Calculate the size of the generated image and the scale for the desired image size
CGRect extent = CGRectIntegral(image.extent);
CGFloat scale = MIN(size.width / CGRectGetWidth(extent), size.height / CGRectGetHeight(extent));
// Since CoreImage nicely interpolates, we need to create a bitmap image that we'll draw into
// a bitmap context at the desired size;
size_t width = CGRectGetWidth(extent) * scale;
size_t height = CGRectGetHeight(extent) * scale;
CGColorSpaceRef cs = CGColorSpaceCreateDeviceGray();
CGContextRef bitmapRef = CGBitmapContextCreate(nil, width, height, 8, 0, cs, (CGBitmapInfo)kCGImageAlphaNone);
#if TARGET_OS_IPHONE
CIContext *context = [CIContext contextWithOptions:nil];
#else
CIContext *context = [CIContext contextWithCGContext:bitmapRef options:nil];
#endif
CGImageRef bitmapImage = [context createCGImage:image fromRect:extent];
CGContextSetInterpolationQuality(bitmapRef, kCGInterpolationNone);
CGContextScaleCTM(bitmapRef, scale, scale);
CGContextDrawImage(bitmapRef, extent, bitmapImage);
// Create an image with the contents of our bitmap
CGImageRef scaledImage = CGBitmapContextCreateImage(bitmapRef);
// Cleanup
CGContextRelease(bitmapRef);
CGImageRelease(bitmapImage);
return scaledImage;
}
@end
+10 -17
View File
@@ -1,13 +1,13 @@
<?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">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11201" systemVersion="16A323" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10117"/>
<plugIn identifier="com.apple.WebKitIBPlugin" version="10117"/>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11201"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="SWBQRCodeWindowController">
<connections>
<outlet property="webView" destination="ojI-LR-jEw" id="bpE-vv-uIe"/>
<outlet property="imageView" destination="yRy-QH-TEe" id="aa5-Ri-k04"/>
<outlet property="window" destination="QvC-M9-y7g" id="HLy-eJ-5RD"/>
</connections>
</customObject>
@@ -16,24 +16,17 @@
<window title="QR Code" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" oneShot="NO" animationBehavior="default" id="QvC-M9-y7g">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
<rect key="contentRect" x="566" y="456" width="250" height="250"/>
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
<view key="contentView" id="EiT-Mj-1SZ">
<rect key="frame" x="0.0" y="0.0" width="250" height="250"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<webView translatesAutoresizingMaskIntoConstraints="NO" id="ojI-LR-jEw">
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="yRy-QH-TEe">
<rect key="frame" x="0.0" y="0.0" width="250" height="250"/>
<webPreferences key="preferences" defaultFontSize="12" defaultFixedFontSize="12">
<nil key="identifier"/>
</webPreferences>
</webView>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" id="iAJ-tw-LNU"/>
</imageView>
</subviews>
<constraints>
<constraint firstAttribute="trailing" secondItem="ojI-LR-jEw" secondAttribute="trailing" id="ImJ-r1-FF9"/>
<constraint firstAttribute="bottom" secondItem="ojI-LR-jEw" secondAttribute="bottom" id="LQv-2G-kyf"/>
<constraint firstItem="ojI-LR-jEw" firstAttribute="leading" secondItem="EiT-Mj-1SZ" secondAttribute="leading" id="kok-J1-X08"/>
<constraint firstItem="ojI-LR-jEw" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" id="voV-aN-Ggt"/>
</constraints>
</view>
</window>
</objects>
+17
View File
@@ -0,0 +1,17 @@
#!/bin/sh
# install_privoxy.sh
# ShadowsocksX-NG
#
# Created by 王晨 on 16/10/7.
# Copyright © 2016年 zhfish. All rights reserved.
cd `dirname "${BASH_SOURCE[0]}"`
privoxyVersion=3.0.26.static
mkdir -p "$HOME/Library/Application Support/ShadowsocksX-NG/privoxy-$privoxyVersion"
cp -f privoxy "$HOME/Library/Application Support/ShadowsocksX-NG/privoxy-$privoxyVersion/"
rm -f "$HOME/Library/Application Support/ShadowsocksX-NG/privoxy"
ln -s "$HOME/Library/Application Support/ShadowsocksX-NG/privoxy-$privoxyVersion/privoxy" "$HOME/Library/Application Support/ShadowsocksX-NG/privoxy"
echo done
-2
View File
File diff suppressed because one or more lines are too long
BIN
View File
Binary file not shown.
+18
View File
@@ -0,0 +1,18 @@
listen-address {http}
toggle 1
enable-remote-toggle 1
enable-remote-http-toggle 1
enable-edit-actions 0
enforce-blocks 0
buffer-limit 4096
forwarded-connect-retries 0
accept-intercepted-requests 0
allow-cgi-request-crunching 0
split-large-forms 0
keep-alive-timeout 5
socket-timeout 60
forward-socks5 / {socks5} .
forward 192.168.*.*/ .
forward 10.*.*.*/ .
forward 127.*.*.*/ .
+1 -1
View File
@@ -9,6 +9,6 @@
#ifndef proxy_conf_helper_version_h
#define proxy_conf_helper_version_h
#define kProxyConfHelperVersion @"1.3.1"
#define kProxyConfHelperVersion @"1.3.2"
#endif /* proxy_conf_helper_version_h */
-28
View File
@@ -1,28 +0,0 @@
<!doctype html>
<script src="jquery.min.js">
</script>
<script src="qrcode.min.js">
</script>
<style>
body {
padding: 10px;
margin: 0;
}
#qrcode {
width:230px;
height:230px;
}
</style>
<div id="qrcode"></div>
<script type="text/javascript">
function genCode(code) {
new QRCode("qrcode", {
text: code,
width: 230,
height: 230,
colorDark : "#000000",
colorLight : "#ffffff",
correctLevel : QRCode.CorrectLevel.H
});
}
</script>
-1
View File
File diff suppressed because one or more lines are too long
+12
View File
@@ -0,0 +1,12 @@
#!/bin/sh
# reload_privoxy.sh
# ShadowsocksX-NG
#
# Created by 王晨 on 16/10/7.
# Copyright © 2016年 zhfish. All rights reserved.
#launchctl kill SIGHUP "$HOME/Library/LaunchAgents/com.qiuyuzhou.shadowsocksX-NG.http.plist"
launchctl unload "$HOME/Library/LaunchAgents/com.qiuyuzhou.shadowsocksX-NG.http.plist"
launchctl load "$HOME/Library/LaunchAgents/com.qiuyuzhou.shadowsocksX-NG.http.plist"
+9
View File
@@ -0,0 +1,9 @@
#!/bin/sh
# start_privoxy.sh
# ShadowsocksX-NG
#
# Created by 王晨 on 16/10/7.
# Copyright © 2016年 zhfish. All rights reserved.
launchctl load "$HOME/Library/LaunchAgents/com.qiuyuzhou.shadowsocksX-NG.http.plist"
+11
View File
@@ -0,0 +1,11 @@
#!/bin/sh
# stop_privoxy.sh
# ShadowsocksX-NG
#
# Created by 王晨 on 16/10/7.
# Copyright © 2016年 zhfish. All rights reserved.
launchctl unload "$HOME/Library/LaunchAgents/com.qiuyuzhou.shadowsocksX-NG.http.plist"
@@ -18,10 +18,22 @@
"cwr-n0-zwn.title" = "本地 Socks5 监听地址:";
/* Class = "NSTextFieldCell"; title = "GFW List URL:"; ObjectID = "dg0-gS-z5V"; */
"dg0-gS-z5V.title" = "GFW List URL:";
"dg0-gS-z5V.title" = "GFW LIST URL:";
/* Class = "NSTextFieldCell"; title = "Timeout:"; ObjectID = "i4l-2S-gOQ"; */
"i4l-2S-gOQ.title" = "超时:";
/* Class = "NSTextFieldCell"; title = "本地 Socks5 监听端口:"; ObjectID = "qRs-ow-vVB"; */
"qRs-ow-vVB.title" = "本地 Socks5 监听端口:";
/* Class = "NSTextFieldCell"; title = "Local PAC Listen Address:"; ObjectID = "dvL-Ic-Wae"; */
"dvL-Ic-Wae.title" = "本地 PAC 监听地址:";
/* Class = "NSTextFieldCell"; title = "Local PAC Listen Port:"; ObjectID = "PSg-XK-qhl"; */
"PSg-XK-qhl.title" = "本地 PAC 监听端口:";
/* Class = "NSTextFieldCell"; title = "White List URL:"; ObjectID = "aif-uV-Lxk"; */
"aif-uV-Lxk.title" = "白名单列表 URL:";
/* Class = "NSTextFieldCell"; title = "White IP List URL:"; ObjectID = "qhu-d1-qgq"; */
"qhu-d1-qgq.title" = "白名单IP列表 URL:";
@@ -0,0 +1,15 @@
/* Class = "NSTextFieldCell"; title = "HTTP Proxy Listen Port:"; ObjectID = "2Sd-yn-gdY"; */
"2Sd-yn-gdY.title" = "HTTP 代理 监听端口:";
/* Class = "NSButtonCell"; title = "HTTP Proxy Enable"; ObjectID = "dqU-MG-Sum"; */
"dqU-MG-Sum.title" = "HTTP 代理 开启";
/* Class = "NSTextFieldCell"; title = "HTTP Proxy Listen Address:"; ObjectID = "qd0-kc-ttB"; */
"qd0-kc-ttB.title" = "HTTP 代理 监听地址:";
/* Class = "NSWindow"; title = "HTTP Proxy Preferences"; ObjectID = "vS3-DL-Nq3"; */
"vS3-DL-Nq3.title" = "HTTP 代理 设置";
/* Class = "NSButtonCell"; title = "Follow Globel Mode"; ObjectID = "ofk-Pc-c8f"; */
"ofk-Pc-c8f.title" = "跟随全局模式";
+8
View File
@@ -51,3 +51,11 @@
"Proxy - Manual" = "代理 - 手动";
"Servers" = "服务器";
"Auto" = "自动";
"Global" = "全局";
"Manual" = "手动";
"Show Running Mode On Status Bar" = "在状态栏显示运行模式";
@@ -67,3 +67,16 @@
/* Class = "NSMenuItem"; title = "退出"; ObjectID = "vJS-JW-byz"; */
"vJS-JW-byz.title" = "退出";
/* Class = "NSMenuItem"; title = "Ping server"; ObjectID = "zfR-Jt-GmS"; */
"zfR-Jt-GmS.title" = "服务器测速";
/* Class = "NSMenuItem"; title = "Show network speed"; ObjectID = "a3h-uQ-DuO"; */
"a3h-uQ-DuO.title" = "显示网速";
/* Class = "NSMenuItem"; title = "Connect At Launch"; ObjectID = "aB3-cf-5j0"; */
"aB3-cf-5j0.title" = "打开时自动连接";
/* Class = "NSMenuItem"; title = "HTTP Proxy Preference ..."; ObjectID = "uEp-Gz-cu0"; */
"uEp-Gz-cu0.title" = "HTTP代理设置...";
@@ -1,5 +1,5 @@
/* Class = "NSWindow"; title = "Advance Proxy Preferences"; ObjectID = "F0z-JX-Cv5"; */
/* Class = "NSWindow"; title = "Advanced Proxy Preferences"; ObjectID = "F0z-JX-Cv5"; */
"F0z-JX-Cv5.title" = "高级代理设置";
/* Class = "NSButtonCell"; title = "Auto Configure"; ObjectID = "FLv-D9-CRw"; */
+30 -3
View File
@@ -22,9 +22,10 @@ int main(int argc, const char * argv[])
NSString* mode;
NSString* pacURL;
NSString* portString;
NSString* privoxyPortString;
BRLOptionParser *options = [BRLOptionParser new];
[options setBanner:@"Usage: %s [-v] [-m auto|global|off] [-u <url>] [-p <port>]", argv[0]];
[options setBanner:@"Usage: %s [-v] [-m auto|global|off] [-u <url>] [-p <port>] [-r <port>]", argv[0]];
// Version
[options addOption:"version" flag:'v' description:@"Print the version number." block:^{
@@ -40,11 +41,13 @@ int main(int argc, const char * argv[])
}];
// Mode
[options addOption:"mode" flag:'m' description:@"Proxy mode, may be: auto,blobal,off" argument:&mode];
[options addOption:"mode" flag:'m' description:@"Proxy mode, may be: auto,global,off" argument:&mode];
[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:"privoxy-port" flag:'r' description:@"Privoxy Port for global mode." argument:&privoxyPortString];
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];
@@ -57,7 +60,6 @@ int main(int argc, const char * argv[])
exit(EXIT_FAILURE);
}
NSInteger port = 0;
if (mode) {
if ([@"auto" isEqualToString:mode]) {
if (!pacURL) {
@@ -75,6 +77,7 @@ int main(int argc, const char * argv[])
return 0;
}
NSInteger port = 0;
if (portString) {
port = [portString integerValue];
if (0 == port) {
@@ -82,6 +85,14 @@ int main(int argc, const char * argv[])
}
}
NSInteger privoxyPort = 0;
if (privoxyPortString) {
privoxyPort = [privoxyPortString integerValue];
if (0 == privoxyPort) {
return 1;
}
}
static AuthorizationRef authRef;
static AuthorizationFlags authFlags;
authFlags = kAuthorizationFlagDefaults
@@ -149,6 +160,22 @@ int main(int argc, const char * argv[])
kCFNetworkProxiesSOCKSEnable];
[proxies setObject:@[@"127.0.0.1", @"localhost"] forKey:(NSString *)kCFNetworkProxiesExceptionsList];
if (privoxyPort != 0) {
[proxies setObject:@"127.0.0.1" forKey:(NSString *)
kCFNetworkProxiesHTTPProxy];
[proxies setObject:[NSNumber numberWithInteger:privoxyPort] forKey:(NSString*)
kCFNetworkProxiesHTTPPort];
[proxies setObject:[NSNumber numberWithInt:1] forKey:(NSString*)
kCFNetworkProxiesHTTPEnable];
[proxies setObject:@"127.0.0.1" forKey:(NSString *)
kCFNetworkProxiesHTTPSProxy];
[proxies setObject:[NSNumber numberWithInteger:privoxyPort] forKey:(NSString*)
kCFNetworkProxiesHTTPSPort];
[proxies setObject:[NSNumber numberWithInt:1] forKey:(NSString*)
kCFNetworkProxiesHTTPSEnable];
}
SCPreferencesPathSetValue(prefRef, (__bridge CFStringRef)prefPath
, (__bridge CFDictionaryRef)proxies);
} else if ([mode isEqualToString:@"off"]) {