add privoxy

This commit is contained in:
王晨
2016-10-07 17:52:30 +08:00
committed by qinyuhang
parent 5815c29003
commit 2ab6f95631
16 changed files with 475 additions and 8 deletions

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!
@ -46,7 +47,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
// Prepare ss-local
InstallSSLocal()
InstallPrivoxy()
// Prepare defaults
let defaults = UserDefaults.standard
defaults.register(defaults: [
@ -60,7 +61,11 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
"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),
"AutoConfigureNetworkServices": NSNumber(value: true as Bool),
"LocalHTTP.ListenAddress": "127.0.0.1",
"LocalHTTP.ListenPort": NSNumber(value: 1087 as UInt16),
"LocalHTTPOn": true
])
statusItem = NSStatusBar.system().statusItem(withLength: 20)
@ -98,6 +103,12 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
self.applyConfig()
}
)
notifyCenter.addObserver(forName: NSNotification.Name(rawValue: NOTIFY_HTTP_CONF_CHANGED), object: nil, queue: nil
, using: {
(note) in
SyncPrivoxy()
}
)
notifyCenter.addObserver(forName: NSNotification.Name(rawValue: "NOTIFY_FOUND_SS_URL"), object: nil, queue: nil) {
(note: Notification) in
if let userInfo = (note as NSNotification).userInfo {
@ -291,6 +302,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()

View File

@ -0,0 +1,95 @@
<?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="163"/>
<rect key="screenRect" x="0.0" y="0.0" width="1280" height="777"/>
<view key="contentView" id="Qef-Mj-9z1">
<rect key="frame" x="0.0" y="0.0" width="209" height="163"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<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="YV3-cX-xGk"/>
</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="URg-d3-2U6"/>
<outlet property="formatter" destination="ji3-e7-HNW" id="xWV-vJ-7eq"/>
</connections>
</textField>
<button translatesAutoresizingMaskIntoConstraints="NO" id="hgn-81-fsH">
<rect key="frame" x="18" y="133" 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"/>
<connections>
<binding destination="Adn-6l-wm4" name="value" keyPath="values.LocalHTTPOn" id="1Pd-0E-d1Z"/>
</connections>
</buttonCell>
</button>
</subviews>
<constraints>
<constraint firstItem="lD1-xm-Qy3" firstAttribute="top" secondItem="Ecd-cS-zUI" secondAttribute="bottom" constant="8" symbolic="YES" id="5Yk-wJ-yNC"/>
<constraint firstItem="vsw-6L-eh3" firstAttribute="leading" secondItem="Ecd-cS-zUI" secondAttribute="leading" id="5mp-aQ-Qhg"/>
<constraint firstItem="vsw-6L-eh3" firstAttribute="top" secondItem="CKF-K9-m8X" secondAttribute="bottom" constant="8" symbolic="YES" id="7uP-qc-xvy"/>
<constraint firstItem="CKF-K9-m8X" firstAttribute="trailing" secondItem="vsw-6L-eh3" secondAttribute="trailing" id="Ezc-Tf-zrc"/>
<constraint firstItem="hgn-81-fsH" firstAttribute="leading" secondItem="Qef-Mj-9z1" secondAttribute="leading" constant="20" symbolic="YES" id="Fpc-TK-Ies"/>
<constraint firstItem="Ecd-cS-zUI" firstAttribute="top" secondItem="vsw-6L-eh3" secondAttribute="bottom" constant="6" id="KgW-Uu-Md4"/>
<constraint firstItem="Ecd-cS-zUI" firstAttribute="leading" secondItem="lD1-xm-Qy3" secondAttribute="leading" id="Mbc-uA-iWI"/>
<constraint firstItem="hgn-81-fsH" firstAttribute="leading" secondItem="CKF-K9-m8X" secondAttribute="leading" id="ScT-n3-3a6"/>
<constraint firstItem="CKF-K9-m8X" firstAttribute="top" secondItem="hgn-81-fsH" secondAttribute="bottom" constant="15" id="Vg9-Uw-dYv"/>
<constraint firstItem="vsw-6L-eh3" firstAttribute="trailing" secondItem="lD1-xm-Qy3" secondAttribute="trailing" id="iO8-bs-YWa"/>
<constraint firstAttribute="bottom" secondItem="lD1-xm-Qy3" secondAttribute="bottom" constant="20" symbolic="YES" id="tqJ-4V-bgH"/>
<constraint firstItem="CKF-K9-m8X" firstAttribute="leading" secondItem="vsw-6L-eh3" secondAttribute="leading" id="yJ3-vA-lWm"/>
</constraints>
</view>
<connections>
<outlet property="delegate" destination="-2" id="mD3-X9-VEN"/>
</connections>
<point key="canvasLocation" x="-19.5" y="92.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>

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">
<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">
@ -118,6 +119,12 @@
<action selector="editAdvPreferences:" target="Voe-Tx-rLC" id="mEF-XS-HJE"/>
</connections>
</menuItem>
<menuItem title="HTTP Proxy Preference ..." 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>
@ -151,5 +158,18 @@
</menuItem>
</items>
</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>

View File

@ -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)
}
}

View File

@ -9,9 +9,11 @@
import Foundation
let SS_LOCAL_VERSION = "2.4.6"
let PRIVOXY_VERSION = "3.0.26"
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()
}
}
}

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"

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
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

BIN
ShadowsocksX-NG/privoxy Executable file

Binary file not shown.

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.*.*.*/ .

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"

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
ShadowsocksX-NG/stop_privoxy.sh Executable file
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"

View File

@ -0,0 +1,12 @@
/* 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 代理 设置";

View File

@ -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代理设置...";