// // ProxyConfigHelper.m // com.west2online.ClashX.ProxyConfigHelper // // Created by yichengchen on 2019/8/17. // Copyright © 2019 west2online. All rights reserved. // #import "ProxyConfigHelper.h" #import #import "ProxyConfigRemoteProcessProtocol.h" #import "ProxySettingTool.h" @interface ProxyConfigHelper() < NSXPCListenerDelegate, ProxyConfigRemoteProcessProtocol > @property (nonatomic, strong) NSXPCListener *listener; @property (nonatomic, strong) NSMutableSet *connections; @property (nonatomic, strong) NSTimer *checkTimer; @property (nonatomic, assign) BOOL shouldQuit; @end @implementation ProxyConfigHelper - (instancetype)init { if (self = [super init]) { self.connections = [NSMutableSet new]; self.shouldQuit = NO; self.listener = [[NSXPCListener alloc] initWithMachServiceName:@"com.west2online.ClashX.ProxyConfigHelper"]; self.listener.delegate = self; } return self; } - (void)run { [self.listener resume]; self.checkTimer = [NSTimer timerWithTimeInterval:5.f target:self selector:@selector(connectionCheckOnLaunch) userInfo:nil repeats:NO]; [[NSRunLoop currentRunLoop] addTimer:self.checkTimer forMode:NSDefaultRunLoopMode]; while (!self.shouldQuit) { [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:2.0]]; } } - (void)connectionCheckOnLaunch { if (self.connections.count == 0) { self.shouldQuit = YES; } } - (BOOL)connectionIsVaild: (NSXPCConnection *)connection { NSRunningApplication *remoteApp = [NSRunningApplication runningApplicationWithProcessIdentifier:connection.processIdentifier]; return remoteApp != nil; } // MARK: - NSXPCListenerDelegate - (BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection { // if (![self connectionIsVaild:newConnection]) { // return NO; // } newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(ProxyConfigRemoteProcessProtocol)]; newConnection.exportedObject = self; __weak NSXPCConnection *weakConnection = newConnection; __weak ProxyConfigHelper *weakSelf = self; newConnection.invalidationHandler = ^{ [weakSelf.connections removeObject:weakConnection]; if (weakSelf.connections.count == 0) { weakSelf.shouldQuit = YES; } }; [self.connections addObject:newConnection]; [newConnection resume]; return YES; } // MARK: - ProxyConfigRemoteProcessProtocol - (void)getVersion:(stringReplyBlock)reply { NSString *version = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"]; if (version == nil) { version = @"unknown"; } reply(version); } - (void)enableProxyWithPort:(int)port socksPort:(int)socksPort error:(stringReplyBlock)reply { ProxySettingTool *tool = [ProxySettingTool new]; [tool enableProxyWithport:port socksPort:socksPort]; reply(nil); } - (void)disableProxy:(stringReplyBlock)reply { ProxySettingTool *tool = [ProxySettingTool new]; [tool disableProxy]; reply(nil); } - (void)restoreProxyWithCurrentPort:(int)port socksPort:(int)socksPort info:(NSDictionary *)dict error:(stringReplyBlock)reply { ProxySettingTool *tool = [ProxySettingTool new]; [tool restoreProxySettint:dict currentPort:port currentSocksPort:socksPort]; reply(nil); } - (void)getCurrentProxySetting:(dictReplyBlock)reply { NSDictionary *info = [ProxySettingTool currentProxySettings]; reply(info); } @end