From 8fa7f76faa1472acdb7d2ebeaec7cbef4831327b Mon Sep 17 00:00:00 2001 From: Qiu Yuzhou Date: Sat, 15 Oct 2016 00:33:53 +0800 Subject: [PATCH 1/8] Add a download link in readme. --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 32dc8a2..755835e 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,10 @@ 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 From dd20ebda682b9c2ed301c5dc9464debc497e76f1 Mon Sep 17 00:00:00 2001 From: qinyuhang Date: Tue, 18 Oct 2016 15:36:56 +0800 Subject: [PATCH 2/8] fix crash problem --- ShadowsocksX-NG/AppDelegate.swift | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ShadowsocksX-NG/AppDelegate.swift b/ShadowsocksX-NG/AppDelegate.swift index 60796e8..f833b61 100755 --- a/ShadowsocksX-NG/AppDelegate.swift +++ b/ShadowsocksX-NG/AppDelegate.swift @@ -385,14 +385,14 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele 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)" } From 7ad9dc42a03858883f8f9e3cf7eebe7b1a4a0254 Mon Sep 17 00:00:00 2001 From: Charlie Qiu Date: Tue, 18 Oct 2016 22:18:54 +0800 Subject: [PATCH 3/8] Fix bug caused by pr #97 --- ShadowsocksX-NG/AppDelegate.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/ShadowsocksX-NG/AppDelegate.swift b/ShadowsocksX-NG/AppDelegate.swift index 0895449..9ed542e 100755 --- a/ShadowsocksX-NG/AppDelegate.swift +++ b/ShadowsocksX-NG/AppDelegate.swift @@ -395,6 +395,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele } else { profileName = p.serverHost } + serverMenuText = "\(serverMenuText) - \(profileName)" } } serversMenuItem.title = serverMenuText From d0ad272198c5802b4c112444624e8e29e06995d2 Mon Sep 17 00:00:00 2001 From: Charlie Qiu Date: Tue, 18 Oct 2016 23:35:17 +0800 Subject: [PATCH 4/8] Refactor pac proxy. --- ShadowsocksX-NG/AppDelegate.swift | 10 +- .../AdvPreferencesWindowController.xib | 164 ++++++++---------- ShadowsocksX-NG/ProxyConfHelper.h | 10 +- ShadowsocksX-NG/ProxyConfHelper.m | 64 ++++--- .../ProxyPreferencesController.swift | 2 +- 5 files changed, 120 insertions(+), 130 deletions(-) diff --git a/ShadowsocksX-NG/AppDelegate.swift b/ShadowsocksX-NG/AppDelegate.swift index 9ed542e..40f58ff 100755 --- a/ShadowsocksX-NG/AppDelegate.swift +++ b/ShadowsocksX-NG/AppDelegate.swift @@ -58,7 +58,6 @@ 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), @@ -171,10 +170,9 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele // Insert code here to tear down your application StopSSLocal() StopPrivoxy() - ProxyConfHelper.disableProxy("hi") + ProxyConfHelper.disableProxy() let defaults = UserDefaults.standard defaults.set(false, forKey: "ShadowsocksOn") - ProxyConfHelper.stopPACServer() } func applyConfig() { @@ -186,16 +184,16 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele 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() StopPrivoxy() - ProxyConfHelper.disableProxy("hi") + ProxyConfHelper.disableProxy() } } diff --git a/ShadowsocksX-NG/Base.lproj/AdvPreferencesWindowController.xib b/ShadowsocksX-NG/Base.lproj/AdvPreferencesWindowController.xib index 35784f1..9e90f71 100644 --- a/ShadowsocksX-NG/Base.lproj/AdvPreferencesWindowController.xib +++ b/ShadowsocksX-NG/Base.lproj/AdvPreferencesWindowController.xib @@ -14,30 +14,19 @@ - + - + - + - - - - - - - - - - - - + - + @@ -53,7 +42,7 @@ - + @@ -61,10 +50,10 @@ - + - + @@ -72,7 +61,7 @@ - + @@ -80,7 +69,7 @@ - + @@ -95,7 +84,7 @@ - + @@ -103,7 +92,7 @@ - + @@ -119,7 +108,7 @@ - + - + @@ -148,10 +137,7 @@ - - - - + @@ -168,18 +154,16 @@ - - - + + - - - + + @@ -194,22 +178,12 @@ - - - - - - - - - - - - - - - - + + + + + + @@ -217,51 +191,57 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + diff --git a/ShadowsocksX-NG/ProxyConfHelper.h b/ShadowsocksX-NG/ProxyConfHelper.h index c00ade2..0f0dfa0 100644 --- a/ShadowsocksX-NG/ProxyConfHelper.h +++ b/ShadowsocksX-NG/ProxyConfHelper.h @@ -14,14 +14,14 @@ + (void)install; -+ (void)enablePACProxy:(NSString*) PACFilePath; ++ (void)enablePACProxy; + (void)enableGlobalProxy; -+ (void)disableProxy:(NSString*) PACFilePath; ++ (void)disableProxy; -+ (NSString*)startPACServer:(NSString*) PACFilePath; - -+ (void)stopPACServer; +//+ (void)startPACServer:(NSString*) PACFilePath; +// +//+ (void)stopPACServer; @end diff --git a/ShadowsocksX-NG/ProxyConfHelper.m b/ShadowsocksX-NG/ProxyConfHelper.m index 6089ae0..dbe0128 100644 --- a/ShadowsocksX-NG/ProxyConfHelper.m +++ b/ShadowsocksX-NG/ProxyConfHelper.m @@ -114,14 +114,14 @@ GCDWebServer *webServer =nil; } } -+ (void)enablePACProxy:(NSString*) PACFilePath { ++ (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 = [NSString stringWithFormat:@"%@/%@", NSHomeDirectory(), @".ShadowsocksX-NG/gfwlist.js"]; + [self startPACServer: PACFilePath]; + + NSURL* url = [NSURL URLWithString: [self getHttpPACUrl]]; + NSMutableArray* args = [@[@"--mode", @"auto", @"--pac-url", [url absoluteString]]mutableCopy]; [self addArguments4ManualSpecifyNetworkServices:args]; @@ -146,12 +146,9 @@ GCDWebServer *webServer =nil; [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" @@ -163,28 +160,43 @@ 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 { + //接受参数为以后使用定制PAC文件 + + NSString * routerPath = @"/proxy.pac"; + [self stopPACServer]; 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) + { + NSLog(@"get proxy.pac"); + NSData* originalPACData = [NSData dataWithContentsOfFile:PACFilePath]; + GCDWebServerDataResponse* resp = [GCDWebServerDataResponse responseWithData:originalPACData + contentType:@"application/x-ns-proxy-autoconfig"]; + resp.cacheControlMaxAge = 0; + 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 { diff --git a/ShadowsocksX-NG/ProxyPreferencesController.swift b/ShadowsocksX-NG/ProxyPreferencesController.swift index 4c215d6..82bab46 100644 --- a/ShadowsocksX-NG/ProxyPreferencesController.swift +++ b/ShadowsocksX-NG/ProxyPreferencesController.swift @@ -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") From e5b342c1346035f28df352074d8571039e5c6ef9 Mon Sep 17 00:00:00 2001 From: Charlie Qiu Date: Wed, 19 Oct 2016 00:24:45 +0800 Subject: [PATCH 5/8] Monitor PAC file. Disable then enable the system pac configure after it has been modified. --- ShadowsocksX-NG/AppDelegate.swift | 1 + ShadowsocksX-NG/ProxyConfHelper.h | 4 +-- ShadowsocksX-NG/ProxyConfHelper.m | 56 +++++++++++++++++++++++++++---- 3 files changed, 52 insertions(+), 9 deletions(-) diff --git a/ShadowsocksX-NG/AppDelegate.swift b/ShadowsocksX-NG/AppDelegate.swift index 40f58ff..c1ca927 100755 --- a/ShadowsocksX-NG/AppDelegate.swift +++ b/ShadowsocksX-NG/AppDelegate.swift @@ -162,6 +162,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele updateLaunchAtLoginMenu() ProxyConfHelper.install() + ProxyConfHelper.startMonitorPAC() applyConfig() SyncSSLocal() } diff --git a/ShadowsocksX-NG/ProxyConfHelper.h b/ShadowsocksX-NG/ProxyConfHelper.h index 0f0dfa0..65e34a0 100644 --- a/ShadowsocksX-NG/ProxyConfHelper.h +++ b/ShadowsocksX-NG/ProxyConfHelper.h @@ -20,8 +20,6 @@ + (void)disableProxy; -//+ (void)startPACServer:(NSString*) PACFilePath; -// -//+ (void)stopPACServer; ++ (void)startMonitorPAC; @end diff --git a/ShadowsocksX-NG/ProxyConfHelper.m b/ShadowsocksX-NG/ProxyConfHelper.m index dbe0128..05187c6 100644 --- a/ShadowsocksX-NG/ProxyConfHelper.m +++ b/ShadowsocksX-NG/ProxyConfHelper.m @@ -14,6 +14,7 @@ @implementation ProxyConfHelper GCDWebServer *webServer =nil; +FSEventStreamRef fsEventStream; + (BOOL)isVersionOk { NSTask *task; @@ -114,10 +115,14 @@ GCDWebServer *webServer =nil; } } ++ (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* PACFilePath = [NSString stringWithFormat:@"%@/%@", NSHomeDirectory(), @".ShadowsocksX-NG/gfwlist.js"]; + NSString* PACFilePath = [self getPACFilePath]; [self startPACServer: PACFilePath]; NSURL* url = [NSURL URLWithString: [self getHttpPACUrl]]; @@ -172,22 +177,20 @@ GCDWebServer *webServer =nil; } + (void)startPACServer:(NSString*) PACFilePath { - //接受参数为以后使用定制PAC文件 + [self stopPACServer]; NSString * routerPath = @"/proxy.pac"; - [self stopPACServer]; + NSData* originalPACData = [NSData dataWithContentsOfFile:PACFilePath]; + webServer = [[GCDWebServer alloc] init]; [webServer addHandlerForMethod:@"GET" path:routerPath requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest *request) { - NSLog(@"get proxy.pac"); - NSData* originalPACData = [NSData dataWithContentsOfFile:PACFilePath]; GCDWebServerDataResponse* resp = [GCDWebServerDataResponse responseWithData:originalPACData contentType:@"application/x-ns-proxy-autoconfig"]; - resp.cacheControlMaxAge = 0; return resp; } ]; @@ -206,4 +209,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 From a85fc4e3b4c8707fb67d7d033472aaa871d16499 Mon Sep 17 00:00:00 2001 From: Charlie Qiu Date: Wed, 19 Oct 2016 00:26:16 +0800 Subject: [PATCH 6/8] Disable the rich text attribute of the user pac fule edit control. --- ShadowsocksX-NG/Base.lproj/UserRulesController.xib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ShadowsocksX-NG/Base.lproj/UserRulesController.xib b/ShadowsocksX-NG/Base.lproj/UserRulesController.xib index 0d53d39..621b98d 100644 --- a/ShadowsocksX-NG/Base.lproj/UserRulesController.xib +++ b/ShadowsocksX-NG/Base.lproj/UserRulesController.xib @@ -58,7 +58,7 @@ Gw - + From 53d41ad27b6f57f5e898a501643d955e9fe0fd4f Mon Sep 17 00:00:00 2001 From: Charlie Qiu Date: Wed, 19 Oct 2016 00:30:21 +0800 Subject: [PATCH 7/8] Update version number to 1.3.1 --- ShadowsocksX-NG/Info.plist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ShadowsocksX-NG/Info.plist b/ShadowsocksX-NG/Info.plist index 04f0ded..0c35489 100644 --- a/ShadowsocksX-NG/Info.plist +++ b/ShadowsocksX-NG/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.3 + 1.3.1 CFBundleSignature ???? CFBundleURLTypes From 3c77fc9fe98ddc9a9a05c2189b88e9d120f903f0 Mon Sep 17 00:00:00 2001 From: Charlie Qiu Date: Wed, 19 Oct 2016 00:30:53 +0800 Subject: [PATCH 8/8] Fix the project file. --- ShadowsocksX-NG.xcodeproj/project.pbxproj | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/ShadowsocksX-NG.xcodeproj/project.pbxproj b/ShadowsocksX-NG.xcodeproj/project.pbxproj index 2afa29a..d4c1550 100755 --- a/ShadowsocksX-NG.xcodeproj/project.pbxproj +++ b/ShadowsocksX-NG.xcodeproj/project.pbxproj @@ -96,18 +96,6 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 083BF8311D82731900831C68 /* SimplePing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimplePing.h; sourceTree = ""; }; - 083BF8321D82731900831C68 /* SimplePing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SimplePing.m; sourceTree = ""; }; - 083BF8341D82742200831C68 /* NetWorkMonitor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetWorkMonitor.swift; sourceTree = ""; }; - 083BF8351D82742200831C68 /* PingClient.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PingClient.swift; sourceTree = ""; }; - 083BF8381D82759600831C68 /* StatusItemView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatusItemView.swift; sourceTree = ""; }; - 083BF83A1D8275A800831C68 /* SystemThemeChangeHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SystemThemeChangeHelper.swift; sourceTree = ""; }; - 085641E91D7188C400116B27 /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/Localizable.strings; sourceTree = ""; }; - 08805F181D878CA5009B53E7 /* PingTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PingTest.swift; sourceTree = ""; }; - 0880CE3F1D6FE6D900BD39E2 /* example-gui-config.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "example-gui-config.json"; sourceTree = ""; }; - 088EC3961D5F5B8600E40791 /* whitelist.pac */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = whitelist.pac; sourceTree = ""; }; - 088EC3981D5F5BA300E40791 /* whiteiplist.pac */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = whiteiplist.pac; sourceTree = ""; }; - 08AF56C01D6AFA7C00DC4F46 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/PreferencesWindowController.strings"; sourceTree = ""; }; 19083CFCED87354F006967FF /* Pods_ShadowsocksX_NGUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ShadowsocksX_NGUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 1E7783AEDB4A3BDDC9FF16AC /* libPods-proxy_conf_helper.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-proxy_conf_helper.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 283ED1A8E9B711AC65670031 /* Pods_ShadowsocksX_NG.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ShadowsocksX_NG.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -505,7 +493,6 @@ 9B3FFF3A1D08CF110019A709 /* qrcode.htm in Resources */, C6D429941DA75988002A5711 /* privoxy in Resources */, C6D429991DA76FBC002A5711 /* privoxy.config.example in Resources */, - 0880CE401D6FE6D900BD39E2 /* example-gui-config.json in Resources */, 9BEEF06B1D04D4D500FC52B3 /* stop_ss_local.sh in Resources */, 9B3FFF341D08CEF70019A709 /* SWBQRCodeWindowController.xib in Resources */, 9BEEF06C1D04D4D500FC52B3 /* reload_conf_ss_local.sh in Resources */,