From ff6863eb2e58c8d5639024c68d5ff34397f1b738 Mon Sep 17 00:00:00 2001 From: RK Date: Sun, 12 Jan 2020 16:24:28 +0500 Subject: [PATCH 01/19] i18n ru-RU First version of Russian translation. --- shadowsocks-csharp/Data/i18n.csv | 414 +++++++++++++++---------------- 1 file changed, 207 insertions(+), 207 deletions(-) diff --git a/shadowsocks-csharp/Data/i18n.csv b/shadowsocks-csharp/Data/i18n.csv index c9f8b48b..9d12799e 100644 --- a/shadowsocks-csharp/Data/i18n.csv +++ b/shadowsocks-csharp/Data/i18n.csv @@ -1,207 +1,207 @@ -en,zh-CN,zh-TW,ja -#Restart program to apply translation,,, -#This is comment line,,, -#Always keep language name at head of file,,, -#Language name is output in log,,, -"#You can find it by search ""Current language is:""",,, -#Please use UTF-8 with BOM encoding so we can edit it in Excel,,, -,,, -Shadowsocks,Shadowsocks,Shadowsocks,Shadowsocks -,,, -#Menu,,, -,,, -System Proxy,系统代理,系統代理,システムプロキシ -Disable,禁用,禁用,無効 -PAC,PAC 模式,PAC 模式,PAC -Global,全局模式,全局模式,全般 -Servers,服务器,伺服器,サーバー -Edit Servers...,编辑服务器...,編輯伺服器...,サーバーの編集... -Statistics Config...,统计配置...,統計設定檔...,統計情報の設定... -Start on Boot,开机启动,開機啟動,システムと同時に起動 -Forward Proxy...,正向代理设置...,正向 Proxy 設定...,フォワードプロキシの設定... -Allow other Devices to connect,允许其他设备连入,允許其他裝置連入,他のデバイスからの接続を許可する -Local PAC,使用本地 PAC,使用本機 PAC,ローカル PAC -Online PAC,使用在线 PAC,使用線上 PAC,オンライン PAC -Edit Local PAC File...,编辑本地 PAC 文件...,編輯本機 PAC 檔案...,ローカル PAC ファイルの編集... -Update Local PAC from GFWList,从 GFWList 更新本地 PAC,從 GFWList 更新本機 PAC,GFWList からローカル PAC を更新 -Edit User Rule for GFWList...,编辑 GFWList 的用户规则...,編輯 GFWList 的使用者規則...,ユーザールールの編集... -Secure Local PAC,保护本地 PAC,安全本機 PAC,ローカル PAC を保護 -Copy Local PAC URL,复制本地 PAC 网址,複製本機 PAC 網址,ローカル PAC URL をコピー -Share Server Config...,分享服务器配置...,分享伺服器設定檔...,サーバーの設定を共有... -Scan QRCode from Screen...,扫描屏幕上的二维码...,掃描螢幕上的 QR 碼...,画面から QR コードをスキャン... -Import URL from Clipboard...,从剪贴板导入URL...,從剪貼簿匯入 URL...,クリップボードから URL をインポート... -Availability Statistics,统计可用性,統計可用性,可用性の統計 -Show Logs...,显示日志...,顯示記錄檔...,ログの表示... -Verbose Logging,详细记录日志,詳細資訊記錄,詳細なログを記録 -Updates...,更新...,更新...,更新... -Check for Updates...,检查更新,檢查更新,更新プログラムの確認... -Check for Updates at Startup,启动时检查更新,啟動時檢查更新,起動時に更新プログラムを確認 -Check Pre-release Version,检查测试版更新,檢查發行前版本更新,先行開発版も確認 -Edit Hotkeys...,编辑快捷键...,編輯快速鍵...,ホットキーの編集... -About...,关于...,關於...,Shadowsocks について... -Help,帮助,說明,ヘルプ -Quit,退出,結束,終了 -Edit Servers,编辑服务器,編輯伺服器,サーバーの編集 -Load Balance,负载均衡,負載平衡,負荷分散 -High Availability,高可用,高可用性,高可用性 -Choose by statistics,根据统计,根據統計,統計で選ぶ -Show Plugin Output,显示插件输出,, -Write translation template,写入翻译模板,, -,,, -# Config Form,,, -,,, -&Add,添加(&A),新增 (&A),新規 (&A) -&Delete,删除(&D),移除 (&D),削除 (&D) -Dupli&cate,复制(&C),複製 (&C),コピー (&C) -Server,服务器,伺服器,サーバー -Server IP,服务器地址,伺服器位址,サーバーアドレス -Server Port,服务器端口,伺服器連接埠,サーバーポート -Password,密码,密碼,パスワード -Show Password,显示密码,顯示密碼,パスワードを表示する -Encryption,加密,加密,暗号化 -Plugin Program,插件程序,外掛程式,プラグインプログラム -Plugin Options,插件选项,外掛程式選項,プラグインのオプション -Need Plugin Argument,需要命令行参数,, -Plugin Arguments,插件参数,外掛程式參數,プラグインの引数 -Proxy Port,代理端口,Proxy 連接埠,プロキシポート -Portable Mode,便携模式,便攜模式,ポータブルモード -Restart required,需要重新启动SS,需要重新啟動SS,再起動SSが必要 -Remarks,备注,註解,付記 -Timeout(Sec),超时(秒),逾時 (秒),タイムアウト (秒) -OK,确定,確定,OK -Cancel,取消,取消,キャンセル -Apply,应用,應用,適用 -New server,未配置的服务器,新伺服器,新規サーバー -Move &Up,上移(&U),上移 (&U),上に移動 (&U) -Move D&own,下移(&O),下移 (&O),下に移動 (&O) -,,, -#Statistics Config,,, -,,, -Enable Statistics,启用统计,, -Ping Test,Ping测试,, -packages everytime,个包/次,, -By hour of day,按照每天的小时数统计,, -Collect data per,收集数据每,, -Keep choice for,保持选择每,, -minutes,分钟,, -Final Score:,总分:,, -AverageLatency,平均延迟,, -MinLatency,最小延迟,, -MaxLatency,最大延迟,, -AverageInboundSpeed,平均入站速度,, -MinInboundSpeed,最小入站速度,, -MaxInboundSpeed,最大入站速度,, -AverageOutboundSpeed,平均出站速度,, -MinOutboundSpeed,最小出站速度,, -MaxOutboundSpeed,最大出站速度,, -AverageResponse,平均响应速度,, -MinResponse,最小响应速度,, -MaxResponse,最大响应速度,, -PackageLoss,丢包率,, -Speed,速度,, -Package Loss,丢包率,, -Ping,网络延迟,, -Chart Mode,图表模式,, -24h,24小时,, -all,全部,, -,,, -# Proxy Form,,, -,,, -Edit Proxy,代理设置,編輯 Proxy,プロキシの編集 -Use Proxy,使用代理,使用 Proxy,プロキシを利用する -Proxy Type,代理类型,Proxy 類型,プロキシの種類 -Proxy Addr,代理地址,Proxy 位址,プロキシアドレス -Proxy Port,代理端口,Proxy 連接埠,プロキシポート -"If server has a plugin, proxy will not be used",若服务器含有插件,代理将不被使用,若伺服器含有外掛程式,Proxy 將不被使用,サーバーにプラグインがある場合、プロキシは利用されません -Use Auth,使用认证,使用認證,認証を利用する -User Name,用户名,認證用戶,認証ユーザ -Auth Pwd,认证密码,認證口令,認証パスワード -,,, -# Log Form,,, -,,, -&File,文件(&F),檔案 (&F),ファイル (&F) -&Open Location,在资源管理器中打开(&O),在檔案總管中開啟 (&O),ファイルの場所を開く (&O) -E&xit,退出(&X),結束 (&X),終了 (&X) -&View,视图(&V),檢視 (&V),表示 (&V) -&Clear Logs,清空日志(&C),清除記錄檔 (&C),ログの削除 (&C) -Change &Font,设置字体(&F),變更字型 (&F),フォント (&F) -&Wrap Text,自动换行(&W),自動換行 (&W),右端で折り返す (&W) -&Top Most,置顶(&T),置頂 (&T),常に最前面に表示 (&T) -&Show Toolbar,显示工具栏(&S),顯示工具列 (&S),ツールバーの表示 (&S) -Log Viewer,日志查看器,記錄檔檢視器,ログビューア -Inbound,入站,輸入,受信 -Outbound,出站,輸出,送信 -,,, -# QRCode Form,,, -,,, -QRCode and URL,二维码与 URL,QR 碼與 URL,QR コードと URL -,,, -# PAC Url Form,,, -,,, -Edit Online PAC URL,编辑在线 PAC 网址,編輯線上 PAC 網址,オンライン PAC URL の編集 -Edit Online PAC URL...,编辑在线 PAC 网址...,編輯線上 PAC 網址...,オンライン PAC URL の編集... -Please input PAC Url,请输入 PAC 网址,請輸入 PAC 網址,PAC URLを入力して下さい -,,, -# HotkeySettings Form,,, -,,, -Switch system proxy,切换系统代理状态,切換系統 Proxy 狀態,システム プロキシの状態を切り替える -Switch system proxy mode,切换系统代理模式,切換系統 Proxy 模式,プロキシモードを切り替える -Allow Clients from LAN,切换局域网共享,切換區域網路共用,LAN からのアクセスの許可を切り替える -Show Logs...,显示日志,顯示記錄檔,ログの表示 -Switch to previous server,切换上个服务器,切換上一個伺服器,前のサーバーに切り替える -Switch to next server,切换下个服务器,切換下一個伺服器,次のサーバーに切り替える -Reg All,注册全部快捷键,註冊所有快速鍵,全部登録する -Reg Hotkeys At Startup,启动时注册快捷键,啟動時註冊快速鍵,起動時にホットキーを登録する -,,, -# Messages,,, -,,, -Shadowsocks Error: {0},Shadowsocks 错误: {0},Shadowsocks 錯誤: {0},Shadowsocks エラー: {0} -Port {0} already in use,端口 {0} 已被占用,連接埠號碼 {0} 已被使用,ポート番号 {0} は既に使用されています。 -Port {0} is reserved by system,端口 {0} 是系统保留端口,連接埠號碼 {0} 由系統保留, ポート番号 {0} はシステムによって予約されています -Invalid server address,非法服务器地址,無效伺服器位址,サーバーアドレスが無効です。 -Illegal port number format,非法端口格式,無效連接埠號碼格式,ポート番号のフォーマットが無効です。 -Illegal timeout format,非法超时格式,無效逾時格式,タイムアウト値のフォーマットが無効です。 -Server IP can not be blank,服务器 IP 不能为空,伺服器 IP 不能為空,サーバー IP が指定されていません。 -Password can not be blank,密码不能为空,密碼不能為空,パスワードが指定されていません。 -Port out of range,端口超出范围,連接埠號碼超出範圍,ポート番号は範囲外です。 -Port can't be 8123,端口不能为 8123,連接埠號碼不能為 8123,8123 番以外のポート番号を指定して下さい。 -Shadowsocks {0} Update Found,Shadowsocks {0} 更新,Shadowsocks {0} 更新,Shadowsocks バージョン {0} は利用できます。 -No update is available,没有可用的更新,沒有可用的更新,お使いのバージョンは最新です。 -Click here to update,点击这里升级,點按此處升級,クリックしてアップデートします。 -Shadowsocks is here,Shadowsocks 在这里,Shadowsocks 在這裡,Shadowsocks はここです。 -You can turn on/off Shadowsocks in the context menu,可以在右键菜单中开关 Shadowsocks,可以在右鍵選項單中開關 Shadowsocks,コンテキストメニューを使って、Shadowsocks を有効または無効にすることができます。 -System Proxy Enabled,系统代理已启用,系統 Proxy 已啟用,システム プロキシが有効です。 -System Proxy Disabled,系统代理未启用,系統 Proxy 未啟用,システム プロキシが無効です。 -Failed to update PAC file ,更新 PAC 文件失败,更新 PAC 檔案失敗,PAC の更新に失敗しました。 -PAC updated,更新 PAC 成功,更新 PAC 成功,PAC を更新しました。 -No updates found. Please report to GFWList if you have problems with it.,未发现更新。如有问题请提交给 GFWList。,未發現更新。如有問題請報告至 GFWList。,お使いのバージョンは最新です。問題がある場合は、GFWList に報告して下さい。 -No QRCode found. Try to zoom in or move it to the center of the screen.,未发现二维码,尝试把它放大或移动到靠近屏幕中间的位置,未發現 QR 碼,嘗試把它放大或移動到靠近熒幕中間的位置,QR コードが見つかりませんでした。コードを大きくするか、画面の中央に移動して下さい。 -Shadowsocks is already running.,Shadowsocks 已经在运行。,Shadowsocks 已經在執行。,Shadowsocks 実行中 -Find Shadowsocks icon in your notify tray.,请在任务栏里寻找 Shadowsocks 图标。,請在工作列裡尋找 Shadowsocks 圖示。,通知領域には Shadowsocks のアイコンがあります。 -"If you want to start multiple Shadowsocks, make a copy in another directory.",如果想同时启动多个,可以另外复制一份到别的目录。,如果想同時啟動多個,可以另外複製一份至別的目錄。,複数起動したい場合は、プログラムファイルを別のフォルダーにコピーしてから、もう一度実行して下さい。 -Failed to decode QRCode,无法解析二维码,QR 碼解碼失敗,QR コードの読み取りに失敗しました。 -Failed to update registry,无法修改注册表,無法修改登錄檔,レジストリの更新に失敗しました。 -System Proxy On: ,系统代理已启用:,系統 Proxy 已啟用:,システム プロキシが有効: -Running: Port {0},正在运行:端口 {0},正在執行:連接埠號碼 {0},実行中:ポート {0} -"Unexpected error, shadowsocks will exit. Please report to",非预期错误,Shadowsocks将退出。请提交此错误到,非預期錯誤,Shadowsocks 將結束。請報告此錯誤至,予想外のエラーが発生したため、Shadowsocks を終了します。詳しくは下記までお問い合わせ下さい: -"Unsupported operating system, use Windows Vista at least.",不支持的操作系统版本,最低需求为Windows Vista。,不支援的作業系統版本,最低需求為 Windows Vista。,お使いの OS はサポートされていません。Windows Vista 以降の OS で実行して下さい。 -"Unsupported .NET Framework, please update to {0} or later.",当前 .NET Framework 版本过低,请升级至{0}或更新版本。,目前 .NET Framework 版本過低,最低需求為{0}。,お使いの .NET Framework はサポートされていません。{0} 以降のバンジョーをインストールして下さい。 -Proxy request failed,代理请求失败,Proxy 要求失敗,プロキシ要求が失敗しました。 -Proxy handshake failed,代理握手失败,Proxy 交握失敗,プロキシ ハンドシェイクに失敗しました。 -Register hotkey failed,注册快捷键失败,註冊快速鍵失敗,ホットキーの登錄に失敗しました。 -Cannot parse hotkey: {0},解析快捷键失败: {0},剖析快速鍵失敗: {0},ホットキーを解析できません: {0} -"Timeout is invalid, it should not exceed {0}",超时无效,不应超过 {0},逾時無效,不應超過 {0},タイムアウト値が無効です。{0} 以下の値を指定して下さい。 -Cannot find the plugin program file,找不到插件程序文件,找不到外掛程式文件, -,,, -Operation failure,操作失败,, -Auto save failed,自动保存失败,, -Whether to discard unconfigured servers,是否丢弃未配置的服务器,, -"Invalid server address, Cannot automatically save or discard changes",非法服务器地址,无法自动保存,是否丢弃修改,, -"Illegal port number format, Cannot automatically save or discard changes",非法端口格式,无法自动保存,是否丢弃修改,, -"Password can not be blank, Cannot automatically save or discard changes",密码不能为空,无法自动保存,是否丢弃修改,, -"Illegal timeout format, Cannot automatically save or discard changes",非法超时格式,无法自动保存,是否丢弃修改,, -,,, -"Error occured when process proxy setting, do you want reset current setting and retry?",处理代理设置时发生错误,是否重置当前代理设置并重试?,, -"Unrecoverable proxy setting error occured, see log for detail",发生不可恢复的代理设置错误,查看日志以取得详情,, -Auth user can not be blank,认证用户不能为空,認證用戶不能為空,認証ユーザが指定されていません。 -Auth pwd can not be blank,认证密码不能为空,認證口令不能為空,認証パスワードが指定されていません。 +en,ru-RU,zh-CN,zh-TW,ja +#Restart program to apply translation,,,, +#This is comment line,,,, +#Always keep language name at head of file,,,, +#Language name is output in log,,,, +"#You can find it by search ""Current language is:""",,,, +#Please use UTF-8 with BOM encoding so we can edit it in Excel,,,, +,,,, +Shadowsocks,Shadowsocks,Shadowsocks,Shadowsocks,Shadowsocks +,,,, +#Menu,,,, +,,,, +System Proxy,Системный прокси-сервер,系统代理,系統代理,システムプロキシ +Disable,Отключен,禁用,禁用,無効 +PAC,Сценарий настройки (PAC),PAC 模式,PAC 模式,PAC +Global,Для всей системы,全局模式,全局模式,全般 +Servers,Серверы,服务器,伺服器,サーバー +Edit Servers...,Редактировать серверы…,编辑服务器...,編輯伺服器...,サーバーの編集... +Statistics Config...,Настройки статистики…,统计配置...,統計設定檔...,統計情報の設定... +Start on Boot,Автозагрузка,开机启动,開機啟動,システムと同時に起動 +Forward Proxy...,Прямой прокси…,正向代理设置...,正向 Proxy 設定...,フォワードプロキシの設定... +Allow other Devices to connect,Общий доступ к подключению,允许其他设备连入,允許其他裝置連入,他のデバイスからの接続を許可する +Local PAC,Локальный PAC,使用本地 PAC,使用本機 PAC,ローカル PAC +Online PAC,Удаленный PAC,使用在线 PAC,使用線上 PAC,オンライン PAC +Edit Local PAC File...,Редактировать локальный PAC…,编辑本地 PAC 文件...,編輯本機 PAC 檔案...,ローカル PAC ファイルの編集... +Update Local PAC from GFWList,Обновить локальный PAC из GFWList,从 GFWList 更新本地 PAC,從 GFWList 更新本機 PAC,GFWList からローカル PAC を更新 +Edit User Rule for GFWList...,Редактировать свои правила для GFWList,编辑 GFWList 的用户规则...,編輯 GFWList 的使用者規則...,ユーザールールの編集... +Secure Local PAC,Безопасный URL локального PAC,保护本地 PAC,安全本機 PAC,ローカル PAC を保護 +Copy Local PAC URL,Копировать URL локального PAC,复制本地 PAC 网址,複製本機 PAC 網址,ローカル PAC URL をコピー +Share Server Config...,Поделиться конфигурацией сервера…,分享服务器配置...,分享伺服器設定檔...,サーバーの設定を共有... +Scan QRCode from Screen...,Сканировать QRCode с экрана…,扫描屏幕上的二维码...,掃描螢幕上的 QR 碼...,画面から QR コードをスキャン... +Import URL from Clipboard...,Импорт адреса из буфера обмена…,从剪贴板导入URL...,從剪貼簿匯入 URL...,クリップボードから URL をインポート... +Availability Statistics,Статистика доступности,统计可用性,統計可用性,可用性の統計 +Show Logs...,Показать журнал…,显示日志...,顯示記錄檔...,ログの表示... +Verbose Logging,Подробный журнал,详细记录日志,詳細資訊記錄,詳細なログを記録 +Updates...,Обновления…,更新...,更新...,更新... +Check for Updates...,Проверить обновления…,检查更新,檢查更新,更新プログラムの確認... +Check for Updates at Startup,Проверять при запуске,启动时检查更新,啟動時檢查更新,起動時に更新プログラムを確認 +Check Pre-release Version,Проверять предрелизные версии,检查测试版更新,檢查發行前版本更新,先行開発版も確認 +Edit Hotkeys...,Горячие клавиши…,编辑快捷键...,編輯快速鍵...,ホットキーの編集... +About...,О программе…,关于...,關於...,Shadowsocks について... +Help,Помощь,帮助,說明,ヘルプ +Quit,Выход,退出,結束,終了 +Edit Servers,Редактирование серверов,编辑服务器,編輯伺服器,サーバーの編集 +Load Balance,Балансировка нагрузки,负载均衡,負載平衡,負荷分散 +High Availability,Высокая доступность,高可用,高可用性,高可用性 +Choose by statistics,На основе статистики,根据统计,根據統計,統計で選ぶ +Show Plugin Output,События плагинов в журнале,显示插件输出,, +Write translation template,Создать шаблон для перевода,写入翻译模板,, +,,,, +# Config Form,,,, +,,,, +&Add,Добавить,添加(&A),新增 (&A),新規 (&A) +&Delete,Удалить,删除(&D),移除 (&D),削除 (&D) +Dupli&cate,Дублир-ть,复制(&C),複製 (&C),コピー (&C) +Server,Сервер,服务器,伺服器,サーバー +Server IP,IP-адрес,服务器地址,伺服器位址,サーバーアドレス +Server Port,Порт,服务器端口,伺服器連接埠,サーバーポート +Password,Пароль,密码,密碼,パスワード +Show Password,Показать пароль,显示密码,顯示密碼,パスワードを表示する +Encryption,Шифрование,加密,加密,暗号化 +Plugin Program,Плагин,插件程序,外掛程式,プラグインプログラム +Plugin Options,Опции плагина,插件选项,外掛程式選項,プラグインのオプション +Need Plugin Argument,Требуются аргументы,需要命令行参数,, +Plugin Arguments,Аргументы,插件参数,外掛程式參數,プラグインの引数 +Proxy Port,Порт прокси,代理端口,Proxy 連接埠,プロキシポート +Portable Mode,Переносимый режим,便携模式,便攜模式,ポータブルモード +Restart required,Требуется перезапуск программы,需要重新启动SS,需要重新啟動SS,再起動SSが必要 +Remarks,Примечания,备注,註解,付記 +Timeout(Sec),Таймаут(сек),超时(秒),逾時 (秒),タイムアウト (秒) +OK,ОК,确定,確定,OK +Cancel,Отмена,取消,取消,キャンセル +Apply,Применить,应用,應用,適用 +New server,Новый сервер,未配置的服务器,新伺服器,新規サーバー +Move &Up,Выше,上移(&U),上移 (&U),上に移動 (&U) +Move D&own,Ниже,下移(&O),下移 (&O),下に移動 (&O) +,,,, +#Statistics Config,,,, +,,,, +Enable Statistics,Включить сбор статистики,启用统计,, +Ping Test,Проверка связи (Ping),Ping测试,, +packages everytime,пакета на проверку,个包/次,, +By hour of day,Ежечасно,按照每天的小时数统计,, +Collect data per,Собирать данные за,收集数据每,, +Keep choice for,Хранить отбор данных за,保持选择每,, +minutes,мин.,分钟,, +Final Score:,Финальная оценка:,总分:,, +AverageLatency,СредЗадержка,平均延迟,, +MinLatency,МинЗадержка,最小延迟,, +MaxLatency,МаксЗадержка,最大延迟,, +AverageInboundSpeed,СредВходСкорость,平均入站速度,, +MinInboundSpeed,МинВходСкорость,最小入站速度,, +MaxInboundSpeed,СредВходСкорость,最大入站速度,, +AverageOutboundSpeed,СредИсхСкорость,平均出站速度,, +MinOutboundSpeed,МинИсхСкорость,最小出站速度,, +MaxOutboundSpeed,МаксИсхСкорость,最大出站速度,, +AverageResponse,СредВремяОтвета,平均响应速度,, +MinResponse,МинВремяОтвета,最小响应速度,, +MaxResponse,МаксВремяОтвета,最大响应速度,, +PackageLoss,ПотериПакетов,丢包率,, +Speed,Скорость,速度,, +Package Loss,Потери пакетов,丢包率,, +Ping,Ping,网络延迟,, +Chart Mode,График,图表模式,, +24h,24ч,24小时,, +all,За все время,全部,, +,,,, +# Proxy Form,,,, +,,,, +Edit Proxy,Редактирование прокси,代理设置,編輯 Proxy,プロキシの編集 +Use Proxy,Использовать прокси,使用代理,使用 Proxy,プロキシを利用する +Proxy Type,Тип прокси,代理类型,Proxy 類型,プロキシの種類 +Proxy Addr,Адрес прокси,代理地址,Proxy 位址,プロキシアドレス +Proxy Port,Порт прокси,代理端口,Proxy 連接埠,プロキシポート +"If server has a plugin, proxy will not be used","Если сервер использует плагины, прокси НЕ будет использоваться",若服务器含有插件,代理将不被使用,若伺服器含有外掛程式,Proxy 將不被使用,サーバーにプラグインがある場合、プロキシは利用されません +Use Auth,Требуется авторизация,使用认证,使用認證,認証を利用する +User Name,Пользователь,用户名,認證用戶,認証ユーザ +Auth Pwd,Пароль,认证密码,認證口令,認証パスワード +,,,, +# Log Form,,,, +,,,, +&File,Файл,文件(&F),檔案 (&F),ファイル (&F) +&Open Location,Расположение файла,在资源管理器中打开(&O),在檔案總管中開啟 (&O),ファイルの場所を開く (&O) +E&xit,Выход,退出(&X),結束 (&X),終了 (&X) +&View,Вид,视图(&V),檢視 (&V),表示 (&V) +&Clear Logs,Очистить журнал,清空日志(&C),清除記錄檔 (&C),ログの削除 (&C) +Change &Font,Шрифт…,设置字体(&F),變更字型 (&F),フォント (&F) +&Wrap Text,Перенос строк,自动换行(&W),自動換行 (&W),右端で折り返す (&W) +&Top Most,Поверх всех окон,置顶(&T),置頂 (&T),常に最前面に表示 (&T) +&Show Toolbar,Панель инструментов,显示工具栏(&S),顯示工具列 (&S),ツールバーの表示 (&S) +Log Viewer,Просмотр журнала,日志查看器,記錄檔檢視器,ログビューア +Inbound,Входящая,入站,輸入,受信 +Outbound,Исходящая,出站,輸出,送信 +,,,, +# QRCode Form,,,, +,,,, +QRCode and URL,QRCode и URL,二维码与 URL,QR 碼與 URL,QR コードと URL +,,,, +# PAC Url Form,,,, +,,,, +Edit Online PAC URL,Изменение URL удаленного PAC,编辑在线 PAC 网址,編輯線上 PAC 網址,オンライン PAC URL の編集 +Edit Online PAC URL...,Редактировать URL удаленного PAC…,编辑在线 PAC 网址...,編輯線上 PAC 網址...,オンライン PAC URL の編集... +Please input PAC Url,Введите URL адрес для PAC-файла,请输入 PAC 网址,請輸入 PAC 網址,PAC URLを入力して下さい +,,,, +# HotkeySettings Form,,,, +,,,, +Switch system proxy,ВКЛ/ВЫКЛ системный прокси-сервер,切换系统代理状态,切換系統 Proxy 狀態,システム プロキシの状態を切り替える +Switch system proxy mode,Переключение режима прокси-сервера,切换系统代理模式,切換系統 Proxy 模式,プロキシモードを切り替える +Allow Clients from LAN,Общий доступ к подключению,切换局域网共享,切換區域網路共用,LAN からのアクセスの許可を切り替える +Show Logs...,Просмотр журналов,显示日志,顯示記錄檔,ログの表示 +Switch to previous server,Переключить на пред. сервер,切换上个服务器,切換上一個伺服器,前のサーバーに切り替える +Switch to next server,Переключить на след. сервер,切换下个服务器,切換下一個伺服器,次のサーバーに切り替える +Reg All,Применить все,注册全部快捷键,註冊所有快速鍵,全部登録する +Reg Hotkeys At Startup,Применять при запуске программы,启动时注册快捷键,啟動時註冊快速鍵,起動時にホットキーを登録する +,,,, +# Messages,,,, +,,,, +Shadowsocks Error: {0},Ошибка Shadowsocks: {0},Shadowsocks 错误: {0},Shadowsocks 錯誤: {0},Shadowsocks エラー: {0} +Port {0} already in use,Порт {0} уже используется,端口 {0} 已被占用,連接埠號碼 {0} 已被使用,ポート番号 {0} は既に使用されています。 +Port {0} is reserved by system,Порт {0} зарезервирован системой,端口 {0} 是系统保留端口,連接埠號碼 {0} 由系統保留, ポート番号 {0} はシステムによって予約されています +Invalid server address,Неверный адрес сервера,非法服务器地址,無效伺服器位址,サーバーアドレスが無効です。 +Illegal port number format,Неверный числовой формат порта,非法端口格式,無效連接埠號碼格式,ポート番号のフォーマットが無効です。 +Illegal timeout format,Неверный формат таймаута,非法超时格式,無效逾時格式,タイムアウト値のフォーマットが無効です。 +Server IP can not be blank,IP-адрес сервера не может быть пустым,服务器 IP 不能为空,伺服器 IP 不能為空,サーバー IP が指定されていません。 +Password can not be blank,Пароль не может быть пустым,密码不能为空,密碼不能為空,パスワードが指定されていません。 +Port out of range,Порт выходит за допустимый диапазон,端口超出范围,連接埠號碼超出範圍,ポート番号は範囲外です。 +Port can't be 8123,Адрес порта 8123 не может быть использован,端口不能为 8123,連接埠號碼不能為 8123,8123 番以外のポート番号を指定して下さい。 +Shadowsocks {0} Update Found,Обнаружена новая версия Shadowsocks: {0},Shadowsocks {0} 更新,Shadowsocks {0} 更新,Shadowsocks バージョン {0} は利用できます。 +No update is available,Обновлений не обнаружено,没有可用的更新,沒有可用的更新,お使いのバージョンは最新です。 +Click here to update,Нажмите сюда для обновления,点击这里升级,點按此處升級,クリックしてアップデートします。 +Shadowsocks is here,Shadowsocks находится здесь,Shadowsocks 在这里,Shadowsocks 在這裡,Shadowsocks はここです。 +You can turn on/off Shadowsocks in the context menu,Вы можете управлять Shadowsocks из контекстного меню,可以在右键菜单中开关 Shadowsocks,可以在右鍵選項單中開關 Shadowsocks,コンテキストメニューを使って、Shadowsocks を有効または無効にすることができます。 +System Proxy Enabled,Системный прокси включен,系统代理已启用,系統 Proxy 已啟用,システム プロキシが有効です。 +System Proxy Disabled,Системный прокси отключен,系统代理未启用,系統 Proxy 未啟用,システム プロキシが無効です。 +Failed to update PAC file ,Не удалось обновить PAC файл,更新 PAC 文件失败,更新 PAC 檔案失敗,PAC の更新に失敗しました。 +PAC updated,PAC файл обновлен,更新 PAC 成功,更新 PAC 成功,PAC を更新しました。 +No updates found. Please report to GFWList if you have problems with it.,Обновлений не найдено. Сообщите авторам GFWList если у вас возникли проблемы.,未发现更新。如有问题请提交给 GFWList。,未發現更新。如有問題請報告至 GFWList。,お使いのバージョンは最新です。問題がある場合は、GFWList に報告して下さい。 +No QRCode found. Try to zoom in or move it to the center of the screen.,QRCode не обнаружен. Попробуйте увеличить изображение или переместить его в центр экрана.,未发现二维码,尝试把它放大或移动到靠近屏幕中间的位置,未發現 QR 碼,嘗試把它放大或移動到靠近熒幕中間的位置,QR コードが見つかりませんでした。コードを大きくするか、画面の中央に移動して下さい。 +Shadowsocks is already running.,Shadowsocks уже запущен.,Shadowsocks 已经在运行。,Shadowsocks 已經在執行。,Shadowsocks 実行中 +Find Shadowsocks icon in your notify tray.,Значок Shadowsocks можно найти в области уведомлений.,请在任务栏里寻找 Shadowsocks 图标。,請在工作列裡尋找 Shadowsocks 圖示。,通知領域には Shadowsocks のアイコンがあります。 +"If you want to start multiple Shadowsocks, make a copy in another directory.","Если вы хотите запустить несколько копий Shadowsocks одновременно, создайте отдельную папку на каждую копию.",如果想同时启动多个,可以另外复制一份到别的目录。,如果想同時啟動多個,可以另外複製一份至別的目錄。,複数起動したい場合は、プログラムファイルを別のフォルダーにコピーしてから、もう一度実行して下さい。 +Failed to decode QRCode,Не удалось распознать QRCode,无法解析二维码,QR 碼解碼失敗,QR コードの読み取りに失敗しました。 +Failed to update registry,Не удалось обновить запись в реестре,无法修改注册表,無法修改登錄檔,レジストリの更新に失敗しました。 +System Proxy On: ,Системный прокси:,系统代理已启用:,系統 Proxy 已啟用:,システム プロキシが有効: +Running: Port {0},Запущен на порту {0},正在运行:端口 {0},正在執行:連接埠號碼 {0},実行中:ポート {0} +"Unexpected error, shadowsocks will exit. Please report to","Непредвиденная ошибка, пожалуйста сообщите на",非预期错误,Shadowsocks将退出。请提交此错误到,非預期錯誤,Shadowsocks 將結束。請報告此錯誤至,予想外のエラーが発生したため、Shadowsocks を終了します。詳しくは下記までお問い合わせ下さい: +"Unsupported operating system, use Windows Vista at least.","Операционная система не поддерживается, минимальные системные требования: Windows Vista или выше.",不支持的操作系统版本,最低需求为Windows Vista。,不支援的作業系統版本,最低需求為 Windows Vista。,お使いの OS はサポートされていません。Windows Vista 以降の OS で実行して下さい。 +"Unsupported .NET Framework, please update to {0} or later.","Версия .NET Framework не поддерживается, минимальные системные требования: {0} или выше.",当前 .NET Framework 版本过低,请升级至{0}或更新版本。,目前 .NET Framework 版本過低,最低需求為{0}。,お使いの .NET Framework はサポートされていません。{0} 以降のバンジョーをインストールして下さい。 +Proxy request failed,Не удалось выполнить запрос,代理请求失败,Proxy 要求失敗,プロキシ要求が失敗しました。 +Proxy handshake failed,Не удалось выполнить хэндшейк,代理握手失败,Proxy 交握失敗,プロキシ ハンドシェイクに失敗しました。 +Register hotkey failed,Не удалось применить настройки горячих клавиш,注册快捷键失败,註冊快速鍵失敗,ホットキーの登錄に失敗しました。 +Cannot parse hotkey: {0},Не удалось распознать следующие горячие клавиши: {0},解析快捷键失败: {0},剖析快速鍵失敗: {0},ホットキーを解析できません: {0} +"Timeout is invalid, it should not exceed {0}",Таймаут не может превышать значение {0},超时无效,不应超过 {0},逾時無效,不應超過 {0},タイムアウト値が無効です。{0} 以下の値を指定して下さい。 +Cannot find the plugin program file,Файл плагина не найден,找不到插件程序文件,找不到外掛程式文件, +,,,, +Operation failure,Операция завершилась неудачей,操作失败,, +Auto save failed,Автоматическое сохранение не удалось,自动保存失败,, +Whether to discard unconfigured servers,,是否丢弃未配置的服务器,, +"Invalid server address, Cannot automatically save or discard changes",Неверный адрес сервера. Невозможно сохранить или отменить изменения,非法服务器地址,无法自动保存,是否丢弃修改,, +"Illegal port number format, Cannot automatically save or discard changes",Неверный числовой адрес порта. Невозможно сохранить или отменить изменения,非法端口格式,无法自动保存,是否丢弃修改,, +"Password can not be blank, Cannot automatically save or discard changes",Пароль не может быть пустым. Невозможно сохранить или отменить изменения,密码不能为空,无法自动保存,是否丢弃修改,, +"Illegal timeout format, Cannot automatically save or discard changes",Неверный формат таймаута. Невозможно сохранить или отменить изменения,非法超时格式,无法自动保存,是否丢弃修改,, +,,,, +"Error occured when process proxy setting, do you want reset current setting and retry?",Произошла ошибка при обработке настроек. Хотите сбросить текущие настройки и попробовать снова?,处理代理设置时发生错误,是否重置当前代理设置并重试?,, +"Unrecoverable proxy setting error occured, see log for detail","Произошла серьезная ошибка, подробности можно узнать в журналах",发生不可恢复的代理设置错误,查看日志以取得详情,, +Auth user can not be blank,Пользователь не может быть пустым,认证用户不能为空,認證用戶不能為空,認証ユーザが指定されていません。 +Auth pwd can not be blank,Пароль не может быть пустым,认证密码不能为空,認證口令不能為空,認証パスワードが指定されていません。 From 35950b9a5885154709fa66c5e4ca61a53d4a06cc Mon Sep 17 00:00:00 2001 From: Student Main Date: Sun, 12 Jan 2020 23:17:57 +0800 Subject: [PATCH 02/19] Rename and translate title of statistics form. close #2768 --- shadowsocks-csharp/Data/i18n.csv | 1 + .../View/StatisticsStrategyConfigurationForm.Designer.cs | 1 + 2 files changed, 2 insertions(+) diff --git a/shadowsocks-csharp/Data/i18n.csv b/shadowsocks-csharp/Data/i18n.csv index c9f8b48b..34312d6d 100644 --- a/shadowsocks-csharp/Data/i18n.csv +++ b/shadowsocks-csharp/Data/i18n.csv @@ -50,6 +50,7 @@ Write translation template,写入翻译模板,, ,,, # Config Form,,, ,,, +Statistics configuration,统计配置,,, &Add,添加(&A),新增 (&A),新規 (&A) &Delete,删除(&D),移除 (&D),削除 (&D) Dupli&cate,复制(&C),複製 (&C),コピー (&C) diff --git a/shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.Designer.cs b/shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.Designer.cs index a4a02f15..0e80c12e 100644 --- a/shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.Designer.cs +++ b/shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.Designer.cs @@ -481,6 +481,7 @@ this.MinimumSize = new System.Drawing.Size(1000, 800); this.Name = "StatisticsStrategyConfigurationForm"; this.Text = "StatisticsStrategyConfigurationForm"; + this.Text = "Statistics configuration"; ((System.ComponentModel.ISupportInitialize)(this.StatisticsChart)).EndInit(); this.chartModeSelector.ResumeLayout(false); this.chartModeSelector.PerformLayout(); From af8977eb9b855db408facbd3da85d11fd759972e Mon Sep 17 00:00:00 2001 From: RK Date: Tue, 14 Jan 2020 20:43:07 +0500 Subject: [PATCH 03/19] Update i18n.csv Added translation for "Statistics configuration" line. --- shadowsocks-csharp/Data/i18n.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shadowsocks-csharp/Data/i18n.csv b/shadowsocks-csharp/Data/i18n.csv index 06109762..3db1ef8f 100644 --- a/shadowsocks-csharp/Data/i18n.csv +++ b/shadowsocks-csharp/Data/i18n.csv @@ -50,6 +50,7 @@ Write translation template,Создать шаблон для перевода, ,,,, # Config Form,,,, ,,,, +Statistics configuration,Настройки статистики,统计配置,, &Add,Добавить,添加(&A),新增 (&A),新規 (&A) &Delete,Удалить,删除(&D),移除 (&D),削除 (&D) Dupli&cate,Дублир-ть,复制(&C),複製 (&C),コピー (&C) @@ -104,7 +105,6 @@ Ping,Ping,网络延迟,, Chart Mode,График,图表模式,, 24h,24ч,24小时,, all,За все время,全部,, -StatisticsStrategyConfigurationForm,Настройки статистики,,, ,,,, # Proxy Form,,,, ,,,, From 79d8c41654390bf0ed4332cd5de12c911f9f94b6 Mon Sep 17 00:00:00 2001 From: Student Main Date: Sun, 19 Jan 2020 00:23:49 +0800 Subject: [PATCH 04/19] Check program is updated --- shadowsocks-csharp/Model/Configuration.cs | 8 +++++ shadowsocks-csharp/View/MenuViewController.cs | 30 ++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/shadowsocks-csharp/Model/Configuration.cs b/shadowsocks-csharp/Model/Configuration.cs index e8aad2d5..b0bec8ad 100644 --- a/shadowsocks-csharp/Model/Configuration.cs +++ b/shadowsocks-csharp/Model/Configuration.cs @@ -37,6 +37,10 @@ namespace Shadowsocks.Model public HotkeyConfig hotkey; private static readonly string CONFIG_FILE = "gui-config.json"; + + [JsonIgnore] + public bool updated = false; + [JsonIgnore] public string localHost => GetLocalHost(); private string GetLocalHost() { @@ -78,6 +82,10 @@ namespace Shadowsocks.Model string configContent = File.ReadAllText(CONFIG_FILE); Configuration config = JsonConvert.DeserializeObject(configContent); config.isDefault = false; + if (UpdateChecker.Asset.CompareVersion(UpdateChecker.Version, config.version) > 0) + { + config.updated = true; + } if (config.configs == null) config.configs = new List(); diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs index 18d0e1b0..3e7c11a5 100644 --- a/shadowsocks-csharp/View/MenuViewController.cs +++ b/shadowsocks-csharp/View/MenuViewController.cs @@ -30,6 +30,7 @@ namespace Shadowsocks.View private bool _isFirstRun; private bool _isStartupChecking; private string _urlToOpen; + private bool _updated; private ContextMenu contextMenu1; private MenuItem disableItem; @@ -113,6 +114,18 @@ namespace Shadowsocks.View _isStartupChecking = true; updateChecker.CheckUpdate(config, 3000); } + + if (config.updated) + { + ShowBalloonTip( + I18N.GetString("Updated"), + I18N.GetString("updated"), + ToolTipIcon.Info, + 0 + ); + config.updated = false; + Configuration.Save(config); + } } private void controller_TrafficChanged(object sender, EventArgs e) @@ -565,9 +578,24 @@ namespace Shadowsocks.View if (_isFirstRun) { CheckUpdateForFirstRun(); - ShowFirstTimeBalloon(); + ShowBalloonTip( + I18N.GetString("Shadowsocks is here"), + I18N.GetString("You can turn on/off Shadowsocks in the context menu"), + ToolTipIcon.Info, + 0 + ); _isFirstRun = false; } + if (_updated) + { + ShowBalloonTip( + I18N.GetString("Updated"), + I18N.GetString("updated"), + ToolTipIcon.Info, + 0 + ); + _updated = false; + } } void proxyForm_FormClosed(object sender, FormClosedEventArgs e) From f12ef1a5be9d81634e60ad6dec29e25f258c0c07 Mon Sep 17 00:00:00 2001 From: Student Main Date: Sun, 19 Jan 2020 19:36:59 +0800 Subject: [PATCH 05/19] replace ShowFirstTimeBalloon with ShowBalloonTip --- shadowsocks-csharp/View/MenuViewController.cs | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs index 3e7c11a5..79c9d5d3 100644 --- a/shadowsocks-csharp/View/MenuViewController.cs +++ b/shadowsocks-csharp/View/MenuViewController.cs @@ -385,7 +385,7 @@ namespace Shadowsocks.View { string argument = @"/select, " + e.Path; - System.Diagnostics.Process.Start("explorer.exe", argument); + Process.Start("explorer.exe", argument); } void ShowBalloonTip(string title, string content, ToolTipIcon icon, int timeout) @@ -428,10 +428,10 @@ namespace Shadowsocks.View if (updateChecker.NewVersionFound) { updateChecker.NewVersionFound = false; /* Reset the flag */ - if (System.IO.File.Exists(updateChecker.LatestVersionLocalName)) + if (File.Exists(updateChecker.LatestVersionLocalName)) { string argument = "/select, \"" + updateChecker.LatestVersionLocalName + "\""; - System.Diagnostics.Process.Start("explorer.exe", argument); + Process.Start("explorer.exe", argument); } } } @@ -632,14 +632,6 @@ namespace Shadowsocks.View updateChecker.CheckUpdate(config, 3000); } - private void ShowFirstTimeBalloon() - { - _notifyIcon.BalloonTipTitle = I18N.GetString("Shadowsocks is here"); - _notifyIcon.BalloonTipText = I18N.GetString("You can turn on/off Shadowsocks in the context menu"); - _notifyIcon.BalloonTipIcon = ToolTipIcon.Info; - _notifyIcon.ShowBalloonTip(0); - } - private void AboutItem_Click(object sender, EventArgs e) { Process.Start("https://github.com/shadowsocks/shadowsocks-windows"); From 13a3471fa321b1b7a1b98f953543c014e97c04fe Mon Sep 17 00:00:00 2001 From: Student Main Date: Sun, 19 Jan 2020 22:31:57 +0800 Subject: [PATCH 06/19] Invoke EventHandler instead of show balloon tip when updated --- .../Controller/ShadowsocksController.cs | 19 +++++++++++++++ shadowsocks-csharp/Program.cs | 14 +++++++---- shadowsocks-csharp/View/MenuViewController.cs | 23 ------------------- 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs index 4faf95d4..66a42f6f 100644 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs @@ -52,6 +52,12 @@ namespace Shadowsocks.Controller public string Path; } + public class UpdatedEventArgs : EventArgs + { + public string OldVersion; + public string NewVersion; + } + public class TrafficPerSecond { public long inboundCounter; @@ -78,6 +84,9 @@ namespace Shadowsocks.Controller public event ErrorEventHandler Errored; + // Invoked when controller.Start(); + public event EventHandler ProgramUpdated; + public ShadowsocksController() { _config = Configuration.Load(); @@ -90,6 +99,16 @@ namespace Shadowsocks.Controller public void Start(bool regHotkeys = true) { + if (_config.updated && regHotkeys) + { + _config.updated = false; + ProgramUpdated.Invoke(this, new UpdatedEventArgs() + { + OldVersion = _config.version, + NewVersion = UpdateChecker.Version, + }); + Configuration.Save(_config); + } Reload(); if (regHotkeys) { diff --git a/shadowsocks-csharp/Program.cs b/shadowsocks-csharp/Program.cs index 05337551..63485522 100755 --- a/shadowsocks-csharp/Program.cs +++ b/shadowsocks-csharp/Program.cs @@ -25,7 +25,7 @@ namespace Shadowsocks static void Main(string[] args) { // .NET Framework 4.7.2 on Win7 compatibility - System.Net.ServicePointManager.SecurityProtocol |= + System.Net.ServicePointManager.SecurityProtocol |= System.Net.SecurityProtocolType.Tls | System.Net.SecurityProtocolType.Tls11 | System.Net.SecurityProtocolType.Tls12; // store args for further use @@ -78,18 +78,22 @@ namespace Shadowsocks return; } Directory.SetCurrentDirectory(Application.StartupPath); -#if DEBUG + Logging.OpenLogFile(); - +#if DEBUG // truncate privoxy log file while debugging string privoxyLogFilename = Utils.GetTempPath("privoxy.log"); if (File.Exists(privoxyLogFilename)) using (new FileStream(privoxyLogFilename, FileMode.Truncate)) { } -#else - Logging.OpenLogFile(); #endif MainController = new ShadowsocksController(); MenuController = new MenuViewController(MainController); + + MainController.ProgramUpdated += (o, e) => + { + Logging.Info($"Updated from {e.OldVersion} to {e.NewVersion}"); + }; + HotKeys.Init(MainController); MainController.Start(); Application.Run(); diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs index 79c9d5d3..59abf18b 100644 --- a/shadowsocks-csharp/View/MenuViewController.cs +++ b/shadowsocks-csharp/View/MenuViewController.cs @@ -30,7 +30,6 @@ namespace Shadowsocks.View private bool _isFirstRun; private bool _isStartupChecking; private string _urlToOpen; - private bool _updated; private ContextMenu contextMenu1; private MenuItem disableItem; @@ -114,18 +113,6 @@ namespace Shadowsocks.View _isStartupChecking = true; updateChecker.CheckUpdate(config, 3000); } - - if (config.updated) - { - ShowBalloonTip( - I18N.GetString("Updated"), - I18N.GetString("updated"), - ToolTipIcon.Info, - 0 - ); - config.updated = false; - Configuration.Save(config); - } } private void controller_TrafficChanged(object sender, EventArgs e) @@ -586,16 +573,6 @@ namespace Shadowsocks.View ); _isFirstRun = false; } - if (_updated) - { - ShowBalloonTip( - I18N.GetString("Updated"), - I18N.GetString("updated"), - ToolTipIcon.Info, - 0 - ); - _updated = false; - } } void proxyForm_FormClosed(object sender, FormClosedEventArgs e) From a8b11ea30bc8704e8239f411905598e4586fdab0 Mon Sep 17 00:00:00 2001 From: Student Main Date: Tue, 21 Jan 2020 22:06:30 +0800 Subject: [PATCH 07/19] update detector works when update from v4.1.2 and before Configuration.version added in 0e426ffe, only 1 year ago --- shadowsocks-csharp/Model/Configuration.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/shadowsocks-csharp/Model/Configuration.cs b/shadowsocks-csharp/Model/Configuration.cs index b0bec8ad..23523416 100644 --- a/shadowsocks-csharp/Model/Configuration.cs +++ b/shadowsocks-csharp/Model/Configuration.cs @@ -43,7 +43,8 @@ namespace Shadowsocks.Model [JsonIgnore] public string localHost => GetLocalHost(); - private string GetLocalHost() { + private string GetLocalHost() + { return isIPv6Enabled ? "[::1]" : "127.0.0.1"; } public Server GetCurrentServer() @@ -82,9 +83,9 @@ namespace Shadowsocks.Model string configContent = File.ReadAllText(CONFIG_FILE); Configuration config = JsonConvert.DeserializeObject(configContent); config.isDefault = false; - if (UpdateChecker.Asset.CompareVersion(UpdateChecker.Version, config.version) > 0) + if (UpdateChecker.Asset.CompareVersion(UpdateChecker.Version, config.version ?? "0") > 0) { - config.updated = true; + config.updated = true; } if (config.configs == null) @@ -101,7 +102,8 @@ namespace Shadowsocks.Model config.proxy = new ProxyConfig(); if (config.hotkey == null) config.hotkey = new HotkeyConfig(); - if (!System.Net.Sockets.Socket.OSSupportsIPv6) { + if (!System.Net.Sockets.Socket.OSSupportsIPv6) + { config.isIPv6Enabled = false; // disable IPv6 if os not support } //TODO if remote host(server) do not support IPv6 (or DNS resolve AAAA TYPE record) disable IPv6? From 84c55d116d4547bdc5523e3e1fdf31ffd4edf537 Mon Sep 17 00:00:00 2001 From: celeron533 Date: Sat, 4 Jan 2020 22:26:58 +0800 Subject: [PATCH 08/19] WIP: Migrate to NLog --- shadowsocks-csharp/Controller/FileManager.cs | 9 +- shadowsocks-csharp/Controller/HotkeyReg.cs | 5 +- shadowsocks-csharp/Controller/I18N.cs | 12 +- .../Controller/LoggerExtension.cs | 110 ++++ shadowsocks-csharp/Controller/Logging.cs | 198 ------- .../Service/AvailabilityStatistics.cs | 41 +- .../Controller/Service/GfwListUpdater.cs | 8 +- .../Controller/Service/Listener.cs | 16 +- .../Controller/Service/PACDaemon.cs | 9 +- .../Controller/Service/PACServer.cs | 7 +- .../Controller/Service/PortForwarder.cs | 23 +- .../Controller/Service/PrivoxyRunner.cs | 11 +- .../Controller/Service/TCPRelay.cs | 76 +-- .../Controller/Service/UDPRelay.cs | 9 +- .../Controller/Service/UpdateChecker.cs | 20 +- .../Controller/ShadowsocksController.cs | 12 +- .../Strategy/HighAvailabilityStrategy.cs | 17 +- .../Controller/Strategy/StatisticsStrategy.cs | 12 +- .../Controller/System/AutoStartup.cs | 19 +- .../Controller/System/SystemProxy.cs | 5 +- shadowsocks-csharp/Data/NLog.config | 10 + .../Encryption/AEAD/AEADEncryptor.cs | 38 +- .../Encryption/AEAD/AEADSodiumEncryptor.cs | 19 +- shadowsocks-csharp/Encryption/MbedTLS.cs | 5 +- shadowsocks-csharp/Encryption/OpenSSL.cs | 5 +- shadowsocks-csharp/Encryption/Sodium.cs | 7 +- shadowsocks-csharp/Model/Configuration.cs | 8 +- .../Model/StatisticsStrategyConfiguration.cs | 8 +- shadowsocks-csharp/Program.cs | 33 +- .../Properties/Resources.Designer.cs | 483 +++++++++--------- shadowsocks-csharp/Properties/Resources.resx | 3 + shadowsocks-csharp/Proxy/HttpProxy.cs | 5 +- .../Util/ProcessManagement/Job.cs | 5 +- .../Util/SystemProxy/Sysproxy.cs | 7 +- shadowsocks-csharp/Util/Util.cs | 11 +- shadowsocks-csharp/View/LogForm.cs | 11 +- shadowsocks-csharp/View/MenuViewController.cs | 8 +- shadowsocks-csharp/packages.config | 1 + shadowsocks-csharp/shadowsocks-csharp.csproj | 12 +- 39 files changed, 676 insertions(+), 622 deletions(-) create mode 100644 shadowsocks-csharp/Controller/LoggerExtension.cs delete mode 100755 shadowsocks-csharp/Controller/Logging.cs create mode 100644 shadowsocks-csharp/Data/NLog.config diff --git a/shadowsocks-csharp/Controller/FileManager.cs b/shadowsocks-csharp/Controller/FileManager.cs index d7db51c1..ef30470d 100755 --- a/shadowsocks-csharp/Controller/FileManager.cs +++ b/shadowsocks-csharp/Controller/FileManager.cs @@ -1,4 +1,5 @@ -using System; +using NLog; +using System; using System.IO; using System.IO.Compression; using System.Text; @@ -7,6 +8,8 @@ namespace Shadowsocks.Controller { public static class FileManager { + private static Logger logger = LogManager.GetCurrentClassLogger(); + public static bool ByteArrayToFile(string fileName, byte[] content) { try @@ -17,7 +20,7 @@ namespace Shadowsocks.Controller } catch (Exception ex) { - Logging.Error(ex); + logger.Error(ex); } return false; } @@ -57,7 +60,7 @@ namespace Shadowsocks.Controller } catch (Exception ex) { - Logging.Error(ex); + logger.Error(ex); throw ex; } } diff --git a/shadowsocks-csharp/Controller/HotkeyReg.cs b/shadowsocks-csharp/Controller/HotkeyReg.cs index 5482ec6d..90a3dee9 100644 --- a/shadowsocks-csharp/Controller/HotkeyReg.cs +++ b/shadowsocks-csharp/Controller/HotkeyReg.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using System.Windows.Forms; - +using NLog; using Shadowsocks.Controller.Hotkeys; using Shadowsocks.Model; @@ -9,6 +9,7 @@ namespace Shadowsocks.Controller { static class HotkeyReg { + private static Logger logger = LogManager.GetCurrentClassLogger(); public static void RegAllHotkeys() { var hotkeyConfig = Configuration.Load().hotkey; @@ -60,7 +61,7 @@ namespace Shadowsocks.Controller var hotkey = HotKeys.Str2HotKey(hotkeyStr); if (hotkey == null) { - Logging.Error($"Cannot parse hotkey: {hotkeyStr}"); + logger.Error($"Cannot parse hotkey: {hotkeyStr}"); onComplete?.Invoke(RegResult.ParseError); return false; } diff --git a/shadowsocks-csharp/Controller/I18N.cs b/shadowsocks-csharp/Controller/I18N.cs index 7102b79a..eb948c39 100755 --- a/shadowsocks-csharp/Controller/I18N.cs +++ b/shadowsocks-csharp/Controller/I18N.cs @@ -1,4 +1,5 @@ using Microsoft.VisualBasic.FileIO; +using NLog; using Shadowsocks.Properties; using Shadowsocks.Util; using System.Collections.Generic; @@ -9,9 +10,10 @@ using System.Windows.Forms; namespace Shadowsocks.Controller { - public static class I18N { + private static Logger logger = LogManager.GetCurrentClassLogger(); + public const string I18N_FILE = "i18n.csv"; private static Dictionary _strings = new Dictionary(); @@ -47,12 +49,12 @@ namespace Shadowsocks.Controller } if (targetIndex != -1 && enIndex != targetIndex) { - Logging.Info($"Using {localeNames[targetIndex]} translation for {locale}"); + logger.Info($"Using {localeNames[targetIndex]} translation for {locale}"); } else { // Still not found, exit - Logging.Info($"Translation for {locale} not found"); + logger.Info($"Translation for {locale} not found"); return; } } @@ -85,10 +87,10 @@ namespace Shadowsocks.Controller } else { - Logging.Info("Using external translation"); + logger.Info("Using external translation"); i18n = File.ReadAllText(I18N_FILE, Encoding.UTF8); } - Logging.Info("Current language is: " + locale); + logger.Info("Current language is: " + locale); Init(i18n, locale); } diff --git a/shadowsocks-csharp/Controller/LoggerExtension.cs b/shadowsocks-csharp/Controller/LoggerExtension.cs new file mode 100644 index 00000000..012c63dd --- /dev/null +++ b/shadowsocks-csharp/Controller/LoggerExtension.cs @@ -0,0 +1,110 @@ +using System; +using System.ComponentModel; +using System.IO; +using System.Net.Sockets; +using System.Net; +using System.Diagnostics; +using System.Text; +using Shadowsocks.Util.SystemProxy; + +namespace NLog +{ + public static class LoggerExtension + { + public static void Dump(this Logger logger, string tag, byte[] arr, int length) + { + var sb = new StringBuilder($"{Environment.NewLine}{tag}: "); + for (int i = 0; i < length - 1; i++) + { + sb.Append($"0x{arr[i]:X2}, "); + } + sb.Append($"0x{arr[length - 1]:X2}"); + sb.Append(Environment.NewLine); + logger.Debug(sb.ToString()); + } + + public static void Debug(this Logger logger, EndPoint local, EndPoint remote, int len, string header = null, string tailer = null) + { + if (header == null && tailer == null) + logger.Debug($"{local} => {remote} (size={len})"); + else if (header == null && tailer != null) + logger.Debug($"{local} => {remote} (size={len}), {tailer}"); + else if (header != null && tailer == null) + logger.Debug($"{header}: {local} => {remote} (size={len})"); + else + logger.Debug($"{header}: {local} => {remote} (size={len}), {tailer}"); + } + + public static void Debug(this Logger logger, Socket sock, int len, string header = null, string tailer = null) + { + logger.Debug(sock.LocalEndPoint, sock.RemoteEndPoint, len, header, tailer); + } + + public static void LogUsefulException(this Logger logger, Exception e) + { + // just log useful exceptions, not all of them + if (e is SocketException) + { + SocketException se = (SocketException)e; + if (se.SocketErrorCode == SocketError.ConnectionAborted) + { + // closed by browser when sending + // normally happens when download is canceled or a tab is closed before page is loaded + } + else if (se.SocketErrorCode == SocketError.ConnectionReset) + { + // received rst + } + else if (se.SocketErrorCode == SocketError.NotConnected) + { + // The application tried to send or receive data, and the System.Net.Sockets.Socket is not connected. + } + else if (se.SocketErrorCode == SocketError.HostUnreachable) + { + // There is no network route to the specified host. + } + else if (se.SocketErrorCode == SocketError.TimedOut) + { + // The connection attempt timed out, or the connected host has failed to respond. + } + else + { + logger.Info(e); + } + } + else if (e is ObjectDisposedException) + { + } + else if (e is Win32Exception) + { + var ex = (Win32Exception)e; + + // Win32Exception (0x80004005): A 32 bit processes cannot access modules of a 64 bit process. + if ((uint)ex.ErrorCode != 0x80004005) + { + logger.Info(e); + } + } + else if (e is ProxyException) + { + var ex = (ProxyException)e; + switch (ex.Type) + { + case ProxyExceptionType.FailToRun: + case ProxyExceptionType.QueryReturnMalformed: + case ProxyExceptionType.SysproxyExitError: + logger.Error($"sysproxy - {ex.Type.ToString()}:{ex.Message}"); + break; + case ProxyExceptionType.QueryReturnEmpty: + case ProxyExceptionType.Unspecific: + logger.Error($"sysproxy - {ex.Type.ToString()}"); + break; + } + } + else + { + logger.Info(e); + } + } + } +} diff --git a/shadowsocks-csharp/Controller/Logging.cs b/shadowsocks-csharp/Controller/Logging.cs deleted file mode 100755 index 1ea6f276..00000000 --- a/shadowsocks-csharp/Controller/Logging.cs +++ /dev/null @@ -1,198 +0,0 @@ -using System; -using System.ComponentModel; -using System.IO; -using System.Net.Sockets; -using System.Net; -using System.Diagnostics; -using System.Text; -using Shadowsocks.Util; -using Shadowsocks.Util.SystemProxy; - -namespace Shadowsocks.Controller -{ - public class Logging - { - public static string LogFilePath; - - private static FileStream _fs; - private static StreamWriterWithTimestamp _sw; - - public static bool OpenLogFile() - { - try - { - LogFilePath = Utils.GetTempPath("shadowsocks.log"); - - _fs = new FileStream(LogFilePath, FileMode.Append); - _sw = new StreamWriterWithTimestamp(_fs); - _sw.AutoFlush = true; - Console.SetOut(_sw); - Console.SetError(_sw); - - return true; - } - catch (IOException e) - { - Console.WriteLine(e.ToString()); - return false; - } - } - - private static void WriteToLogFile(object o) - { - try { - Console.WriteLine(o); - } catch(ObjectDisposedException) { - } - } - - public static void Error(object o) - { - WriteToLogFile("[E] " + o); - } - - public static void Info(object o) - { - WriteToLogFile(o); - } - - public static void Clear() { - _sw.Close(); - _sw.Dispose(); - _fs.Close(); - _fs.Dispose(); - File.Delete(LogFilePath); - OpenLogFile(); - } - - [Conditional("DEBUG")] - public static void Debug(object o) - { - WriteToLogFile("[D] " + o); - } - - [Conditional("DEBUG")] - public static void Dump(string tag, byte[] arr, int length) - { - var sb = new StringBuilder($"{Environment.NewLine}{tag}: "); - for (int i = 0; i < length - 1; i++) { - sb.Append($"0x{arr[i]:X2}, "); - } - sb.Append($"0x{arr[length - 1]:X2}"); - sb.Append(Environment.NewLine); - Debug(sb.ToString()); - } - - [Conditional("DEBUG")] - public static void Debug(EndPoint local, EndPoint remote, int len, string header = null, string tailer = null) - { - if (header == null && tailer == null) - Debug($"{local} => {remote} (size={len})"); - else if (header == null && tailer != null) - Debug($"{local} => {remote} (size={len}), {tailer}"); - else if (header != null && tailer == null) - Debug($"{header}: {local} => {remote} (size={len})"); - else - Debug($"{header}: {local} => {remote} (size={len}), {tailer}"); - } - - [Conditional("DEBUG")] - public static void Debug(Socket sock, int len, string header = null, string tailer = null) - { - Debug(sock.LocalEndPoint, sock.RemoteEndPoint, len, header, tailer); - } - - public static void LogUsefulException(Exception e) - { - // just log useful exceptions, not all of them - if (e is SocketException) - { - SocketException se = (SocketException)e; - if (se.SocketErrorCode == SocketError.ConnectionAborted) - { - // closed by browser when sending - // normally happens when download is canceled or a tab is closed before page is loaded - } - else if (se.SocketErrorCode == SocketError.ConnectionReset) - { - // received rst - } - else if (se.SocketErrorCode == SocketError.NotConnected) - { - // The application tried to send or receive data, and the System.Net.Sockets.Socket is not connected. - } - else if (se.SocketErrorCode == SocketError.HostUnreachable) - { - // There is no network route to the specified host. - } - else if (se.SocketErrorCode == SocketError.TimedOut) - { - // The connection attempt timed out, or the connected host has failed to respond. - } - else - { - Info(e); - } - } - else if (e is ObjectDisposedException) - { - } - else if (e is Win32Exception) - { - var ex = (Win32Exception) e; - - // Win32Exception (0x80004005): A 32 bit processes cannot access modules of a 64 bit process. - if ((uint) ex.ErrorCode != 0x80004005) - { - Info(e); - } - } - else if (e is ProxyException) - { - var ex = (ProxyException)e; - switch (ex.Type) - { - case ProxyExceptionType.FailToRun: - case ProxyExceptionType.QueryReturnMalformed: - case ProxyExceptionType.SysproxyExitError: - Error($"sysproxy - {ex.Type.ToString()}:{ex.Message}"); - break; - case ProxyExceptionType.QueryReturnEmpty: - case ProxyExceptionType.Unspecific: - Error($"sysproxy - {ex.Type.ToString()}"); - break; - } - - - } - else - { - Info(e); - } - } - } - - // Simply extended System.IO.StreamWriter for adding timestamp workaround - public class StreamWriterWithTimestamp : StreamWriter - { - public StreamWriterWithTimestamp(Stream stream) : base(stream) - { - } - - private string GetTimestamp() - { - return "[" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "] "; - } - - public override void WriteLine(string value) - { - base.WriteLine(GetTimestamp() + value); - } - - public override void Write(string value) - { - base.Write(GetTimestamp() + value); - } - } - -} diff --git a/shadowsocks-csharp/Controller/Service/AvailabilityStatistics.cs b/shadowsocks-csharp/Controller/Service/AvailabilityStatistics.cs index 7cbeb743..5d11e1d8 100644 --- a/shadowsocks-csharp/Controller/Service/AvailabilityStatistics.cs +++ b/shadowsocks-csharp/Controller/Service/AvailabilityStatistics.cs @@ -9,6 +9,7 @@ using System.Net.Sockets; using System.Threading; using System.Threading.Tasks; using Newtonsoft.Json; +using NLog; using Shadowsocks.Model; using Shadowsocks.Util; @@ -18,6 +19,8 @@ namespace Shadowsocks.Controller public sealed class AvailabilityStatistics : IDisposable { + private static Logger logger = LogManager.GetCurrentClassLogger(); + public const string DateTimePattern = "yyyy-MM-dd HH:mm:ss"; private const string StatisticsFilesName = "shadowsocks.availability.json"; public static string AvailabilityStatisticsFile; @@ -111,7 +114,7 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Logging.LogUsefulException(e); + logger.LogUsefulException(e); } } @@ -155,7 +158,7 @@ namespace Shadowsocks.Controller inR.Add(inboundSpeed); outR.Add(outboundSpeed); - Logging.Debug( + logger.Debug( $"{id}: current/max inbound {inboundSpeed}/{inR.Max()} KiB/s, current/max outbound {outboundSpeed}/{outR.Max()} KiB/s"); } } @@ -213,7 +216,7 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Logging.Debug("config changed asynchrously, just ignore this server"); + logger.Debug("config changed asynchrously, just ignore this server"); } } @@ -235,7 +238,7 @@ namespace Shadowsocks.Controller { AppendRecord(server.Identifier(), record); } - Logging.Debug($"Ping {server.FriendlyName()} {e.RoundtripTime.Count} times, {(100 - record.PackageLoss * 100)}% packages loss, min {record.MinResponse} ms, max {record.MaxResponse} ms, avg {record.AverageResponse} ms"); + logger.Debug($"Ping {server.FriendlyName()} {e.RoundtripTime.Count} times, {(100 - record.PackageLoss * 100)}% packages loss, min {record.MinResponse} ms, max {record.MaxResponse} ms, avg {record.AverageResponse} ms"); if (Interlocked.Decrement(ref state.counter) == 0) { Save(); @@ -260,13 +263,13 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Logging.LogUsefulException(e); + logger.LogUsefulException(e); } } private void Save() { - Logging.Debug($"save statistics to {AvailabilityStatisticsFile}"); + logger.Debug($"save statistics to {AvailabilityStatisticsFile}"); if (RawStatistics.Count == 0) { return; @@ -283,7 +286,7 @@ namespace Shadowsocks.Controller } catch (IOException e) { - Logging.LogUsefulException(e); + logger.LogUsefulException(e); } } @@ -300,7 +303,7 @@ namespace Shadowsocks.Controller { try { - Logging.Debug("filter raw statistics"); + logger.Debug("filter raw statistics"); if (RawStatistics == null) return; var filteredStatistics = new Statistics(); @@ -315,7 +318,7 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Logging.LogUsefulException(e); + logger.LogUsefulException(e); } } @@ -324,7 +327,7 @@ namespace Shadowsocks.Controller try { var path = AvailabilityStatisticsFile; - Logging.Debug($"loading statistics from {path}"); + logger.Debug($"loading statistics from {path}"); if (!File.Exists(path)) { using (File.Create(path)) @@ -337,7 +340,7 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Logging.LogUsefulException(e); + logger.LogUsefulException(e); Console.WriteLine($"failed to load statistics; use runtime statistics, some data may be lost"); } } @@ -411,6 +414,8 @@ namespace Shadowsocks.Controller class MyPing { + private static Logger logger = LogManager.GetCurrentClassLogger(); + //arguments for ICMP tests public const int TimeoutMilliseconds = 500; @@ -445,7 +450,7 @@ namespace Shadowsocks.Controller { try { - Logging.Debug($"Ping {server.FriendlyName()}"); + logger.Debug($"Ping {server.FriendlyName()}"); if (ip == null) { ip = Dns.GetHostAddresses(server.server) @@ -461,8 +466,8 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Logging.Error($"An exception occured while eveluating {server.FriendlyName()}"); - Logging.LogUsefulException(e); + logger.Error($"An exception occured while eveluating {server.FriendlyName()}"); + logger.LogUsefulException(e); FireCompleted(e, userstate); } } @@ -473,20 +478,20 @@ namespace Shadowsocks.Controller { if (e.Reply.Status == IPStatus.Success) { - Logging.Debug($"Ping {server.FriendlyName()} {e.Reply.RoundtripTime} ms"); + logger.Debug($"Ping {server.FriendlyName()} {e.Reply.RoundtripTime} ms"); RoundtripTime.Add((int?)e.Reply.RoundtripTime); } else { - Logging.Debug($"Ping {server.FriendlyName()} timeout"); + logger.Debug($"Ping {server.FriendlyName()} timeout"); RoundtripTime.Add(null); } TestNext(e.UserState); } catch (Exception ex) { - Logging.Error($"An exception occured while eveluating {server.FriendlyName()}"); - Logging.LogUsefulException(ex); + logger.Error($"An exception occured while eveluating {server.FriendlyName()}"); + logger.LogUsefulException(ex); FireCompleted(ex, e.UserState); } } diff --git a/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs b/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs index 38044315..7f380cb4 100644 --- a/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs +++ b/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs @@ -5,7 +5,7 @@ using System.Net; using System.Text; using Newtonsoft.Json; - +using NLog; using Shadowsocks.Model; using Shadowsocks.Properties; using Shadowsocks.Util; @@ -14,6 +14,8 @@ namespace Shadowsocks.Controller { public class GFWListUpdater { + private static Logger logger = LogManager.GetCurrentClassLogger(); + private const string GFWLIST_URL = "https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt"; public event EventHandler UpdateCompleted; @@ -93,10 +95,10 @@ var __RULES__ = {JsonConvert.SerializeObject(gfwLines, Formatting.Indented)}; string gfwListUrl = GFWLIST_URL; if (!string.IsNullOrWhiteSpace(config.gfwListUrl)) { - Logging.Info("Found custom GFWListURL in config file"); + logger.Info("Found custom GFWListURL in config file"); gfwListUrl = config.gfwListUrl; } - Logging.Info($"Checking GFWList from {gfwListUrl}"); + logger.Info($"Checking GFWList from {gfwListUrl}"); WebClient http = new WebClient(); if (config.enabled) { diff --git a/shadowsocks-csharp/Controller/Service/Listener.cs b/shadowsocks-csharp/Controller/Service/Listener.cs index 70819163..6a9ab5b1 100644 --- a/shadowsocks-csharp/Controller/Service/Listener.cs +++ b/shadowsocks-csharp/Controller/Service/Listener.cs @@ -4,13 +4,15 @@ using System.Linq; using System.Net; using System.Net.NetworkInformation; using System.Net.Sockets; - +using NLog; using Shadowsocks.Model; namespace Shadowsocks.Controller { public class Listener { + private static Logger logger = LogManager.GetCurrentClassLogger(); + public interface IService { bool Handle(byte[] firstPacket, int length, Socket socket, object state); @@ -80,10 +82,10 @@ namespace Shadowsocks.Controller _tcpSocket.Listen(1024); // Start an asynchronous socket to listen for connections. - Logging.Info($"Shadowsocks started ({UpdateChecker.Version})"); + logger.Info($"Shadowsocks started ({UpdateChecker.Version})"); if (_config.isVerboseLogging) { - Logging.Info(Encryption.EncryptorFactory.DumpRegisteredEncryptor()); + logger.Info(Encryption.EncryptorFactory.DumpRegisteredEncryptor()); } _tcpSocket.BeginAccept(new AsyncCallback(AcceptCallback), _tcpSocket); UDPState udpState = new UDPState(_udpSocket); @@ -132,7 +134,7 @@ namespace Shadowsocks.Controller } catch (Exception ex) { - Logging.Debug(ex); + logger.Debug(ex); } finally { @@ -171,7 +173,7 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Logging.LogUsefulException(e); + logger.LogUsefulException(e); } finally { @@ -187,7 +189,7 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Logging.LogUsefulException(e); + logger.LogUsefulException(e); } } } @@ -218,7 +220,7 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Logging.LogUsefulException(e); + logger.LogUsefulException(e); conn.Close(); } } diff --git a/shadowsocks-csharp/Controller/Service/PACDaemon.cs b/shadowsocks-csharp/Controller/Service/PACDaemon.cs index 11dc18b4..3aee925a 100644 --- a/shadowsocks-csharp/Controller/Service/PACDaemon.cs +++ b/shadowsocks-csharp/Controller/Service/PACDaemon.cs @@ -1,4 +1,5 @@ -using Shadowsocks.Properties; +using NLog; +using Shadowsocks.Properties; using Shadowsocks.Util; using System; using System.Collections.Generic; @@ -15,6 +16,8 @@ namespace Shadowsocks.Controller /// public class PACDaemon { + private static Logger logger = LogManager.GetCurrentClassLogger(); + public const string PAC_FILE = "pac.txt"; public const string USER_RULE_FILE = "user-rule.txt"; public const string USER_ABP_FILE = "abp.txt"; @@ -100,7 +103,7 @@ namespace Shadowsocks.Controller { if (PACFileChanged != null) { - Logging.Info($"Detected: PAC file '{e.Name}' was {e.ChangeType.ToString().ToLower()}."); + logger.Info($"Detected: PAC file '{e.Name}' was {e.ChangeType.ToString().ToLower()}."); Task.Factory.StartNew(() => { ((FileSystemWatcher)sender).EnableRaisingEvents = false; @@ -115,7 +118,7 @@ namespace Shadowsocks.Controller { if (UserRuleFileChanged != null) { - Logging.Info($"Detected: User Rule file '{e.Name}' was {e.ChangeType.ToString().ToLower()}."); + logger.Info($"Detected: User Rule file '{e.Name}' was {e.ChangeType.ToString().ToLower()}."); Task.Factory.StartNew(() => { ((FileSystemWatcher)sender).EnableRaisingEvents = false; diff --git a/shadowsocks-csharp/Controller/Service/PACServer.cs b/shadowsocks-csharp/Controller/Service/PACServer.cs index 57e64ca2..7fd9250e 100644 --- a/shadowsocks-csharp/Controller/Service/PACServer.cs +++ b/shadowsocks-csharp/Controller/Service/PACServer.cs @@ -6,11 +6,14 @@ using System.Net; using System.Net.Sockets; using System.Text; using System.Web; +using NLog; namespace Shadowsocks.Controller { public class PACServer : Listener.Service { + private static Logger logger = LogManager.GetCurrentClassLogger(); + public const string RESOURCE_NAME = "pac"; private string PacSecret @@ -43,7 +46,7 @@ namespace Shadowsocks.Controller string usedSecret = _config.secureLocalPac ? $"&secret={PacSecret}" : ""; string contentHash = GetHash(_pacDaemon.GetPACContent()); PacUrl = $"http://{config.localHost}:{config.localPort}/{RESOURCE_NAME}?hash={contentHash}{usedSecret}"; - Logging.Debug("Set PAC URL:" + PacUrl); + logger.Debug("Set PAC URL:" + PacUrl); } private static string GetHash(string content) @@ -177,7 +180,7 @@ Connection: Close } catch (Exception e) { - Logging.LogUsefulException(e); + logger.LogUsefulException(e); socket.Close(); } } diff --git a/shadowsocks-csharp/Controller/Service/PortForwarder.cs b/shadowsocks-csharp/Controller/Service/PortForwarder.cs index 1acfa5bd..8284fd11 100644 --- a/shadowsocks-csharp/Controller/Service/PortForwarder.cs +++ b/shadowsocks-csharp/Controller/Service/PortForwarder.cs @@ -1,6 +1,7 @@ using System; using System.Net; using System.Net.Sockets; +using NLog; using Shadowsocks.Util.Sockets; namespace Shadowsocks.Controller @@ -26,6 +27,8 @@ namespace Shadowsocks.Controller private class Handler { + private static Logger logger = LogManager.GetCurrentClassLogger(); + private byte[] _firstPacket; private int _firstPacketLength; private Socket _local; @@ -58,7 +61,7 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Logging.LogUsefulException(e); + logger.LogUsefulException(e); Close(); } } @@ -77,7 +80,7 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Logging.LogUsefulException(e); + logger.LogUsefulException(e); Close(); } } @@ -94,7 +97,7 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Logging.LogUsefulException(e); + logger.LogUsefulException(e); Close(); } } @@ -115,7 +118,7 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Logging.LogUsefulException(e); + logger.LogUsefulException(e); Close(); } } @@ -142,7 +145,7 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Logging.LogUsefulException(e); + logger.LogUsefulException(e); Close(); } } @@ -169,7 +172,7 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Logging.LogUsefulException(e); + logger.LogUsefulException(e); Close(); } } @@ -188,7 +191,7 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Logging.LogUsefulException(e); + logger.LogUsefulException(e); Close(); } } @@ -207,7 +210,7 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Logging.LogUsefulException(e); + logger.LogUsefulException(e); Close(); } } @@ -239,7 +242,7 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Logging.LogUsefulException(e); + logger.LogUsefulException(e); } } if (_remote != null) @@ -251,7 +254,7 @@ namespace Shadowsocks.Controller } catch (SocketException e) { - Logging.LogUsefulException(e); + logger.LogUsefulException(e); } } } diff --git a/shadowsocks-csharp/Controller/Service/PrivoxyRunner.cs b/shadowsocks-csharp/Controller/Service/PrivoxyRunner.cs index 187e7a09..0a6135d1 100644 --- a/shadowsocks-csharp/Controller/Service/PrivoxyRunner.cs +++ b/shadowsocks-csharp/Controller/Service/PrivoxyRunner.cs @@ -6,6 +6,7 @@ using System.Net; using System.Net.Sockets; using System.Text; using System.Windows.Forms; +using NLog; using Shadowsocks.Model; using Shadowsocks.Properties; using Shadowsocks.Util; @@ -15,6 +16,8 @@ namespace Shadowsocks.Controller { class PrivoxyRunner { + private static Logger logger = LogManager.GetCurrentClassLogger(); + private static int _uid; private static string _uniqueConfigFile; private static Job _privoxyJob; @@ -33,7 +36,7 @@ namespace Shadowsocks.Controller } catch (IOException e) { - Logging.LogUsefulException(e); + logger.LogUsefulException(e); } } @@ -106,7 +109,7 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Logging.LogUsefulException(e); + logger.LogUsefulException(e); } } @@ -139,7 +142,7 @@ namespace Shadowsocks.Controller * are already dead, and that will cause exceptions here. * We could simply ignore those exceptions. */ - Logging.LogUsefulException(ex); + logger.LogUsefulException(ex); return false; } } @@ -159,7 +162,7 @@ namespace Shadowsocks.Controller catch (Exception e) { // in case access denied - Logging.LogUsefulException(e); + logger.LogUsefulException(e); return defaultPort; } } diff --git a/shadowsocks-csharp/Controller/Service/TCPRelay.cs b/shadowsocks-csharp/Controller/Service/TCPRelay.cs index 7c89cac3..e97bfcb0 100644 --- a/shadowsocks-csharp/Controller/Service/TCPRelay.cs +++ b/shadowsocks-csharp/Controller/Service/TCPRelay.cs @@ -1,4 +1,5 @@ -using System; +using NLog; +using System; using System.Collections.Generic; using System.Linq; using System.Net; @@ -17,6 +18,7 @@ namespace Shadowsocks.Controller { class TCPRelay : Listener.Service { + private static Logger logger = LogManager.GetCurrentClassLogger(); private ShadowsocksController _controller; private DateTime _lastSweepTime; private Configuration _config; @@ -54,7 +56,7 @@ namespace Shadowsocks.Controller } foreach (TCPHandler handler1 in handlersToClose) { - Logging.Debug("Closing timed out TCP connection."); + logger.Debug("Closing timed out TCP connection."); handler1.Close(); } @@ -122,6 +124,8 @@ namespace Shadowsocks.Controller } } + private static Logger Logger = LogManager.GetCurrentClassLogger(); + private readonly int _serverTimeout; private readonly int _proxyTimeout; @@ -217,7 +221,7 @@ namespace Shadowsocks.Controller this._server = server; /* prepare address buffer length for AEAD */ - Logging.Debug($"_addrBufLength={_addrBufLength}"); + Logger.Debug($"_addrBufLength={_addrBufLength}"); _encryptor.AddrBufLength = _addrBufLength; } @@ -252,7 +256,7 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Logging.LogUsefulException(e); + Logger.LogUsefulException(e); } if (_currentRemoteSession != null) @@ -265,7 +269,7 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Logging.LogUsefulException(e); + Logger.LogUsefulException(e); } } @@ -291,7 +295,7 @@ namespace Shadowsocks.Controller { // reject socks 4 response = new byte[] { 0, 91 }; - Logging.Error("socks 5 protocol error"); + Logger.Error("socks 5 protocol error"); } _connection.BeginSend(response, 0, response.Length, SocketFlags.None, HandshakeSendCallback, null); @@ -301,7 +305,7 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Logging.LogUsefulException(e); + Logger.LogUsefulException(e); Close(); } } @@ -326,7 +330,7 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Logging.LogUsefulException(e); + Logger.LogUsefulException(e); Close(); } } @@ -358,21 +362,21 @@ namespace Shadowsocks.Controller break; case CMD_BIND: // not implemented default: - Logging.Debug("Unsupported CMD=" + _command); + Logger.Debug("Unsupported CMD=" + _command); Close(); break; } } else { - Logging.Debug( + Logger.Debug( "failed to recv data in Shadowsocks.Controller.TCPHandler.handshakeReceive2Callback()"); Close(); } } catch (Exception e) { - Logging.LogUsefulException(e); + Logger.LogUsefulException(e); Close(); } } @@ -387,7 +391,7 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Logging.LogUsefulException(e); + Logger.LogUsefulException(e); Close(); } } @@ -409,7 +413,7 @@ namespace Shadowsocks.Controller ReadAddress(16 + ADDR_PORT_LEN - 1, onSuccess); break; default: - Logging.Debug("Unsupported ATYP=" + atyp); + Logger.Debug("Unsupported ATYP=" + atyp); Close(); break; } @@ -470,7 +474,7 @@ namespace Shadowsocks.Controller if (_config.isVerboseLogging) { - Logging.Info($"connect to {dstAddr}:{dstPort}"); + Logger.Info($"connect to {dstAddr}:{dstPort}"); } _destEndPoint = SocketUtil.GetEndPoint(dstAddr, dstPort); @@ -479,13 +483,13 @@ namespace Shadowsocks.Controller } else { - Logging.Debug("failed to recv data in Shadowsocks.Controller.TCPHandler.OnAddressFullyRead()"); + Logger.Debug("failed to recv data in Shadowsocks.Controller.TCPHandler.OnAddressFullyRead()"); Close(); } } catch (Exception e) { - Logging.LogUsefulException(e); + Logger.LogUsefulException(e); Close(); } } @@ -537,7 +541,7 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Logging.LogUsefulException(e); + Logger.LogUsefulException(e); Close(); } } @@ -631,7 +635,7 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Logging.LogUsefulException(e); + Logger.LogUsefulException(e); Close(); } } @@ -650,7 +654,7 @@ namespace Shadowsocks.Controller } var proxy = timer.Session.Remote; - Logging.Info($"Proxy {proxy.ProxyEndPoint} timed out"); + Logger.Info($"Proxy {proxy.ProxyEndPoint} timed out"); proxy.Close(); Close(); } @@ -682,7 +686,7 @@ namespace Shadowsocks.Controller { if (!(remote is DirectConnect)) { - Logging.Info($"Socket connected to proxy {remote.ProxyEndPoint}"); + Logger.Info($"Socket connected to proxy {remote.ProxyEndPoint}"); } } @@ -710,7 +714,7 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Logging.LogUsefulException(e); + Logger.LogUsefulException(e); Close(); } } @@ -731,7 +735,7 @@ namespace Shadowsocks.Controller Server server = timer.Server; IStrategy strategy = _controller.GetCurrentStrategy(); strategy?.SetFailure(server); - Logging.Info($"{server.FriendlyName()} timed out"); + Logger.Info($"{server.FriendlyName()} timed out"); session.Remote.Close(); Close(); } @@ -756,7 +760,7 @@ namespace Shadowsocks.Controller if (_config.isVerboseLogging) { - Logging.Info($"Socket connected to ss server: {_server.FriendlyName()}"); + Logger.Info($"Socket connected to ss server: {_server.FriendlyName()}"); } var latency = DateTime.Now - _startConnectTime; @@ -776,7 +780,7 @@ namespace Shadowsocks.Controller IStrategy strategy = _controller.GetCurrentStrategy(); strategy?.SetFailure(_server); } - Logging.LogUsefulException(e); + Logger.LogUsefulException(e); Close(); } } @@ -803,12 +807,12 @@ namespace Shadowsocks.Controller PipeRemoteReceiveCallback, session); TryReadAvailableData(); - Logging.Debug($"_firstPacketLength = {_firstPacketLength}"); + Logger.Debug($"_firstPacketLength = {_firstPacketLength}"); SendToServer(_firstPacketLength, session); } catch (Exception e) { - Logging.LogUsefulException(e); + Logger.LogUsefulException(e); Close(); } } @@ -834,7 +838,7 @@ namespace Shadowsocks.Controller } catch (CryptoErrorException) { - Logging.Error("decryption error"); + Logger.Error("decryption error"); Close(); return; } @@ -842,12 +846,12 @@ namespace Shadowsocks.Controller if (bytesToSend == 0) { // need more to decrypt - Logging.Debug("Need more to decrypt"); + Logger.Debug("Need more to decrypt"); session.Remote.BeginReceive(_remoteRecvBuffer, 0, RecvSize, SocketFlags.None, PipeRemoteReceiveCallback, session); return; } - Logging.Debug($"start sending {bytesToSend}"); + Logger.Debug($"start sending {bytesToSend}"); _connection.BeginSend(_remoteSendBuffer, 0, bytesToSend, SocketFlags.None, PipeConnectionSendCallback, new object[] { session, bytesToSend }); IStrategy strategy = _controller.GetCurrentStrategy(); @@ -862,7 +866,7 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Logging.LogUsefulException(e); + Logger.LogUsefulException(e); Close(); } } @@ -890,7 +894,7 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Logging.LogUsefulException(e); + Logger.LogUsefulException(e); Close(); } } @@ -907,7 +911,7 @@ namespace Shadowsocks.Controller } catch (CryptoErrorException) { - Logging.Debug("encryption error"); + Logger.Debug("encryption error"); Close(); return; } @@ -932,7 +936,7 @@ namespace Shadowsocks.Controller int bytesRemaining = bytesShouldSend - bytesSent; if (bytesRemaining > 0) { - Logging.Info("reconstruct _connetionSendBuffer to re-send"); + Logger.Info("reconstruct _connetionSendBuffer to re-send"); Buffer.BlockCopy(_connetionSendBuffer, bytesSent, _connetionSendBuffer, 0, bytesRemaining); session.Remote.BeginSend(_connetionSendBuffer, 0, bytesRemaining, SocketFlags.None, PipeRemoteSendCallback, new object[] { session, bytesRemaining }); @@ -943,7 +947,7 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Logging.LogUsefulException(e); + Logger.LogUsefulException(e); Close(); } } @@ -960,7 +964,7 @@ namespace Shadowsocks.Controller var bytesRemaining = bytesShouldSend - bytesSent; if (bytesRemaining > 0) { - Logging.Info("reconstruct _remoteSendBuffer to re-send"); + Logger.Info("reconstruct _remoteSendBuffer to re-send"); Buffer.BlockCopy(_remoteSendBuffer, bytesSent, _remoteSendBuffer, 0, bytesRemaining); _connection.BeginSend(_remoteSendBuffer, 0, bytesRemaining, SocketFlags.None, PipeConnectionSendCallback, new object[] { session, bytesRemaining }); @@ -971,7 +975,7 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Logging.LogUsefulException(e); + Logger.LogUsefulException(e); Close(); } } diff --git a/shadowsocks-csharp/Controller/Service/UDPRelay.cs b/shadowsocks-csharp/Controller/Service/UDPRelay.cs index 5ac03839..568e1f75 100644 --- a/shadowsocks-csharp/Controller/Service/UDPRelay.cs +++ b/shadowsocks-csharp/Controller/Service/UDPRelay.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.Runtime.CompilerServices; +using NLog; using Shadowsocks.Controller.Strategy; using Shadowsocks.Encryption; using Shadowsocks.Model; @@ -49,6 +50,8 @@ namespace Shadowsocks.Controller public class UDPHandler { + private static Logger logger = LogManager.GetCurrentClassLogger(); + private Socket _local; private Socket _remote; @@ -98,14 +101,14 @@ namespace Shadowsocks.Controller byte[] dataOut = new byte[65536]; // enough space for AEAD ciphers int outlen; encryptor.EncryptUDP(dataIn, length - 3, dataOut, out outlen); - Logging.Debug(_localEndPoint, _remoteEndPoint, outlen, "UDP Relay"); + logger.Debug(_localEndPoint, _remoteEndPoint, outlen, "UDP Relay"); _remote?.SendTo(dataOut, outlen, SocketFlags.None, _remoteEndPoint); } public void Receive() { EndPoint remoteEndPoint = new IPEndPoint(GetIPAddress(), 0); - Logging.Debug($"++++++Receive Server Port, size:" + _buffer.Length); + logger.Debug($"++++++Receive Server Port, size:" + _buffer.Length); _remote?.BeginReceiveFrom(_buffer, 0, _buffer.Length, 0, ref remoteEndPoint, new AsyncCallback(RecvFromCallback), null); } @@ -126,7 +129,7 @@ namespace Shadowsocks.Controller byte[] sendBuf = new byte[outlen + 3]; Array.Copy(dataOut, 0, sendBuf, 3, outlen); - Logging.Debug(_localEndPoint, _remoteEndPoint, outlen, "UDP Relay"); + logger.Debug(_localEndPoint, _remoteEndPoint, outlen, "UDP Relay"); _local?.SendTo(sendBuf, outlen + 3, 0, _localEndPoint); Receive(); diff --git a/shadowsocks-csharp/Controller/Service/UpdateChecker.cs b/shadowsocks-csharp/Controller/Service/UpdateChecker.cs index cce193f1..fb1aa331 100644 --- a/shadowsocks-csharp/Controller/Service/UpdateChecker.cs +++ b/shadowsocks-csharp/Controller/Service/UpdateChecker.cs @@ -4,7 +4,7 @@ using System.Net; using System.Text.RegularExpressions; using Newtonsoft.Json.Linq; - +using NLog; using Shadowsocks.Model; using Shadowsocks.Util; @@ -12,6 +12,8 @@ namespace Shadowsocks.Controller { public class UpdateChecker { + private static Logger logger = LogManager.GetCurrentClassLogger(); + private const string UpdateURL = "https://api.github.com/repos/shadowsocks/shadowsocks-windows/releases"; private const string UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"; @@ -60,14 +62,14 @@ namespace Shadowsocks.Controller try { - Logging.Debug("Checking updates..."); + logger.Debug("Checking updates..."); WebClient http = CreateWebClient(); http.DownloadStringCompleted += http_DownloadStringCompleted; http.DownloadStringAsync(new Uri(UpdateURL)); } catch (Exception ex) { - Logging.LogUsefulException(ex); + logger.LogUsefulException(ex); } } @@ -117,7 +119,7 @@ namespace Shadowsocks.Controller } else { - Logging.Debug("No update is available"); + logger.Debug("No update is available"); if (CheckUpdateCompleted != null) { CheckUpdateCompleted(this, new EventArgs()); @@ -126,7 +128,7 @@ namespace Shadowsocks.Controller } catch (Exception ex) { - Logging.LogUsefulException(ex); + logger.LogUsefulException(ex); } } @@ -141,7 +143,7 @@ namespace Shadowsocks.Controller } catch (Exception ex) { - Logging.LogUsefulException(ex); + logger.LogUsefulException(ex); } } @@ -151,10 +153,10 @@ namespace Shadowsocks.Controller { if (e.Error != null) { - Logging.LogUsefulException(e.Error); + logger.LogUsefulException(e.Error); return; } - Logging.Debug($"New version {LatestVersionNumber}{LatestVersionSuffix} found: {LatestVersionLocalName}"); + logger.Debug($"New version {LatestVersionNumber}{LatestVersionSuffix} found: {LatestVersionLocalName}"); if (CheckUpdateCompleted != null) { CheckUpdateCompleted(this, new EventArgs()); @@ -162,7 +164,7 @@ namespace Shadowsocks.Controller } catch (Exception ex) { - Logging.LogUsefulException(ex); + logger.LogUsefulException(ex); } } diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs index 4faf95d4..c17dbea8 100644 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs @@ -9,7 +9,7 @@ using System.Text; using System.Threading; using System.Web; using System.Windows.Forms; - +using NLog; using Shadowsocks.Controller.Service; using Shadowsocks.Controller.Strategy; using Shadowsocks.Model; @@ -19,6 +19,8 @@ namespace Shadowsocks.Controller { public class ShadowsocksController { + private static Logger logger = LogManager.GetCurrentClassLogger(); + // controller: // handle user actions // manipulates UI @@ -165,13 +167,13 @@ namespace Shadowsocks.Controller { if (plugin.StartIfNeeded()) { - Logging.Info( + logger.Info( $"Started SIP003 plugin for {server.Identifier()} on {plugin.LocalEndPoint} - PID: {plugin.ProcessId}"); } } catch (Exception ex) { - Logging.Error("Failed to start SIP003 plugin: " + ex.Message); + logger.Error("Failed to start SIP003 plugin: " + ex.Message); throw; } @@ -213,7 +215,7 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Logging.LogUsefulException(e); + logger.LogUsefulException(e); return false; } } @@ -533,7 +535,7 @@ namespace Shadowsocks.Controller e = new Exception(I18N.GetString("Port {0} is reserved by system", _config.localPort), e); } } - Logging.LogUsefulException(e); + logger.LogUsefulException(e); ReportError(e); } diff --git a/shadowsocks-csharp/Controller/Strategy/HighAvailabilityStrategy.cs b/shadowsocks-csharp/Controller/Strategy/HighAvailabilityStrategy.cs index 9804fad2..61356543 100644 --- a/shadowsocks-csharp/Controller/Strategy/HighAvailabilityStrategy.cs +++ b/shadowsocks-csharp/Controller/Strategy/HighAvailabilityStrategy.cs @@ -1,4 +1,5 @@ -using Shadowsocks.Model; +using NLog; +using Shadowsocks.Model; using System; using System.Collections.Generic; using System.Net; @@ -8,6 +9,8 @@ namespace Shadowsocks.Controller.Strategy { class HighAvailabilityStrategy : IStrategy { + private static Logger logger = LogManager.GetCurrentClassLogger(); + protected ServerStatus _currentServer; protected Dictionary _serverStatus; ShadowsocksController _controller; @@ -111,7 +114,7 @@ namespace Shadowsocks.Controller.Strategy 100 * 1000 * Math.Min(5 * 60, (now - status.lastFailure).TotalSeconds) -2 * 5 * (Math.Min(2000, status.latency.TotalMilliseconds) / (1 + (now - status.lastTimeDetectLatency).TotalSeconds / 30 / 10) + -0.5 * 200 * Math.Min(5, (status.lastRead - status.lastWrite).TotalSeconds)); - Logging.Debug(String.Format("server: {0} latency:{1} score: {2}", status.server.FriendlyName(), status.latency, status.score)); + logger.Debug(String.Format("server: {0} latency:{1} score: {2}", status.server.FriendlyName(), status.latency, status.score)); } ServerStatus max = null; foreach (var status in servers) @@ -133,14 +136,14 @@ namespace Shadowsocks.Controller.Strategy if (_currentServer == null || max.score - _currentServer.score > 200) { _currentServer = max; - Logging.Info($"HA switching to server: {_currentServer.server.FriendlyName()}"); + logger.Info($"HA switching to server: {_currentServer.server.FriendlyName()}"); } } } public void UpdateLatency(Model.Server server, TimeSpan latency) { - Logging.Debug($"latency: {server.FriendlyName()} {latency}"); + logger.Debug($"latency: {server.FriendlyName()} {latency}"); ServerStatus status; if (_serverStatus.TryGetValue(server, out status)) @@ -152,7 +155,7 @@ namespace Shadowsocks.Controller.Strategy public void UpdateLastRead(Model.Server server) { - Logging.Debug($"last read: {server.FriendlyName()}"); + logger.Debug($"last read: {server.FriendlyName()}"); ServerStatus status; if (_serverStatus.TryGetValue(server, out status)) @@ -163,7 +166,7 @@ namespace Shadowsocks.Controller.Strategy public void UpdateLastWrite(Model.Server server) { - Logging.Debug($"last write: {server.FriendlyName()}"); + logger.Debug($"last write: {server.FriendlyName()}"); ServerStatus status; if (_serverStatus.TryGetValue(server, out status)) @@ -174,7 +177,7 @@ namespace Shadowsocks.Controller.Strategy public void SetFailure(Model.Server server) { - Logging.Debug($"failure: {server.FriendlyName()}"); + logger.Debug($"failure: {server.FriendlyName()}"); ServerStatus status; if (_serverStatus.TryGetValue(server, out status)) diff --git a/shadowsocks-csharp/Controller/Strategy/StatisticsStrategy.cs b/shadowsocks-csharp/Controller/Strategy/StatisticsStrategy.cs index d965a083..57f37989 100644 --- a/shadowsocks-csharp/Controller/Strategy/StatisticsStrategy.cs +++ b/shadowsocks-csharp/Controller/Strategy/StatisticsStrategy.cs @@ -5,7 +5,7 @@ using System.Net; using System.Threading; using Newtonsoft.Json; - +using NLog; using Shadowsocks.Model; namespace Shadowsocks.Controller.Strategy @@ -14,6 +14,8 @@ namespace Shadowsocks.Controller.Strategy internal class StatisticsStrategy : IStrategy, IDisposable { + private static Logger logger = LogManager.GetCurrentClassLogger(); + private readonly ShadowsocksController _controller; private Server _currentServer; private readonly Timer _timer; @@ -34,7 +36,7 @@ namespace Shadowsocks.Controller.Strategy private void ReloadStatisticsAndChooseAServer(object obj) { - Logging.Debug("Reloading statistics and choose a new server...."); + logger.Debug("Reloading statistics and choose a new server...."); var servers = _controller.GetCurrentConfiguration().configs; LoadStatistics(); ChooseNewServer(servers); @@ -74,7 +76,7 @@ namespace Shadowsocks.Controller.Strategy if (score != null) { - Logging.Debug($"Highest score: {score} {JsonConvert.SerializeObject(averageRecord, Formatting.Indented)}"); + logger.Debug($"Highest score: {score} {JsonConvert.SerializeObject(averageRecord, Formatting.Indented)}"); } return score; } @@ -112,7 +114,7 @@ namespace Shadowsocks.Controller.Strategy } catch (Exception e) { - Logging.LogUsefulException(e); + logger.LogUsefulException(e); } } @@ -145,7 +147,7 @@ namespace Shadowsocks.Controller.Strategy public void SetFailure(Server server) { - Logging.Debug($"failure: {server.FriendlyName()}"); + logger.Debug($"failure: {server.FriendlyName()}"); } public void UpdateLastRead(Server server) diff --git a/shadowsocks-csharp/Controller/System/AutoStartup.cs b/shadowsocks-csharp/Controller/System/AutoStartup.cs index 310a3c71..c1d207e0 100644 --- a/shadowsocks-csharp/Controller/System/AutoStartup.cs +++ b/shadowsocks-csharp/Controller/System/AutoStartup.cs @@ -5,12 +5,15 @@ using System.Reflection; using System.Runtime.InteropServices; using System.Windows.Forms; using Microsoft.Win32; +using NLog; using Shadowsocks.Util; namespace Shadowsocks.Controller { static class AutoStartup { + private static Logger logger = LogManager.GetCurrentClassLogger(); + // Don't use Application.ExecutablePath // see https://stackoverflow.com/questions/12945805/odd-c-sharp-path-issue private static readonly string ExecutablePath = Assembly.GetEntryAssembly().Location; @@ -25,7 +28,7 @@ namespace Shadowsocks.Controller runKey = Utils.OpenRegKey(@"Software\Microsoft\Windows\CurrentVersion\Run", true); if (runKey == null) { - Logging.Error(@"Cannot find HKCU\Software\Microsoft\Windows\CurrentVersion\Run"); + logger.Error(@"Cannot find HKCU\Software\Microsoft\Windows\CurrentVersion\Run"); return false; } if (enabled) @@ -42,7 +45,7 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Logging.LogUsefulException(e); + logger.LogUsefulException(e); return false; } finally @@ -55,7 +58,7 @@ namespace Shadowsocks.Controller runKey.Dispose(); } catch (Exception e) - { Logging.LogUsefulException(e); } + { logger.LogUsefulException(e); } } } } @@ -68,7 +71,7 @@ namespace Shadowsocks.Controller runKey = Utils.OpenRegKey(@"Software\Microsoft\Windows\CurrentVersion\Run", true); if (runKey == null) { - Logging.Error(@"Cannot find HKCU\Software\Microsoft\Windows\CurrentVersion\Run"); + logger.Error(@"Cannot find HKCU\Software\Microsoft\Windows\CurrentVersion\Run"); return false; } string[] runList = runKey.GetValueNames(); @@ -91,7 +94,7 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Logging.LogUsefulException(e); + logger.LogUsefulException(e); return false; } finally @@ -104,7 +107,7 @@ namespace Shadowsocks.Controller runKey.Dispose(); } catch (Exception e) - { Logging.LogUsefulException(e); } + { logger.LogUsefulException(e); } } } } @@ -140,13 +143,13 @@ namespace Shadowsocks.Controller // first parameter is process command line parameter // needn't include the name of the executable in the command line RegisterApplicationRestart(cmdline, (int)(ApplicationRestartFlags.RESTART_NO_CRASH | ApplicationRestartFlags.RESTART_NO_HANG)); - Logging.Debug("Register restart after system reboot, command line:" + cmdline); + logger.Debug("Register restart after system reboot, command line:" + cmdline); } // requested unregister, which has no side effect else if (!register) { UnregisterApplicationRestart(); - Logging.Debug("Unregister restart after system reboot"); + logger.Debug("Unregister restart after system reboot"); } } } diff --git a/shadowsocks-csharp/Controller/System/SystemProxy.cs b/shadowsocks-csharp/Controller/System/SystemProxy.cs index fa7d6853..1d61dd86 100644 --- a/shadowsocks-csharp/Controller/System/SystemProxy.cs +++ b/shadowsocks-csharp/Controller/System/SystemProxy.cs @@ -1,5 +1,6 @@ using System; using System.Windows.Forms; +using NLog; using Shadowsocks.Model; using Shadowsocks.Util.SystemProxy; @@ -7,6 +8,8 @@ namespace Shadowsocks.Controller { public static class SystemProxy { + private static Logger logger = LogManager.GetCurrentClassLogger(); + private static string GetTimestamp(DateTime value) { return value.ToString("yyyyMMddHHmmssfff"); @@ -52,7 +55,7 @@ namespace Shadowsocks.Controller } catch (ProxyException ex) { - Logging.LogUsefulException(ex); + logger.LogUsefulException(ex); if (ex.Type != ProxyExceptionType.Unspecific && !noRetry) { var ret = MessageBox.Show(I18N.GetString("Error occured when process proxy setting, do you want reset current setting and retry?"), I18N.GetString("Shadowsocks"), MessageBoxButtons.YesNo, MessageBoxIcon.Warning); diff --git a/shadowsocks-csharp/Data/NLog.config b/shadowsocks-csharp/Data/NLog.config new file mode 100644 index 00000000..4b779775 --- /dev/null +++ b/shadowsocks-csharp/Data/NLog.config @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/shadowsocks-csharp/Encryption/AEAD/AEADEncryptor.cs b/shadowsocks-csharp/Encryption/AEAD/AEADEncryptor.cs index a4e42eae..2acd54bd 100644 --- a/shadowsocks-csharp/Encryption/AEAD/AEADEncryptor.cs +++ b/shadowsocks-csharp/Encryption/AEAD/AEADEncryptor.cs @@ -1,4 +1,5 @@ -using System; +using NLog; +using System; using System.Collections.Generic; using System.Diagnostics; using System.Net; @@ -13,6 +14,7 @@ namespace Shadowsocks.Encryption.AEAD public abstract class AEADEncryptor : EncryptorBase { + private static Logger logger = LogManager.GetCurrentClassLogger(); // We are using the same saltLen and keyLen private const string Info = "ss-subkey"; private static readonly byte[] InfoBytes = Encoding.ASCII.GetBytes(Info); @@ -122,7 +124,7 @@ namespace Shadowsocks.Encryption.AEAD _decryptSalt = new byte[saltLen]; Array.Copy(salt, _decryptSalt, saltLen); } - Logging.Dump("Salt", salt, saltLen); + logger.Dump("Salt", salt, saltLen); } public static void randBytes(byte[] buf, int length) { RNG.GetBytes(buf, length); } @@ -139,7 +141,7 @@ namespace Shadowsocks.Encryption.AEAD _encCircularBuffer.Put(buf, 0, length); outlength = 0; - Logging.Debug("---Start Encryption"); + logger.Debug("---Start Encryption"); if (! _encryptSaltSent) { _encryptSaltSent = true; // Generate salt @@ -148,7 +150,7 @@ namespace Shadowsocks.Encryption.AEAD InitCipher(saltBytes, true, false); Array.Copy(saltBytes, 0, outbuf, 0, saltLen); outlength = saltLen; - Logging.Debug($"_encryptSaltSent outlength {outlength}"); + logger.Debug($"_encryptSaltSent outlength {outlength}"); } if (! _tcpRequestSent) { @@ -161,7 +163,7 @@ namespace Shadowsocks.Encryption.AEAD Debug.Assert(encAddrBufLength == AddrBufLength + tagLen * 2 + CHUNK_LEN_BYTES); Array.Copy(encAddrBufBytes, 0, outbuf, outlength, encAddrBufLength); outlength += encAddrBufLength; - Logging.Debug($"_tcpRequestSent outlength {outlength}"); + logger.Debug($"_tcpRequestSent outlength {outlength}"); } // handle other chunks @@ -176,15 +178,15 @@ namespace Shadowsocks.Encryption.AEAD Debug.Assert(encChunkLength == chunklength + tagLen * 2 + CHUNK_LEN_BYTES); Buffer.BlockCopy(encChunkBytes, 0, outbuf, outlength, encChunkLength); outlength += encChunkLength; - Logging.Debug("chunks enc outlength " + outlength); + logger.Debug("chunks enc outlength " + outlength); // check if we have enough space for outbuf if (outlength + TCPHandler.ChunkOverheadSize > TCPHandler.BufferSize) { - Logging.Debug("enc outbuf almost full, giving up"); + logger.Debug("enc outbuf almost full, giving up"); return; } bufSize = (uint)_encCircularBuffer.Size; if (bufSize <= 0) { - Logging.Debug("No more data to encrypt, leaving"); + logger.Debug("No more data to encrypt, leaving"); return; } } @@ -199,7 +201,7 @@ namespace Shadowsocks.Encryption.AEAD // drop all into buffer _decCircularBuffer.Put(buf, 0, length); - Logging.Debug("---Start Decryption"); + logger.Debug("---Start Decryption"); if (! _decryptSaltReceived) { bufSize = _decCircularBuffer.Size; // check if we get the leading salt @@ -210,7 +212,7 @@ namespace Shadowsocks.Encryption.AEAD _decryptSaltReceived = true; byte[] salt = _decCircularBuffer.Get(saltLen); InitCipher(salt, false, false); - Logging.Debug("get salt len " + saltLen); + logger.Debug("get salt len " + saltLen); } // handle chunks @@ -218,7 +220,7 @@ namespace Shadowsocks.Encryption.AEAD bufSize = _decCircularBuffer.Size; // check if we have any data if (bufSize <= 0) { - Logging.Debug("No data in _decCircularBuffer"); + logger.Debug("No data in _decCircularBuffer"); return; } @@ -241,13 +243,13 @@ namespace Shadowsocks.Encryption.AEAD if (chunkLen > CHUNK_LEN_MASK) { // we get invalid chunk - Logging.Error($"Invalid chunk length: {chunkLen}"); + logger.Error($"Invalid chunk length: {chunkLen}"); throw new CryptoErrorException(); } - Logging.Debug("Get the real chunk len:" + chunkLen); + logger.Debug("Get the real chunk len:" + chunkLen); bufSize = _decCircularBuffer.Size; if (bufSize < CHUNK_LEN_BYTES + tagLen /* we haven't remove them */+ chunkLen + tagLen) { - Logging.Debug("No more data to decrypt one chunk"); + logger.Debug("No more data to decrypt one chunk"); return; } IncrementNonce(false); @@ -267,16 +269,16 @@ namespace Shadowsocks.Encryption.AEAD // output to outbuf Buffer.BlockCopy(decChunkBytes, 0, outbuf, outlength, (int) decChunkLen); outlength += (int)decChunkLen; - Logging.Debug("aead dec outlength " + outlength); + logger.Debug("aead dec outlength " + outlength); if (outlength + 100 > TCPHandler.BufferSize) { - Logging.Debug("dec outbuf almost full, giving up"); + logger.Debug("dec outbuf almost full, giving up"); return; } bufSize = _decCircularBuffer.Size; // check if we already done all of them if (bufSize <= 0) { - Logging.Debug("No data in _decCircularBuffer, already all done"); + logger.Debug("No data in _decCircularBuffer, already all done"); return; } } @@ -319,7 +321,7 @@ namespace Shadowsocks.Encryption.AEAD private void ChunkEncrypt(byte[] plaintext, int plainLen, byte[] ciphertext, out int cipherLen) { if (plainLen > CHUNK_LEN_MASK) { - Logging.Error("enc chunk too big"); + logger.Error("enc chunk too big"); throw new CryptoErrorException(); } diff --git a/shadowsocks-csharp/Encryption/AEAD/AEADSodiumEncryptor.cs b/shadowsocks-csharp/Encryption/AEAD/AEADSodiumEncryptor.cs index 2aa2856f..06aef5d7 100644 --- a/shadowsocks-csharp/Encryption/AEAD/AEADSodiumEncryptor.cs +++ b/shadowsocks-csharp/Encryption/AEAD/AEADSodiumEncryptor.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using NLog; using Shadowsocks.Controller; using Shadowsocks.Encryption.Exception; @@ -9,6 +10,8 @@ namespace Shadowsocks.Encryption.AEAD public class AEADSodiumEncryptor : AEADEncryptor, IDisposable { + private static Logger logger = LogManager.GetCurrentClassLogger(); + private const int CIPHER_CHACHA20IETFPOLY1305 = 1; private const int CIPHER_XCHACHA20IETFPOLY1305 = 2; private const int CIPHER_AES256GCM = 3; @@ -55,9 +58,9 @@ namespace Shadowsocks.Encryption.AEAD // outbuf: ciphertext + tag int ret; ulong encClen = 0; - Logging.Dump("_encNonce before enc", _encNonce, nonceLen); - Logging.Dump("_sodiumEncSubkey", _sodiumEncSubkey, keyLen); - Logging.Dump("before cipherEncrypt: plain", plaintext, (int) plen); + logger.Dump("_encNonce before enc", _encNonce, nonceLen); + logger.Dump("_sodiumEncSubkey", _sodiumEncSubkey, keyLen); + logger.Dump("before cipherEncrypt: plain", plaintext, (int) plen); switch (_cipher) { case CIPHER_CHACHA20IETFPOLY1305: @@ -85,7 +88,7 @@ namespace Shadowsocks.Encryption.AEAD throw new System.Exception("not implemented"); } if (ret != 0) throw new CryptoErrorException(String.Format("ret is {0}", ret)); - Logging.Dump("after cipherEncrypt: cipher", ciphertext, (int) encClen); + logger.Dump("after cipherEncrypt: cipher", ciphertext, (int) encClen); clen = (uint) encClen; } @@ -96,9 +99,9 @@ namespace Shadowsocks.Encryption.AEAD // outbuf: plaintext int ret; ulong decPlen = 0; - Logging.Dump("_decNonce before dec", _decNonce, nonceLen); - Logging.Dump("_sodiumDecSubkey", _sodiumDecSubkey, keyLen); - Logging.Dump("before cipherDecrypt: cipher", ciphertext, (int) clen); + logger.Dump("_decNonce before dec", _decNonce, nonceLen); + logger.Dump("_sodiumDecSubkey", _sodiumDecSubkey, keyLen); + logger.Dump("before cipherDecrypt: cipher", ciphertext, (int) clen); switch (_cipher) { case CIPHER_CHACHA20IETFPOLY1305: @@ -127,7 +130,7 @@ namespace Shadowsocks.Encryption.AEAD } if (ret != 0) throw new CryptoErrorException(String.Format("ret is {0}", ret)); - Logging.Dump("after cipherDecrypt: plain", plaintext, (int) decPlen); + logger.Dump("after cipherDecrypt: plain", plaintext, (int) decPlen); plen = (uint) decPlen; } diff --git a/shadowsocks-csharp/Encryption/MbedTLS.cs b/shadowsocks-csharp/Encryption/MbedTLS.cs index 4e0b76d8..be681670 100644 --- a/shadowsocks-csharp/Encryption/MbedTLS.cs +++ b/shadowsocks-csharp/Encryption/MbedTLS.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Runtime.InteropServices; +using NLog; using Shadowsocks.Controller; using Shadowsocks.Properties; using Shadowsocks.Util; @@ -9,6 +10,8 @@ namespace Shadowsocks.Encryption { public static class MbedTLS { + private static Logger logger = LogManager.GetCurrentClassLogger(); + private const string DLLNAME = "libsscrypto.dll"; public const int MBEDTLS_ENCRYPT = 1; @@ -26,7 +29,7 @@ namespace Shadowsocks.Encryption } catch (System.Exception e) { - Logging.LogUsefulException(e); + logger.LogUsefulException(e); } LoadLibrary(dllPath); } diff --git a/shadowsocks-csharp/Encryption/OpenSSL.cs b/shadowsocks-csharp/Encryption/OpenSSL.cs index c88404ed..00056a04 100644 --- a/shadowsocks-csharp/Encryption/OpenSSL.cs +++ b/shadowsocks-csharp/Encryption/OpenSSL.cs @@ -3,6 +3,7 @@ using System.IO; using System.Runtime.InteropServices; using System.Security; using System.Text; +using NLog; using Shadowsocks.Controller; using Shadowsocks.Encryption.Exception; using Shadowsocks.Properties; @@ -13,6 +14,8 @@ namespace Shadowsocks.Encryption // XXX: only for OpenSSL 1.1.0 and higher public static class OpenSSL { + private static Logger logger = LogManager.GetCurrentClassLogger(); + private const string DLLNAME = "libsscrypto.dll"; public const int OPENSSL_ENCRYPT = 1; @@ -34,7 +37,7 @@ namespace Shadowsocks.Encryption } catch (System.Exception e) { - Logging.LogUsefulException(e); + logger.LogUsefulException(e); } LoadLibrary(dllPath); } diff --git a/shadowsocks-csharp/Encryption/Sodium.cs b/shadowsocks-csharp/Encryption/Sodium.cs index 66b1abbe..6b9441dd 100755 --- a/shadowsocks-csharp/Encryption/Sodium.cs +++ b/shadowsocks-csharp/Encryption/Sodium.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Runtime.InteropServices; +using NLog; using Shadowsocks.Controller; using Shadowsocks.Properties; using Shadowsocks.Util; @@ -9,6 +10,8 @@ namespace Shadowsocks.Encryption { public static class Sodium { + private static Logger logger = LogManager.GetCurrentClassLogger(); + private const string DLLNAME = "libsscrypto.dll"; private static bool _initialized = false; @@ -28,7 +31,7 @@ namespace Shadowsocks.Encryption } catch (System.Exception e) { - Logging.LogUsefulException(e); + logger.LogUsefulException(e); } LoadLibrary(dllPath); @@ -46,7 +49,7 @@ namespace Shadowsocks.Encryption } AES256GCMAvailable = crypto_aead_aes256gcm_is_available() == 1; - Logging.Debug($"sodium: AES256GCMAvailable is {AES256GCMAvailable}"); + logger.Debug($"sodium: AES256GCMAvailable is {AES256GCMAvailable}"); } } } diff --git a/shadowsocks-csharp/Model/Configuration.cs b/shadowsocks-csharp/Model/Configuration.cs index e8aad2d5..f2f54b08 100644 --- a/shadowsocks-csharp/Model/Configuration.cs +++ b/shadowsocks-csharp/Model/Configuration.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO; using Newtonsoft.Json; +using NLog; using Shadowsocks.Controller; namespace Shadowsocks.Model @@ -9,6 +10,9 @@ namespace Shadowsocks.Model [Serializable] public class Configuration { + [JsonIgnore] + private static Logger logger = LogManager.GetCurrentClassLogger(); + public string version; public List configs; @@ -105,7 +109,7 @@ namespace Shadowsocks.Model catch (Exception e) { if (!(e is FileNotFoundException)) - Logging.LogUsefulException(e); + logger.LogUsefulException(e); return new Configuration { index = 0, @@ -144,7 +148,7 @@ namespace Shadowsocks.Model } catch (IOException e) { - Logging.LogUsefulException(e); + logger.LogUsefulException(e); } } diff --git a/shadowsocks-csharp/Model/StatisticsStrategyConfiguration.cs b/shadowsocks-csharp/Model/StatisticsStrategyConfiguration.cs index c648027d..e0f3bf2d 100644 --- a/shadowsocks-csharp/Model/StatisticsStrategyConfiguration.cs +++ b/shadowsocks-csharp/Model/StatisticsStrategyConfiguration.cs @@ -5,7 +5,7 @@ using System.Linq; using System.Reflection; using Newtonsoft.Json; - +using NLog; using Shadowsocks.Controller; namespace Shadowsocks.Model @@ -13,6 +13,8 @@ namespace Shadowsocks.Model [Serializable] public class StatisticsStrategyConfiguration { + private static Logger logger = LogManager.GetCurrentClassLogger(); + public static readonly string ID = "com.shadowsocks.strategy.statistics"; public bool StatisticsEnabled { get; set; } = false; public bool ByHourOfDay { get; set; } = true; @@ -39,7 +41,7 @@ namespace Shadowsocks.Model } catch (Exception e) { - Logging.LogUsefulException(e); + logger.LogUsefulException(e); return new StatisticsStrategyConfiguration(); } } @@ -53,7 +55,7 @@ namespace Shadowsocks.Model } catch (Exception e) { - Logging.LogUsefulException(e); + logger.LogUsefulException(e); } } diff --git a/shadowsocks-csharp/Program.cs b/shadowsocks-csharp/Program.cs index 05337551..b85e6ced 100755 --- a/shadowsocks-csharp/Program.cs +++ b/shadowsocks-csharp/Program.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using System.IO; using System.Threading; using System.Windows.Forms; +using NLog; using Microsoft.Win32; using Shadowsocks.Controller; @@ -14,6 +15,7 @@ namespace Shadowsocks { static class Program { + private static Logger logger = LogManager.GetCurrentClassLogger(); public static ShadowsocksController MainController { get; private set; } public static MenuViewController MenuController { get; private set; } public static string[] Args { get; private set; } @@ -24,6 +26,9 @@ namespace Shadowsocks [STAThread] static void Main(string[] args) { + // todo: initialize the NLog configuartion + TouchAndApplyNLogConfig(); + // .NET Framework 4.7.2 on Win7 compatibility System.Net.ServicePointManager.SecurityProtocol |= System.Net.SecurityProtocolType.Tls | System.Net.SecurityProtocolType.Tls11 | System.Net.SecurityProtocolType.Tls12; @@ -79,14 +84,10 @@ namespace Shadowsocks } Directory.SetCurrentDirectory(Application.StartupPath); #if DEBUG - Logging.OpenLogFile(); - // truncate privoxy log file while debugging string privoxyLogFilename = Utils.GetTempPath("privoxy.log"); if (File.Exists(privoxyLogFilename)) using (new FileStream(privoxyLogFilename, FileMode.Truncate)) { } -#else - Logging.OpenLogFile(); #endif MainController = new ShadowsocksController(); MenuController = new MenuViewController(MainController); @@ -96,13 +97,23 @@ namespace Shadowsocks } } + private static void TouchAndApplyNLogConfig() + { + string NLogConfigFileName = "NLog.config"; + if (!File.Exists(NLogConfigFileName)) + { + File.WriteAllText(NLogConfigFileName, Properties.Resources.NLog_config); + LogManager.LoadConfiguration(NLogConfigFileName); + } + } + private static int exited = 0; private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { if (Interlocked.Increment(ref exited) == 1) { string errMsg = e.ExceptionObject.ToString(); - Logging.Error(errMsg); + logger.Error(errMsg); MessageBox.Show( $"{I18N.GetString("Unexpected error, shadowsocks will exit. Please report to")} https://github.com/shadowsocks/shadowsocks-windows/issues {Environment.NewLine}{errMsg}", "Shadowsocks non-UI Error", MessageBoxButtons.OK, MessageBoxIcon.Error); @@ -115,7 +126,7 @@ namespace Shadowsocks if (Interlocked.Increment(ref exited) == 1) { string errorMsg = $"Exception Detail: {Environment.NewLine}{e.Exception}"; - Logging.Error(errorMsg); + logger.Error(errorMsg); MessageBox.Show( $"{I18N.GetString("Unexpected error, shadowsocks will exit. Please report to")} https://github.com/shadowsocks/shadowsocks-windows/issues {Environment.NewLine}{errorMsg}", "Shadowsocks UI Error", MessageBoxButtons.OK, MessageBoxIcon.Error); @@ -128,7 +139,7 @@ namespace Shadowsocks switch (e.Mode) { case PowerModes.Resume: - Logging.Info("os wake up"); + logger.Info("os wake up"); if (MainController != null) { System.Threading.Tasks.Task.Factory.StartNew(() => @@ -137,11 +148,11 @@ namespace Shadowsocks try { MainController.Start(false); - Logging.Info("controller started"); + logger.Info("controller started"); } catch (Exception ex) { - Logging.LogUsefulException(ex); + logger.LogUsefulException(ex); } }); } @@ -150,9 +161,9 @@ namespace Shadowsocks if (MainController != null) { MainController.Stop(); - Logging.Info("controller stopped"); + logger.Info("controller stopped"); } - Logging.Info("os suspend"); + logger.Info("os suspend"); break; } } diff --git a/shadowsocks-csharp/Properties/Resources.Designer.cs b/shadowsocks-csharp/Properties/Resources.Designer.cs index dea95e63..bc5b8c24 100644 --- a/shadowsocks-csharp/Properties/Resources.Designer.cs +++ b/shadowsocks-csharp/Properties/Resources.Designer.cs @@ -1,91 +1,91 @@ -//------------------------------------------------------------------------------ -// -// 此代码由工具生成。 -// 运行时版本:4.0.30319.42000 -// -// 对此文件的更改可能会导致不正确的行为,并且如果 -// 重新生成代码,这些更改将会丢失。 -// -//------------------------------------------------------------------------------ - -namespace Shadowsocks.Properties { - using System; - - - /// - /// 一个强类型的资源类,用于查找本地化的字符串等。 - /// - // 此类是由 StronglyTypedResourceBuilder - // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 - // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen - // (以 /str 作为命令选项),或重新生成 VS 项目。 - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { - } - - /// - /// 返回此类使用的缓存的 ResourceManager 实例。 - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Shadowsocks.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// 重写当前线程的 CurrentUICulture 属性 - /// 重写当前线程的 CurrentUICulture 属性。 - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// 查找类似 /* eslint-disable */ - ///// Was generated by gfwlist2pac in precise mode - ///// https://github.com/clowwindy/gfwlist2pac - /// - ///// 2019-10-06: More 'javascript' way to interaction with main program - ///// 2019-02-08: Updated to support shadowsocks-windows user rules. - /// - ///var proxy = __PROXY__; - ///var userrules = __USERRULES__; - ///var rules = __RULES__; - /// - ////* - ///* This file is part of Adblock Plus <http://adblockplus.org/>, - ///* Copyright (C) 2006-2014 Eyeo GmbH - ///* - ///* Adblock Plus is free software: you can redistribute it and/or [字符串的其余部分被截断]"; 的本地化字符串。 - /// - internal static string abp_js { - get { - return ResourceManager.GetString("abp_js", resourceCulture); - } - } - - /// - /// 查找类似 var __USERRULES__ = []; +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Shadowsocks.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Shadowsocks.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to /* eslint-disable */ + ///// Was generated by gfwlist2pac in precise mode + ///// https://github.com/clowwindy/gfwlist2pac + /// + ///// 2019-10-06: More 'javascript' way to interaction with main program + ///// 2019-02-08: Updated to support shadowsocks-windows user rules. + /// + ///var proxy = __PROXY__; + ///var userrules = __USERRULES__; + ///var rules = __RULES__; + /// + ////* + ///* This file is part of Adblock Plus <http://adblockplus.org/>, + ///* Copyright (C) 2006-2014 Eyeo GmbH + ///* + ///* Adblock Plus is free software: you can redistribute it and/or [rest of string was truncated]";. + /// + internal static string abp_js { + get { + return ResourceManager.GetString("abp_js", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to var __USERRULES__ = []; ///var __RULES__ = [ /// "|http://85.17.73.31/", /// "||agnesb.fr", @@ -106,154 +106,175 @@ namespace Shadowsocks.Properties { /// "||beeg.com", /// "||global.bing.com", /// "||bloombergview.com", - /// " [字符串的其余部分被截断]"; 的本地化字符串。 - /// - internal static string default_abp_rule { - get { - return ResourceManager.GetString("default_abp_rule", resourceCulture); - } - } - - /// - /// 查找类似 en,zh-CN,zh-TW,ja + /// "||booktopia.com.au", + /// [rest of string was truncated]";. + /// + internal static string default_abp_rule { + get { + return ResourceManager.GetString("default_abp_rule", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to en,zh-CN,zh-TW,ja + ///#Restart program to apply translation,,, + ///#This is comment line,,, + ///#Always keep language name at head of file,,, + ///#Language name is output in log,,, + ///"#You can find it by search ""Current language is:""",,, + ///#Please use UTF-8 with BOM encoding so we can edit it in Excel,,, ///,,, ///Shadowsocks,Shadowsocks,Shadowsocks,Shadowsocks ///,,, + ///#Menu,,, + ///,,, ///System Proxy,系统代理,系統代理,システムプロキシ ///Disable,禁用,禁用,無効 ///PAC,PAC 模式,PAC 模式,PAC ///Global,全局模式,全局模式,全般 ///Servers,服务器,伺服器,サーバー - ///Edit Servers...,编辑服务器...,編輯伺服器...,サーバーの編集... - ///Statistics Config...,统计配置...,統計設定檔...,統計情報の設定... - ///Start on Boot,开机启动,開機啟動,システムと同時に起動 - ///Forward Proxy...,正向代理设置...,正向 Proxy 設定...,フォワードプロキシの設定... - ///Allow other Devices to connect,允许其他设备连入,允許其他裝置連入,他のデバイスからの接続を許可する - ///Local PAC,使用本地 PAC,使用本機 PAC,ローカル PAC - ///Online PAC,使用在线 PAC,使 [字符串的其余部分被截断]"; 的本地化字符串。 - /// - internal static string i18n_csv { - get { - return ResourceManager.GetString("i18n_csv", resourceCulture); - } - } - - /// - /// 查找 System.Byte[] 类型的本地化资源。 - /// - internal static byte[] libsscrypto_dll { - get { - object obj = ResourceManager.GetObject("libsscrypto_dll", resourceCulture); - return ((byte[])(obj)); - } - } - - /// - /// 查找类似 listen-address __PRIVOXY_BIND_IP__:__PRIVOXY_BIND_PORT__ - ///toggle 0 - ///logfile ss_privoxy.log - ///show-on-task-bar 0 - ///activity-animation 0 - ///forward-socks5 / __SOCKS_HOST__:__SOCKS_PORT__ . - ///max-client-connections 2048 - ///hide-console - /// 的本地化字符串。 - /// - internal static string privoxy_conf { - get { - return ResourceManager.GetString("privoxy_conf", resourceCulture); - } - } - - /// - /// 查找 System.Byte[] 类型的本地化资源。 - /// - internal static byte[] privoxy_exe { - get { - object obj = ResourceManager.GetObject("privoxy_exe", resourceCulture); - return ((byte[])(obj)); - } - } - - /// - /// 查找 System.Drawing.Bitmap 类型的本地化资源。 - /// - internal static System.Drawing.Bitmap ss32Fill { - get { - object obj = ResourceManager.GetObject("ss32Fill", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// 查找 System.Drawing.Bitmap 类型的本地化资源。 - /// - internal static System.Drawing.Bitmap ss32In { - get { - object obj = ResourceManager.GetObject("ss32In", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// 查找 System.Drawing.Bitmap 类型的本地化资源。 - /// - internal static System.Drawing.Bitmap ss32Out { - get { - object obj = ResourceManager.GetObject("ss32Out", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// 查找 System.Drawing.Bitmap 类型的本地化资源。 - /// - internal static System.Drawing.Bitmap ss32Outline { - get { - object obj = ResourceManager.GetObject("ss32Outline", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// 查找 System.Drawing.Bitmap 类型的本地化资源。 - /// - internal static System.Drawing.Bitmap ssw128 { - get { - object obj = ResourceManager.GetObject("ssw128", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// 查找 System.Byte[] 类型的本地化资源。 - /// - internal static byte[] sysproxy_exe { - get { - object obj = ResourceManager.GetObject("sysproxy_exe", resourceCulture); - return ((byte[])(obj)); - } - } - - /// - /// 查找 System.Byte[] 类型的本地化资源。 - /// - internal static byte[] sysproxy64_exe { - get { - object obj = ResourceManager.GetObject("sysproxy64_exe", resourceCulture); - return ((byte[])(obj)); - } - } - - /// - /// 查找类似 ! Put user rules line by line in this file. - ///! See https://adblockplus.org/en/filter-cheatsheet - /// 的本地化字符串。 - /// - internal static string user_rule { - get { - return ResourceManager.GetString("user_rule", resourceCulture); - } - } - } -} + ///Edit Servers...,编辑服务器...,編輯伺服器...,サーバーの編集.. [rest of string was truncated]";. + /// + internal static string i18n_csv { + get { + return ResourceManager.GetString("i18n_csv", resourceCulture); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] libsscrypto_dll { + get { + object obj = ResourceManager.GetObject("libsscrypto_dll", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized string similar to <?xml version="1.0" encoding="utf-8" ?> + ///<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + /// <targets> + /// <target name="file" xsi:type="File" fileName="shadowsocks.log"/> + /// + /// </targets> + /// <rules> + /// <logger name="Name.Space.Class1" minlevel="Debug" writeTo="f1" /> + /// </rules> + ///</nlog>. + /// + internal static string NLog_config { + get { + return ResourceManager.GetString("NLog_config", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to listen-address __PRIVOXY_BIND_IP__:__PRIVOXY_BIND_PORT__ + ///toggle 0 + ///logfile ss_privoxy.log + ///show-on-task-bar 0 + ///activity-animation 0 + ///forward-socks5 / __SOCKS_HOST__:__SOCKS_PORT__ . + ///max-client-connections 2048 + ///hide-console + ///. + /// + internal static string privoxy_conf { + get { + return ResourceManager.GetString("privoxy_conf", resourceCulture); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] privoxy_exe { + get { + object obj = ResourceManager.GetObject("privoxy_exe", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap ss32Fill { + get { + object obj = ResourceManager.GetObject("ss32Fill", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap ss32In { + get { + object obj = ResourceManager.GetObject("ss32In", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap ss32Out { + get { + object obj = ResourceManager.GetObject("ss32Out", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap ss32Outline { + get { + object obj = ResourceManager.GetObject("ss32Outline", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap ssw128 { + get { + object obj = ResourceManager.GetObject("ssw128", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] sysproxy_exe { + get { + object obj = ResourceManager.GetObject("sysproxy_exe", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] sysproxy64_exe { + get { + object obj = ResourceManager.GetObject("sysproxy64_exe", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized string similar to ! Put user rules line by line in this file. + ///! See https://adblockplus.org/en/filter-cheatsheet + ///. + /// + internal static string user_rule { + get { + return ResourceManager.GetString("user_rule", resourceCulture); + } + } + } +} diff --git a/shadowsocks-csharp/Properties/Resources.resx b/shadowsocks-csharp/Properties/Resources.resx index 9661ee9a..99f2c596 100755 --- a/shadowsocks-csharp/Properties/Resources.resx +++ b/shadowsocks-csharp/Properties/Resources.resx @@ -130,6 +130,9 @@ ..\Data\libsscrypto.dll.gz;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + ..\data\nlog.config;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + ..\data\privoxy_conf.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 diff --git a/shadowsocks-csharp/Proxy/HttpProxy.cs b/shadowsocks-csharp/Proxy/HttpProxy.cs index b7d671a6..ecf7dc89 100644 --- a/shadowsocks-csharp/Proxy/HttpProxy.cs +++ b/shadowsocks-csharp/Proxy/HttpProxy.cs @@ -4,6 +4,7 @@ using System.Net.Sockets; using System.Text; using System.Text.RegularExpressions; using System.Threading; +using NLog; using Shadowsocks.Controller; using Shadowsocks.Util.Sockets; @@ -11,6 +12,8 @@ namespace Shadowsocks.Proxy { public class HttpProxy : IProxy { + private static Logger logger = LogManager.GetCurrentClassLogger(); + private class FakeAsyncResult : IAsyncResult { public readonly HttpState innerState; @@ -179,7 +182,7 @@ namespace Shadowsocks.Proxy private bool OnLineRead(string line, object state) { - Logging.Debug(line); + logger.Debug(line); if (_respondLineCount == 0) { diff --git a/shadowsocks-csharp/Util/ProcessManagement/Job.cs b/shadowsocks-csharp/Util/ProcessManagement/Job.cs index dd82134d..bb05dccb 100644 --- a/shadowsocks-csharp/Util/ProcessManagement/Job.cs +++ b/shadowsocks-csharp/Util/ProcessManagement/Job.cs @@ -1,6 +1,7 @@ using System; using System.Diagnostics; using System.Runtime.InteropServices; +using NLog; using Shadowsocks.Controller; namespace Shadowsocks.Util.ProcessManagement @@ -11,6 +12,8 @@ namespace Shadowsocks.Util.ProcessManagement */ public class Job : IDisposable { + private static Logger logger = LogManager.GetCurrentClassLogger(); + private IntPtr handle = IntPtr.Zero; public Job() @@ -54,7 +57,7 @@ namespace Shadowsocks.Util.ProcessManagement if (!succ) { - Logging.Error("Failed to call AssignProcessToJobObject! GetLastError=" + Marshal.GetLastWin32Error()); + logger.Error("Failed to call AssignProcessToJobObject! GetLastError=" + Marshal.GetLastWin32Error()); } return succ; diff --git a/shadowsocks-csharp/Util/SystemProxy/Sysproxy.cs b/shadowsocks-csharp/Util/SystemProxy/Sysproxy.cs index 863be1df..b1ffcac4 100644 --- a/shadowsocks-csharp/Util/SystemProxy/Sysproxy.cs +++ b/shadowsocks-csharp/Util/SystemProxy/Sysproxy.cs @@ -1,4 +1,5 @@ using Newtonsoft.Json; +using NLog; using Shadowsocks.Controller; using Shadowsocks.Model; using Shadowsocks.Properties; @@ -14,6 +15,8 @@ namespace Shadowsocks.Util.SystemProxy { public static class Sysproxy { + private static Logger logger = LogManager.GetCurrentClassLogger(); + private const string _userWininetConfigFile = "user-wininet.json"; private readonly static string[] _lanIP = { @@ -70,7 +73,7 @@ namespace Shadowsocks.Util.SystemProxy } catch (IOException e) { - Logging.LogUsefulException(e); + logger.LogUsefulException(e); } } @@ -233,7 +236,7 @@ namespace Shadowsocks.Util.SystemProxy } catch (IOException e) { - Logging.LogUsefulException(e); + logger.LogUsefulException(e); } } diff --git a/shadowsocks-csharp/Util/Util.cs b/shadowsocks-csharp/Util/Util.cs index 56f1e0b1..6209a376 100755 --- a/shadowsocks-csharp/Util/Util.cs +++ b/shadowsocks-csharp/Util/Util.cs @@ -1,4 +1,5 @@ -using System; +using NLog; +using System; using System.Diagnostics; using System.IO; using System.IO.Compression; @@ -26,6 +27,8 @@ namespace Shadowsocks.Util public static class Utils { + private static Logger logger = LogManager.GetCurrentClassLogger(); + private static string _tempPath = null; // return path to store temporary files @@ -48,7 +51,7 @@ namespace Shadowsocks.Util } catch (Exception e) { - Logging.Error(e); + logger.Error(e); throw; } } @@ -80,7 +83,7 @@ namespace Shadowsocks.Util { if (isVerbose) { - Logging.Info( + logger.Info( $"Cannot get Windows 10 system theme mode, return default value 0 (dark mode)."); } } @@ -251,7 +254,7 @@ namespace Shadowsocks.Util } catch (Exception e) { - Logging.LogUsefulException(e); + logger.LogUsefulException(e); return null; } } diff --git a/shadowsocks-csharp/View/LogForm.cs b/shadowsocks-csharp/View/LogForm.cs index ba4e76cf..2f0e3fcc 100644 --- a/shadowsocks-csharp/View/LogForm.cs +++ b/shadowsocks-csharp/View/LogForm.cs @@ -11,11 +11,14 @@ using Shadowsocks.Properties; using Shadowsocks.Model; using Shadowsocks.Util; using System.Text; +using NLog; namespace Shadowsocks.View { public partial class LogForm : Form { + private static Logger logger = LogManager.GetCurrentClassLogger(); + long lastOffset; string filename; Timer timer; @@ -38,7 +41,7 @@ namespace Shadowsocks.View TextAnnotation outboundAnnotation = new TextAnnotation(); #endregion - public LogForm(ShadowsocksController controller, string filename) + public LogForm(ShadowsocksController controller, string filename=null) { this.controller = controller; this.filename = filename; @@ -270,7 +273,7 @@ namespace Shadowsocks.View private void OpenLocationMenuItem_Click(object sender, EventArgs e) { string argument = "/select, \"" + filename + "\""; - Logging.Debug(argument); + logger.Debug(argument); System.Diagnostics.Process.Start("explorer.exe", argument); } @@ -287,7 +290,7 @@ namespace Shadowsocks.View #region Clean up the content in LogMessageTextBox. private void DoClearLogs() { - Logging.Clear(); + //logger.Clear(); lastOffset = 0; LogMessageTextBox.Clear(); } @@ -317,7 +320,7 @@ namespace Shadowsocks.View } catch (Exception ex) { - Logging.LogUsefulException(ex); + logger.LogUsefulException(ex); MessageBox.Show(ex.Message); } } diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs index 18d0e1b0..7f310d2b 100644 --- a/shadowsocks-csharp/View/MenuViewController.cs +++ b/shadowsocks-csharp/View/MenuViewController.cs @@ -1,4 +1,5 @@ -using Shadowsocks.Controller; +using NLog; +using Shadowsocks.Controller; using Shadowsocks.Model; using Shadowsocks.Properties; using Shadowsocks.Util; @@ -17,6 +18,7 @@ namespace Shadowsocks.View { public class MenuViewController { + private static Logger logger = LogManager.GetCurrentClassLogger(); // yes this is just a menu view controller // when config form is closed, it moves away from RAM // and it should just do anything related to the config form @@ -386,7 +388,7 @@ namespace Shadowsocks.View void controller_UpdatePACFromGFWListError(object sender, System.IO.ErrorEventArgs e) { ShowBalloonTip(I18N.GetString("Failed to update PAC file"), e.GetException().Message, ToolTipIcon.Error, 5000); - Logging.LogUsefulException(e.GetException()); + logger.LogUsefulException(e.GetException()); } void controller_UpdatePACFromGFWListCompleted(object sender, GFWListUpdater.ResultEventArgs e) @@ -543,7 +545,7 @@ namespace Shadowsocks.View } else { - logForm = new LogForm(controller, Logging.LogFilePath); + logForm = new LogForm(controller); logForm.Show(); logForm.Activate(); logForm.FormClosed += logForm_FormClosed; diff --git a/shadowsocks-csharp/packages.config b/shadowsocks-csharp/packages.config index f7fcb451..911e1d9a 100644 --- a/shadowsocks-csharp/packages.config +++ b/shadowsocks-csharp/packages.config @@ -5,6 +5,7 @@ + \ No newline at end of file diff --git a/shadowsocks-csharp/shadowsocks-csharp.csproj b/shadowsocks-csharp/shadowsocks-csharp.csproj index dd59f561..053234a4 100644 --- a/shadowsocks-csharp/shadowsocks-csharp.csproj +++ b/shadowsocks-csharp/shadowsocks-csharp.csproj @@ -82,12 +82,21 @@ ..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll + + ..\packages\NLog.4.6.8\lib\net45\NLog.dll + + + + + + + @@ -102,6 +111,7 @@ + @@ -145,7 +155,6 @@ - @@ -257,6 +266,7 @@ + From 6240501b0304c5580ad3fa19f76a84baf1267e9a Mon Sep 17 00:00:00 2001 From: celeron533 Date: Sat, 25 Jan 2020 15:56:52 +0800 Subject: [PATCH 09/19] Optimize performance and change log level --- .../Controller/LoggerExtension.cs | 45 +++++++++++-------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/shadowsocks-csharp/Controller/LoggerExtension.cs b/shadowsocks-csharp/Controller/LoggerExtension.cs index 012c63dd..bd9b5925 100644 --- a/shadowsocks-csharp/Controller/LoggerExtension.cs +++ b/shadowsocks-csharp/Controller/LoggerExtension.cs @@ -13,31 +13,40 @@ namespace NLog { public static void Dump(this Logger logger, string tag, byte[] arr, int length) { - var sb = new StringBuilder($"{Environment.NewLine}{tag}: "); - for (int i = 0; i < length - 1; i++) + if (logger.IsTraceEnabled) { - sb.Append($"0x{arr[i]:X2}, "); + var sb = new StringBuilder($"{Environment.NewLine}{tag}: "); + for (int i = 0; i < length - 1; i++) + { + sb.Append($"0x{arr[i]:X2}, "); + } + sb.Append($"0x{arr[length - 1]:X2}"); + sb.Append(Environment.NewLine); + logger.Trace(sb.ToString()); } - sb.Append($"0x{arr[length - 1]:X2}"); - sb.Append(Environment.NewLine); - logger.Debug(sb.ToString()); } public static void Debug(this Logger logger, EndPoint local, EndPoint remote, int len, string header = null, string tailer = null) { - if (header == null && tailer == null) - logger.Debug($"{local} => {remote} (size={len})"); - else if (header == null && tailer != null) - logger.Debug($"{local} => {remote} (size={len}), {tailer}"); - else if (header != null && tailer == null) - logger.Debug($"{header}: {local} => {remote} (size={len})"); - else - logger.Debug($"{header}: {local} => {remote} (size={len}), {tailer}"); + if (logger.IsDebugEnabled) + { + if (header == null && tailer == null) + logger.Debug($"{local} => {remote} (size={len})"); + else if (header == null && tailer != null) + logger.Debug($"{local} => {remote} (size={len}), {tailer}"); + else if (header != null && tailer == null) + logger.Debug($"{header}: {local} => {remote} (size={len})"); + else + logger.Debug($"{header}: {local} => {remote} (size={len}), {tailer}"); + } } public static void Debug(this Logger logger, Socket sock, int len, string header = null, string tailer = null) { - logger.Debug(sock.LocalEndPoint, sock.RemoteEndPoint, len, header, tailer); + if (logger.IsDebugEnabled) + { + logger.Debug(sock.LocalEndPoint, sock.RemoteEndPoint, len, header, tailer); + } } public static void LogUsefulException(this Logger logger, Exception e) @@ -69,7 +78,7 @@ namespace NLog } else { - logger.Info(e); + logger.Warn(e); } } else if (e is ObjectDisposedException) @@ -82,7 +91,7 @@ namespace NLog // Win32Exception (0x80004005): A 32 bit processes cannot access modules of a 64 bit process. if ((uint)ex.ErrorCode != 0x80004005) { - logger.Info(e); + logger.Warn(e); } } else if (e is ProxyException) @@ -103,7 +112,7 @@ namespace NLog } else { - logger.Info(e); + logger.Warn(e); } } } From c93e1d58d4a1b5d1b68c23b36a9d2ba6c8aba693 Mon Sep 17 00:00:00 2001 From: celeron533 Date: Sat, 25 Jan 2020 15:57:22 +0800 Subject: [PATCH 10/19] Not using isVerboseLogging flag --- .../Controller/Service/Listener.cs | 5 +---- .../Controller/Service/TCPRelay.cs | 17 ++++------------- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/shadowsocks-csharp/Controller/Service/Listener.cs b/shadowsocks-csharp/Controller/Service/Listener.cs index 6a9ab5b1..2627587c 100644 --- a/shadowsocks-csharp/Controller/Service/Listener.cs +++ b/shadowsocks-csharp/Controller/Service/Listener.cs @@ -83,10 +83,7 @@ namespace Shadowsocks.Controller // Start an asynchronous socket to listen for connections. logger.Info($"Shadowsocks started ({UpdateChecker.Version})"); - if (_config.isVerboseLogging) - { - logger.Info(Encryption.EncryptorFactory.DumpRegisteredEncryptor()); - } + logger.Debug(Encryption.EncryptorFactory.DumpRegisteredEncryptor()); _tcpSocket.BeginAccept(new AsyncCallback(AcceptCallback), _tcpSocket); UDPState udpState = new UDPState(_udpSocket); _udpSocket.BeginReceiveFrom(udpState.buffer, 0, udpState.buffer.Length, 0, ref udpState.remoteEndPoint, new AsyncCallback(RecvFromCallback), udpState); diff --git a/shadowsocks-csharp/Controller/Service/TCPRelay.cs b/shadowsocks-csharp/Controller/Service/TCPRelay.cs index e97bfcb0..8327bda9 100644 --- a/shadowsocks-csharp/Controller/Service/TCPRelay.cs +++ b/shadowsocks-csharp/Controller/Service/TCPRelay.cs @@ -472,10 +472,7 @@ namespace Shadowsocks.Controller break; } - if (_config.isVerboseLogging) - { - Logger.Info($"connect to {dstAddr}:{dstPort}"); - } + Logger.Debug($"connect to {dstAddr}:{dstPort}"); _destEndPoint = SocketUtil.GetEndPoint(dstAddr, dstPort); @@ -682,12 +679,9 @@ namespace Shadowsocks.Controller _proxyConnected = true; - if (_config.isVerboseLogging) + if (!(remote is DirectConnect)) { - if (!(remote is DirectConnect)) - { - Logger.Info($"Socket connected to proxy {remote.ProxyEndPoint}"); - } + Logger.Debug($"Socket connected to proxy {remote.ProxyEndPoint}"); } _startConnectTime = DateTime.Now; @@ -758,10 +752,7 @@ namespace Shadowsocks.Controller _destConnected = true; - if (_config.isVerboseLogging) - { - Logger.Info($"Socket connected to ss server: {_server.FriendlyName()}"); - } + Logger.Debug($"Socket connected to ss server: {_server.FriendlyName()}"); var latency = DateTime.Now - _startConnectTime; IStrategy strategy = _controller.GetCurrentStrategy(); From 1d0aa5881eaaed9bb85bc1992293d7df9ebe7aa6 Mon Sep 17 00:00:00 2001 From: celeron533 Date: Sat, 25 Jan 2020 23:40:25 +0800 Subject: [PATCH 11/19] Working NLog with config file and "verbose log" option --- .../Controller/ShadowsocksController.cs | 4 + shadowsocks-csharp/Data/NLog.config | 7 +- shadowsocks-csharp/Model/Configuration.cs | 38 +++++- shadowsocks-csharp/Model/NlogConfig.cs | 117 ++++++++++++++++++ shadowsocks-csharp/Program.cs | 12 +- shadowsocks-csharp/Util/Util.cs | 11 +- shadowsocks-csharp/View/LogForm.cs | 11 +- shadowsocks-csharp/View/MenuViewController.cs | 2 +- shadowsocks-csharp/shadowsocks-csharp.csproj | 1 + shadowsocks-windows.sln | 13 +- 10 files changed, 188 insertions(+), 28 deletions(-) create mode 100644 shadowsocks-csharp/Model/NlogConfig.cs diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs index c17dbea8..1d2be8c9 100644 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs @@ -254,6 +254,7 @@ namespace Shadowsocks.Controller { _config.isVerboseLogging = enabled; SaveConfig(_config); + NLogConfig.LoadConfiguration(); // reload nlog VerboseLoggingStatusChanged?.Invoke(this, new EventArgs()); } @@ -477,6 +478,9 @@ namespace Shadowsocks.Controller Encryption.RNG.Reload(); // some logic in configuration updated the config when saving, we need to read it again _config = Configuration.Load(); + + NLogConfig.LoadConfiguration(); + StatisticsConfiguration = StatisticsStrategyConfiguration.Load(); privoxyRunner = privoxyRunner ?? new PrivoxyRunner(); diff --git a/shadowsocks-csharp/Data/NLog.config b/shadowsocks-csharp/Data/NLog.config index 4b779775..4f9d27e3 100644 --- a/shadowsocks-csharp/Data/NLog.config +++ b/shadowsocks-csharp/Data/NLog.config @@ -1,10 +1,11 @@  - + - - + \ No newline at end of file diff --git a/shadowsocks-csharp/Model/Configuration.cs b/shadowsocks-csharp/Model/Configuration.cs index f2f54b08..db686288 100644 --- a/shadowsocks-csharp/Model/Configuration.cs +++ b/shadowsocks-csharp/Model/Configuration.cs @@ -36,10 +36,14 @@ namespace Shadowsocks.Model public bool autoCheckUpdate; public bool checkPreRelease; public bool isVerboseLogging; + //public NLogConfig.LogLevel logLevel; public LogViewerConfig logViewer; public ProxyConfig proxy; public HotkeyConfig hotkey; + [JsonIgnore] + NLogConfig nLogConfig; + private static readonly string CONFIG_FILE = "gui-config.json"; [JsonIgnore] public string localHost => GetLocalHost(); @@ -104,6 +108,28 @@ namespace Shadowsocks.Model config.proxy.CheckConfig(); + try + { + config.nLogConfig = NLogConfig.LoadXML(); + switch (config.nLogConfig.GetLogLevel()) + { + case NLogConfig.LogLevel.Fatal: + case NLogConfig.LogLevel.Error: + case NLogConfig.LogLevel.Warn: + case NLogConfig.LogLevel.Info: + config.isVerboseLogging = false; + break; + case NLogConfig.LogLevel.Debug: + case NLogConfig.LogLevel.Trace: + config.isVerboseLogging = true; + break; + } + } + catch (Exception e) + { + logger.Error(e, "Cannot get the log level from NLog config file."); + } + return config; } catch (Exception e) @@ -122,7 +148,7 @@ namespace Shadowsocks.Model }, logViewer = new LogViewerConfig(), proxy = new ProxyConfig(), - hotkey = new HotkeyConfig() + hotkey = new HotkeyConfig(), }; } } @@ -145,6 +171,16 @@ namespace Shadowsocks.Model sw.Write(jsonString); sw.Flush(); } + try + { + // apply changs to NLog.config + config.nLogConfig.SetLogLevel(config.isVerboseLogging? NLogConfig.LogLevel.Trace: NLogConfig.LogLevel.Info); + NLogConfig.SaveXML(config.nLogConfig); + } + catch(Exception e) + { + logger.Error(e, "Cannot set the log level"); + } } catch (IOException e) { diff --git a/shadowsocks-csharp/Model/NlogConfig.cs b/shadowsocks-csharp/Model/NlogConfig.cs new file mode 100644 index 00000000..fe460a5f --- /dev/null +++ b/shadowsocks-csharp/Model/NlogConfig.cs @@ -0,0 +1,117 @@ +using NLog; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml; + +namespace Shadowsocks.Model +{ + public class NLogConfig + { + public enum LogLevel + { + Fatal, + Error, + Warn, + Info, + Debug, + Trace, + } + + const string NLOG_CONFIG_FILE_NAME = "NLog.config"; + const string MIN_LEVEL_ATTRIBUTE = "minlevel"; + const string FILE_NAME_ATTRIBUTE = "fileName"; + + XmlDocument doc = new XmlDocument(); + XmlElement logLevelElement; + XmlElement logFileNameElement; + + /// + /// Load the NLog config xml file content + /// + public static NLogConfig LoadXML() + { + NLogConfig config = new NLogConfig(); + config.doc.Load(NLOG_CONFIG_FILE_NAME); + config.logLevelElement = (XmlElement)SelectSingleNode(config.doc, "//nlog:logger[@name='*']"); + config.logFileNameElement = (XmlElement)SelectSingleNode(config.doc, "//nlog:target[@name='file']"); + return config; + } + + /// + /// Save the content to NLog config xml file + /// + public static void SaveXML(NLogConfig nLogConfig) + { + nLogConfig.doc.Save(NLOG_CONFIG_FILE_NAME); + } + + + /// + /// Get the current minLogLevel from xml file + /// + /// + public LogLevel GetLogLevel() + { + LogLevel level = LogLevel.Warn; + string levelStr = logLevelElement.GetAttribute(MIN_LEVEL_ATTRIBUTE); + Enum.TryParse(levelStr, out level); + return level; + } + + /// + /// Get the target fileName from xml file + /// + /// + public string GetLogFileName() + { + return logFileNameElement.GetAttribute(FILE_NAME_ATTRIBUTE); + } + + /// + /// Set the minLogLevel to xml file + /// + /// + public void SetLogLevel(LogLevel logLevel) + { + logLevelElement.SetAttribute(MIN_LEVEL_ATTRIBUTE, logLevel.ToString("G")); + } + + /// + /// Set the target fileName to xml file + /// + /// + public void SetLogFileName(string fileName) + { + logFileNameElement.SetAttribute(FILE_NAME_ATTRIBUTE, fileName); + } + + private static XmlNode SelectSingleNode(XmlDocument doc, string xpath) + { + XmlNamespaceManager manager = new XmlNamespaceManager(doc.NameTable); + manager.AddNamespace("nlog", "http://www.nlog-project.org/schemas/NLog.xsd"); + //return doc.SelectSingleNode("//nlog:logger[(@shadowsocks='managed') and (@name='*')]", manager); + return doc.SelectSingleNode(xpath, manager); + } + + /// + /// Extract the pre-defined NLog configuration file is does not exist. Then reload the Nlog configuration. + /// + public static void TouchAndApplyNLogConfig() + { + if (!File.Exists(NLOG_CONFIG_FILE_NAME)) + { + File.WriteAllText(NLOG_CONFIG_FILE_NAME, Properties.Resources.NLog_config); + LogManager.LoadConfiguration(NLOG_CONFIG_FILE_NAME); + } + } + + public static void LoadConfiguration() + { + LogManager.LoadConfiguration(NLOG_CONFIG_FILE_NAME); + } + } +} diff --git a/shadowsocks-csharp/Program.cs b/shadowsocks-csharp/Program.cs index b85e6ced..906ea685 100755 --- a/shadowsocks-csharp/Program.cs +++ b/shadowsocks-csharp/Program.cs @@ -27,7 +27,7 @@ namespace Shadowsocks static void Main(string[] args) { // todo: initialize the NLog configuartion - TouchAndApplyNLogConfig(); + Model.NLogConfig.TouchAndApplyNLogConfig(); // .NET Framework 4.7.2 on Win7 compatibility System.Net.ServicePointManager.SecurityProtocol |= @@ -97,16 +97,6 @@ namespace Shadowsocks } } - private static void TouchAndApplyNLogConfig() - { - string NLogConfigFileName = "NLog.config"; - if (!File.Exists(NLogConfigFileName)) - { - File.WriteAllText(NLogConfigFileName, Properties.Resources.NLog_config); - LogManager.LoadConfiguration(NLogConfigFileName); - } - } - private static int exited = 0; private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { diff --git a/shadowsocks-csharp/Util/Util.cs b/shadowsocks-csharp/Util/Util.cs index 6209a376..dffd5271 100755 --- a/shadowsocks-csharp/Util/Util.cs +++ b/shadowsocks-csharp/Util/Util.cs @@ -61,7 +61,7 @@ namespace Shadowsocks.Util public enum WindowsThemeMode { Dark, Light } // Support on Windows 10 1903+ - public static WindowsThemeMode GetWindows10SystemThemeSetting(bool isVerbose) + public static WindowsThemeMode GetWindows10SystemThemeSetting() { WindowsThemeMode themeMode = WindowsThemeMode.Dark; try @@ -81,11 +81,10 @@ namespace Shadowsocks.Util } catch { - if (isVerbose) - { - logger.Info( - $"Cannot get Windows 10 system theme mode, return default value 0 (dark mode)."); - } + + logger.Info( + $"Cannot get Windows 10 system theme mode, return default value 0 (dark mode)."); + } return themeMode; } diff --git a/shadowsocks-csharp/View/LogForm.cs b/shadowsocks-csharp/View/LogForm.cs index 2f0e3fcc..16f2ad6e 100644 --- a/shadowsocks-csharp/View/LogForm.cs +++ b/shadowsocks-csharp/View/LogForm.cs @@ -41,13 +41,16 @@ namespace Shadowsocks.View TextAnnotation outboundAnnotation = new TextAnnotation(); #endregion - public LogForm(ShadowsocksController controller, string filename=null) + public LogForm(ShadowsocksController controller) { this.controller = controller; - this.filename = filename; + InitializeComponent(); Icon = Icon.FromHandle(Resources.ssw128.GetHicon()); + var nLogConfig = NLogConfig.LoadXML(); + this.filename = nLogConfig.GetLogFileName(); + LogViewerConfig config = controller.GetConfigurationCopy().logViewer; topMostTrigger = config.topMost; @@ -173,7 +176,7 @@ namespace Shadowsocks.View string line = ""; StringBuilder appendText = new StringBuilder(1024); while ((line = reader.ReadLine()) != null) - appendText.Append(line + Environment.NewLine); + appendText.AppendLine(line); LogMessageTextBox.AppendText(appendText.ToString()); LogMessageTextBox.ScrollToCaret(); @@ -197,7 +200,7 @@ namespace Shadowsocks.View while ((line = reader.ReadLine()) != null) { changed = true; - appendText.Append(line + Environment.NewLine); + appendText.AppendLine(line); } if (changed) diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs index 7f310d2b..02be5162 100644 --- a/shadowsocks-csharp/View/MenuViewController.cs +++ b/shadowsocks-csharp/View/MenuViewController.cs @@ -222,7 +222,7 @@ namespace Shadowsocks.View { Color colorMask = Color.White; - Utils.WindowsThemeMode currentWindowsThemeMode = Utils.GetWindows10SystemThemeSetting(controller.GetCurrentConfiguration().isVerboseLogging); + Utils.WindowsThemeMode currentWindowsThemeMode = Utils.GetWindows10SystemThemeSetting(); if (isProxyEnabled) { diff --git a/shadowsocks-csharp/shadowsocks-csharp.csproj b/shadowsocks-csharp/shadowsocks-csharp.csproj index 053234a4..bf562337 100644 --- a/shadowsocks-csharp/shadowsocks-csharp.csproj +++ b/shadowsocks-csharp/shadowsocks-csharp.csproj @@ -132,6 +132,7 @@ + diff --git a/shadowsocks-windows.sln b/shadowsocks-windows.sln index 1c24be82..d0048437 100644 --- a/shadowsocks-windows.sln +++ b/shadowsocks-windows.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26228.10 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29709.97 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "shadowsocks-csharp", "shadowsocks-csharp\shadowsocks-csharp.csproj", "{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}" EndProject @@ -12,21 +12,30 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShadowsocksTest", "test\Sha EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Debug|Any CPU.ActiveCfg = Debug|x86 {8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Debug|x86.ActiveCfg = Debug|x86 {8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Debug|x86.Build.0 = Debug|x86 {8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Debug|x86.Deploy.0 = Debug|x86 + {8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Release|Any CPU.ActiveCfg = Release|x86 {8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Release|x86.ActiveCfg = Release|x86 {8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Release|x86.Build.0 = Release|x86 + {45913187-0685-4903-B250-DCEF0479CD86}.Debug|Any CPU.ActiveCfg = Debug|x86 {45913187-0685-4903-B250-DCEF0479CD86}.Debug|x86.ActiveCfg = Debug|x86 {45913187-0685-4903-B250-DCEF0479CD86}.Debug|x86.Build.0 = Debug|x86 + {45913187-0685-4903-B250-DCEF0479CD86}.Release|Any CPU.ActiveCfg = Release|x86 {45913187-0685-4903-B250-DCEF0479CD86}.Release|x86.ActiveCfg = Release|x86 {45913187-0685-4903-B250-DCEF0479CD86}.Release|x86.Build.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {F7E7D35B-4FDA-4385-95CF-09DADED042EA} + EndGlobalSection EndGlobal From 95f4e0ae1aa4af80069f59987520e36db64ee779 Mon Sep 17 00:00:00 2001 From: celeron533 Date: Mon, 27 Jan 2020 23:47:38 +0800 Subject: [PATCH 12/19] Bug fix: wrong server in tray menu as selected server when there has an invalid server in the list Fix #2782 --- shadowsocks-csharp/View/MenuViewController.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs index 18d0e1b0..c3a3a886 100644 --- a/shadowsocks-csharp/View/MenuViewController.cs +++ b/shadowsocks-csharp/View/MenuViewController.cs @@ -454,30 +454,30 @@ namespace Shadowsocks.View { items.RemoveAt(0); } - int i = 0; + int strategyCount = 0; foreach (var strategy in controller.GetStrategies()) { MenuItem item = new MenuItem(strategy.Name); item.Tag = strategy.ID; item.Click += AStrategyItem_Click; - items.Add(i, item); - i++; + items.Add(strategyCount, item); + strategyCount++; } // user wants a seperator item between strategy and servers menugroup - items.Add(i++, new MenuItem("-")); + items.Add(strategyCount++, new MenuItem("-")); - int strategyCount = i; + int serverCount = 0; Configuration configuration = controller.GetConfigurationCopy(); foreach (var server in configuration.configs) { if (Configuration.ChecksServer(server)) { MenuItem item = new MenuItem(server.FriendlyName()); - item.Tag = i - strategyCount; + item.Tag = configuration.configs.FindIndex(s => s == server); item.Click += AServerItem_Click; - items.Add(i, item); - i++; + items.Add(strategyCount + serverCount, item); + serverCount++; } } From 01e3b10f5e9b632cf711aaa3a6f80c8ade3698a3 Mon Sep 17 00:00:00 2001 From: Student Main Date: Mon, 6 Jan 2020 00:30:47 +0800 Subject: [PATCH 13/19] deprecate unsafe encryption method --- shadowsocks-csharp/Data/i18n.csv | 3 +- .../View/ConfigForm.Designer.cs | 238 +++++++++--------- shadowsocks-csharp/View/ConfigForm.cs | 82 +++++- 3 files changed, 204 insertions(+), 119 deletions(-) diff --git a/shadowsocks-csharp/Data/i18n.csv b/shadowsocks-csharp/Data/i18n.csv index 3db1ef8f..f6be9f33 100644 --- a/shadowsocks-csharp/Data/i18n.csv +++ b/shadowsocks-csharp/Data/i18n.csv @@ -1,4 +1,4 @@ -en,ru-RU,zh-CN,zh-TW,ja +en,ru-RU,zh-CN,zh-TW,ja #Restart program to apply translation,,,, #This is comment line,,,, #Always keep language name at head of file,,,, @@ -75,6 +75,7 @@ Apply,Применить,应用,應用,適用 New server,Новый сервер,未配置的服务器,新伺服器,新規サーバー Move &Up,Выше,上移(&U),上移 (&U),上に移動 (&U) Move D&own,Ниже,下移(&O),下移 (&O),下に移動 (&O) +deprecated,不推荐,, ,,,, #Statistics Config,,,, ,,,, diff --git a/shadowsocks-csharp/View/ConfigForm.Designer.cs b/shadowsocks-csharp/View/ConfigForm.Designer.cs index fafbca48..0642fa77 100755 --- a/shadowsocks-csharp/View/ConfigForm.Designer.cs +++ b/shadowsocks-csharp/View/ConfigForm.Designer.cs @@ -106,10 +106,10 @@ this.tableLayoutPanel1.Controls.Add(this.PluginArgumentsLabel, 0, 8); this.tableLayoutPanel1.Controls.Add(this.RemarksLabel, 0, 10); this.tableLayoutPanel1.Controls.Add(this.NeedPluginArgCheckBox, 1, 7); - this.tableLayoutPanel1.Location = new System.Drawing.Point(8, 21); + this.tableLayoutPanel1.Location = new System.Drawing.Point(10, 26); this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(0); this.tableLayoutPanel1.Name = "tableLayoutPanel1"; - this.tableLayoutPanel1.Padding = new System.Windows.Forms.Padding(3); + this.tableLayoutPanel1.Padding = new System.Windows.Forms.Padding(4, 4, 4, 4); this.tableLayoutPanel1.RowCount = 12; this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); @@ -123,16 +123,17 @@ this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel1.Size = new System.Drawing.Size(279, 292); + this.tableLayoutPanel1.Size = new System.Drawing.Size(394, 357); this.tableLayoutPanel1.TabIndex = 0; // // PluginOptionsLabel // this.PluginOptionsLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.PluginOptionsLabel.AutoSize = true; - this.PluginOptionsLabel.Location = new System.Drawing.Point(18, 166); + this.PluginOptionsLabel.Location = new System.Drawing.Point(24, 203); + this.PluginOptionsLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.PluginOptionsLabel.Name = "PluginOptionsLabel"; - this.PluginOptionsLabel.Size = new System.Drawing.Size(89, 12); + this.PluginOptionsLabel.Size = new System.Drawing.Size(119, 15); this.PluginOptionsLabel.TabIndex = 6; this.PluginOptionsLabel.Text = "Plugin Options"; this.toolTip1.SetToolTip(this.PluginOptionsLabel, "Environment variables for plugin program"); @@ -140,20 +141,22 @@ // PluginTextBox // this.PluginTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.PluginTextBox.Location = new System.Drawing.Point(113, 135); + this.PluginTextBox.Location = new System.Drawing.Point(151, 165); + this.PluginTextBox.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.PluginTextBox.MaxLength = 256; this.PluginTextBox.Name = "PluginTextBox"; - this.PluginTextBox.Size = new System.Drawing.Size(160, 21); + this.PluginTextBox.Size = new System.Drawing.Size(235, 25); this.PluginTextBox.TabIndex = 5; this.PluginTextBox.WordWrap = false; // // RemarksTextBox // this.RemarksTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.RemarksTextBox.Location = new System.Drawing.Point(113, 238); + this.RemarksTextBox.Location = new System.Drawing.Point(151, 291); + this.RemarksTextBox.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.RemarksTextBox.MaxLength = 32; this.RemarksTextBox.Name = "RemarksTextBox"; - this.RemarksTextBox.Size = new System.Drawing.Size(160, 21); + this.RemarksTextBox.Size = new System.Drawing.Size(235, 25); this.RemarksTextBox.TabIndex = 8; this.RemarksTextBox.WordWrap = false; // @@ -161,9 +164,10 @@ // this.IPLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.IPLabel.AutoSize = true; - this.IPLabel.Location = new System.Drawing.Point(48, 10); + this.IPLabel.Location = new System.Drawing.Point(64, 13); + this.IPLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.IPLabel.Name = "IPLabel"; - this.IPLabel.Size = new System.Drawing.Size(59, 12); + this.IPLabel.Size = new System.Drawing.Size(79, 15); this.IPLabel.TabIndex = 0; this.IPLabel.Text = "Server IP"; // @@ -171,9 +175,10 @@ // this.ServerPortLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.ServerPortLabel.AutoSize = true; - this.ServerPortLabel.Location = new System.Drawing.Point(36, 37); + this.ServerPortLabel.Location = new System.Drawing.Point(48, 46); + this.ServerPortLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.ServerPortLabel.Name = "ServerPortLabel"; - this.ServerPortLabel.Size = new System.Drawing.Size(71, 12); + this.ServerPortLabel.Size = new System.Drawing.Size(95, 15); this.ServerPortLabel.TabIndex = 1; this.ServerPortLabel.Text = "Server Port"; // @@ -181,9 +186,10 @@ // this.PasswordLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.PasswordLabel.AutoSize = true; - this.PasswordLabel.Location = new System.Drawing.Point(54, 64); + this.PasswordLabel.Location = new System.Drawing.Point(72, 79); + this.PasswordLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.PasswordLabel.Name = "PasswordLabel"; - this.PasswordLabel.Size = new System.Drawing.Size(53, 12); + this.PasswordLabel.Size = new System.Drawing.Size(71, 15); this.PasswordLabel.TabIndex = 2; this.PasswordLabel.Text = "Password"; this.PasswordLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; @@ -191,30 +197,33 @@ // IPTextBox // this.IPTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.IPTextBox.Location = new System.Drawing.Point(113, 6); + this.IPTextBox.Location = new System.Drawing.Point(151, 8); + this.IPTextBox.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.IPTextBox.MaxLength = 512; this.IPTextBox.Name = "IPTextBox"; - this.IPTextBox.Size = new System.Drawing.Size(160, 21); + this.IPTextBox.Size = new System.Drawing.Size(235, 25); this.IPTextBox.TabIndex = 0; this.IPTextBox.WordWrap = false; // // ServerPortTextBox // this.ServerPortTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.ServerPortTextBox.Location = new System.Drawing.Point(113, 33); + this.ServerPortTextBox.Location = new System.Drawing.Point(151, 41); + this.ServerPortTextBox.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.ServerPortTextBox.MaxLength = 10; this.ServerPortTextBox.Name = "ServerPortTextBox"; - this.ServerPortTextBox.Size = new System.Drawing.Size(160, 21); + this.ServerPortTextBox.Size = new System.Drawing.Size(235, 25); this.ServerPortTextBox.TabIndex = 1; this.ServerPortTextBox.WordWrap = false; // // PasswordTextBox // this.PasswordTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.PasswordTextBox.Location = new System.Drawing.Point(113, 60); + this.PasswordTextBox.Location = new System.Drawing.Point(151, 74); + this.PasswordTextBox.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.PasswordTextBox.MaxLength = 256; this.PasswordTextBox.Name = "PasswordTextBox"; - this.PasswordTextBox.Size = new System.Drawing.Size(160, 21); + this.PasswordTextBox.Size = new System.Drawing.Size(235, 25); this.PasswordTextBox.TabIndex = 2; this.PasswordTextBox.UseSystemPasswordChar = true; this.PasswordTextBox.WordWrap = false; @@ -223,9 +232,10 @@ // this.EncryptionLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.EncryptionLabel.AutoSize = true; - this.EncryptionLabel.Location = new System.Drawing.Point(42, 113); + this.EncryptionLabel.Location = new System.Drawing.Point(56, 138); + this.EncryptionLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.EncryptionLabel.Name = "EncryptionLabel"; - this.EncryptionLabel.Size = new System.Drawing.Size(65, 12); + this.EncryptionLabel.Size = new System.Drawing.Size(87, 15); this.EncryptionLabel.TabIndex = 4; this.EncryptionLabel.Text = "Encryption"; // @@ -236,69 +246,54 @@ this.EncryptionSelect.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.EncryptionSelect.FormattingEnabled = true; this.EncryptionSelect.ImeMode = System.Windows.Forms.ImeMode.NoControl; - this.EncryptionSelect.ItemHeight = 12; - this.EncryptionSelect.Items.AddRange(new object[] { - "rc4-md5", - "salsa20", - "chacha20", - "chacha20-ietf", - "aes-256-cfb", - "aes-192-cfb", - "aes-128-cfb", - "aes-256-ctr", - "aes-192-ctr", - "aes-128-ctr", - "bf-cfb", - "camellia-128-cfb", - "camellia-192-cfb", - "camellia-256-cfb", - "aes-128-gcm", - "aes-192-gcm", - "aes-256-gcm", - "chacha20-ietf-poly1305", - "xchacha20-ietf-poly1305"}); - this.EncryptionSelect.Location = new System.Drawing.Point(113, 109); + this.EncryptionSelect.ItemHeight = 15; + this.EncryptionSelect.Location = new System.Drawing.Point(151, 134); + this.EncryptionSelect.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.EncryptionSelect.Name = "EncryptionSelect"; - this.EncryptionSelect.Size = new System.Drawing.Size(160, 20); + this.EncryptionSelect.Size = new System.Drawing.Size(235, 23); this.EncryptionSelect.TabIndex = 4; // // TimeoutLabel // this.TimeoutLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.TimeoutLabel.AutoSize = true; - this.TimeoutLabel.Location = new System.Drawing.Point(30, 269); + this.TimeoutLabel.Location = new System.Drawing.Point(40, 329); + this.TimeoutLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.TimeoutLabel.Name = "TimeoutLabel"; this.TimeoutLabel.RightToLeft = System.Windows.Forms.RightToLeft.No; - this.TimeoutLabel.Size = new System.Drawing.Size(77, 12); + this.TimeoutLabel.Size = new System.Drawing.Size(103, 15); this.TimeoutLabel.TabIndex = 9; this.TimeoutLabel.Text = "Timeout(Sec)"; // // TimeoutTextBox // this.TimeoutTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.TimeoutTextBox.Location = new System.Drawing.Point(113, 265); + this.TimeoutTextBox.Location = new System.Drawing.Point(151, 324); + this.TimeoutTextBox.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.TimeoutTextBox.MaxLength = 5; this.TimeoutTextBox.Name = "TimeoutTextBox"; - this.TimeoutTextBox.Size = new System.Drawing.Size(160, 21); + this.TimeoutTextBox.Size = new System.Drawing.Size(235, 25); this.TimeoutTextBox.TabIndex = 9; // // PluginLabel // this.PluginLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.PluginLabel.AutoSize = true; - this.PluginLabel.Location = new System.Drawing.Point(18, 139); + this.PluginLabel.Location = new System.Drawing.Point(24, 170); + this.PluginLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.PluginLabel.Name = "PluginLabel"; - this.PluginLabel.Size = new System.Drawing.Size(89, 12); + this.PluginLabel.Size = new System.Drawing.Size(119, 15); this.PluginLabel.TabIndex = 5; this.PluginLabel.Text = "Plugin Program"; // // PluginOptionsTextBox // this.PluginOptionsTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.PluginOptionsTextBox.Location = new System.Drawing.Point(113, 162); + this.PluginOptionsTextBox.Location = new System.Drawing.Point(151, 198); + this.PluginOptionsTextBox.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.PluginOptionsTextBox.MaxLength = 256; this.PluginOptionsTextBox.Name = "PluginOptionsTextBox"; - this.PluginOptionsTextBox.Size = new System.Drawing.Size(160, 21); + this.PluginOptionsTextBox.Size = new System.Drawing.Size(235, 25); this.PluginOptionsTextBox.TabIndex = 6; this.PluginOptionsTextBox.WordWrap = false; // @@ -307,9 +302,10 @@ this.ShowPasswdCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left))); this.ShowPasswdCheckBox.AutoSize = true; - this.ShowPasswdCheckBox.Location = new System.Drawing.Point(113, 87); + this.ShowPasswdCheckBox.Location = new System.Drawing.Point(151, 107); + this.ShowPasswdCheckBox.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.ShowPasswdCheckBox.Name = "ShowPasswdCheckBox"; - this.ShowPasswdCheckBox.Size = new System.Drawing.Size(102, 16); + this.ShowPasswdCheckBox.Size = new System.Drawing.Size(133, 19); this.ShowPasswdCheckBox.TabIndex = 3; this.ShowPasswdCheckBox.Text = "Show Password"; this.ShowPasswdCheckBox.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; @@ -319,10 +315,11 @@ // PluginArgumentsTextBox // this.PluginArgumentsTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.PluginArgumentsTextBox.Location = new System.Drawing.Point(113, 211); + this.PluginArgumentsTextBox.Location = new System.Drawing.Point(151, 258); + this.PluginArgumentsTextBox.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.PluginArgumentsTextBox.MaxLength = 512; this.PluginArgumentsTextBox.Name = "PluginArgumentsTextBox"; - this.PluginArgumentsTextBox.Size = new System.Drawing.Size(160, 21); + this.PluginArgumentsTextBox.Size = new System.Drawing.Size(235, 25); this.PluginArgumentsTextBox.TabIndex = 7; this.PluginArgumentsTextBox.WordWrap = false; // @@ -330,9 +327,10 @@ // this.PluginArgumentsLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.PluginArgumentsLabel.AutoSize = true; - this.PluginArgumentsLabel.Location = new System.Drawing.Point(6, 215); + this.PluginArgumentsLabel.Location = new System.Drawing.Point(8, 263); + this.PluginArgumentsLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.PluginArgumentsLabel.Name = "PluginArgumentsLabel"; - this.PluginArgumentsLabel.Size = new System.Drawing.Size(101, 12); + this.PluginArgumentsLabel.Size = new System.Drawing.Size(135, 15); this.PluginArgumentsLabel.TabIndex = 7; this.PluginArgumentsLabel.Text = "Plugin Arguments"; this.toolTip1.SetToolTip(this.PluginArgumentsLabel, "Not a SIP003 standard. Used as CLI arguments.\r\nMandatory:\r\n%SS_LOCAL_HOST%, %SS_L" + @@ -342,18 +340,20 @@ // this.RemarksLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.RemarksLabel.AutoSize = true; - this.RemarksLabel.Location = new System.Drawing.Point(60, 242); + this.RemarksLabel.Location = new System.Drawing.Point(80, 296); + this.RemarksLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.RemarksLabel.Name = "RemarksLabel"; - this.RemarksLabel.Size = new System.Drawing.Size(47, 12); + this.RemarksLabel.Size = new System.Drawing.Size(63, 15); this.RemarksLabel.TabIndex = 8; this.RemarksLabel.Text = "Remarks"; // // NeedPluginArgCheckBox // this.NeedPluginArgCheckBox.AutoSize = true; - this.NeedPluginArgCheckBox.Location = new System.Drawing.Point(113, 189); + this.NeedPluginArgCheckBox.Location = new System.Drawing.Point(151, 231); + this.NeedPluginArgCheckBox.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.NeedPluginArgCheckBox.Name = "NeedPluginArgCheckBox"; - this.NeedPluginArgCheckBox.Size = new System.Drawing.Size(144, 16); + this.NeedPluginArgCheckBox.Size = new System.Drawing.Size(189, 19); this.NeedPluginArgCheckBox.TabIndex = 10; this.NeedPluginArgCheckBox.Text = "Need Plugin Argument"; this.NeedPluginArgCheckBox.UseVisualStyleBackColor = true; @@ -364,7 +364,8 @@ this.panel2.Anchor = System.Windows.Forms.AnchorStyles.Top; this.panel2.AutoSize = true; this.panel2.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; - this.panel2.Location = new System.Drawing.Point(165, 187); + this.panel2.Location = new System.Drawing.Point(206, 234); + this.panel2.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.panel2.Name = "panel2"; this.panel2.Size = new System.Drawing.Size(0, 0); this.panel2.TabIndex = 1; @@ -373,10 +374,10 @@ // this.OKButton.DialogResult = System.Windows.Forms.DialogResult.OK; this.OKButton.Dock = System.Windows.Forms.DockStyle.Right; - this.OKButton.Location = new System.Drawing.Point(3, 3); - this.OKButton.Margin = new System.Windows.Forms.Padding(3, 3, 3, 0); + this.OKButton.Location = new System.Drawing.Point(4, 4); + this.OKButton.Margin = new System.Windows.Forms.Padding(4, 4, 4, 0); this.OKButton.Name = "OKButton"; - this.OKButton.Size = new System.Drawing.Size(75, 23); + this.OKButton.Size = new System.Drawing.Size(94, 29); this.OKButton.TabIndex = 17; this.OKButton.Text = "OK"; this.OKButton.UseVisualStyleBackColor = true; @@ -386,10 +387,10 @@ // this.MyCancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.MyCancelButton.Dock = System.Windows.Forms.DockStyle.Right; - this.MyCancelButton.Location = new System.Drawing.Point(84, 3); - this.MyCancelButton.Margin = new System.Windows.Forms.Padding(3, 3, 3, 0); + this.MyCancelButton.Location = new System.Drawing.Point(106, 4); + this.MyCancelButton.Margin = new System.Windows.Forms.Padding(4, 4, 4, 0); this.MyCancelButton.Name = "MyCancelButton"; - this.MyCancelButton.Size = new System.Drawing.Size(75, 23); + this.MyCancelButton.Size = new System.Drawing.Size(94, 29); this.MyCancelButton.TabIndex = 18; this.MyCancelButton.Text = "Cancel"; this.MyCancelButton.UseVisualStyleBackColor = true; @@ -399,10 +400,10 @@ // this.ApplyButton.Dock = System.Windows.Forms.DockStyle.Right; this.ApplyButton.Enabled = false; - this.ApplyButton.Location = new System.Drawing.Point(165, 3); - this.ApplyButton.Margin = new System.Windows.Forms.Padding(3, 3, 0, 0); + this.ApplyButton.Location = new System.Drawing.Point(208, 4); + this.ApplyButton.Margin = new System.Windows.Forms.Padding(4, 4, 0, 0); this.ApplyButton.Name = "ApplyButton"; - this.ApplyButton.Size = new System.Drawing.Size(75, 23); + this.ApplyButton.Size = new System.Drawing.Size(94, 29); this.ApplyButton.TabIndex = 19; this.ApplyButton.Text = "Apply"; this.ApplyButton.UseVisualStyleBackColor = true; @@ -411,10 +412,10 @@ // DeleteButton // this.DeleteButton.Dock = System.Windows.Forms.DockStyle.Right; - this.DeleteButton.Location = new System.Drawing.Point(86, 6); - this.DeleteButton.Margin = new System.Windows.Forms.Padding(3, 6, 0, 3); + this.DeleteButton.Location = new System.Drawing.Point(108, 8); + this.DeleteButton.Margin = new System.Windows.Forms.Padding(4, 8, 0, 4); this.DeleteButton.Name = "DeleteButton"; - this.DeleteButton.Size = new System.Drawing.Size(80, 23); + this.DeleteButton.Size = new System.Drawing.Size(100, 29); this.DeleteButton.TabIndex = 13; this.DeleteButton.Text = "&Delete"; this.DeleteButton.UseVisualStyleBackColor = true; @@ -423,10 +424,10 @@ // AddButton // this.AddButton.Dock = System.Windows.Forms.DockStyle.Left; - this.AddButton.Location = new System.Drawing.Point(0, 6); - this.AddButton.Margin = new System.Windows.Forms.Padding(0, 6, 3, 3); + this.AddButton.Location = new System.Drawing.Point(0, 8); + this.AddButton.Margin = new System.Windows.Forms.Padding(0, 8, 4, 4); this.AddButton.Name = "AddButton"; - this.AddButton.Size = new System.Drawing.Size(80, 23); + this.AddButton.Size = new System.Drawing.Size(100, 29); this.AddButton.TabIndex = 12; this.AddButton.Text = "&Add"; this.AddButton.UseVisualStyleBackColor = true; @@ -437,10 +438,11 @@ this.ServerGroupBox.AutoSize = true; this.ServerGroupBox.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; this.ServerGroupBox.Controls.Add(this.tableLayoutPanel1); - this.ServerGroupBox.Location = new System.Drawing.Point(178, 0); - this.ServerGroupBox.Margin = new System.Windows.Forms.Padding(12, 0, 0, 0); + this.ServerGroupBox.Location = new System.Drawing.Point(223, 0); + this.ServerGroupBox.Margin = new System.Windows.Forms.Padding(15, 0, 0, 0); this.ServerGroupBox.Name = "ServerGroupBox"; - this.ServerGroupBox.Size = new System.Drawing.Size(290, 330); + this.ServerGroupBox.Padding = new System.Windows.Forms.Padding(4, 4, 4, 4); + this.ServerGroupBox.Size = new System.Drawing.Size(408, 405); this.ServerGroupBox.TabIndex = 0; this.ServerGroupBox.TabStop = false; this.ServerGroupBox.Text = "Server"; @@ -449,11 +451,11 @@ // this.ServersListBox.FormattingEnabled = true; this.ServersListBox.IntegralHeight = false; - this.ServersListBox.ItemHeight = 12; + this.ServersListBox.ItemHeight = 15; this.ServersListBox.Location = new System.Drawing.Point(0, 0); this.ServersListBox.Margin = new System.Windows.Forms.Padding(0); this.ServersListBox.Name = "ServersListBox"; - this.ServersListBox.Size = new System.Drawing.Size(166, 148); + this.ServersListBox.Size = new System.Drawing.Size(206, 184); this.ServersListBox.TabIndex = 11; this.ServersListBox.SelectedIndexChanged += new System.EventHandler(this.ServersListBox_SelectedIndexChanged); // @@ -470,14 +472,14 @@ this.tableLayoutPanel2.Controls.Add(this.ServersListBox, 0, 0); this.tableLayoutPanel2.Controls.Add(this.ServerGroupBox, 1, 0); this.tableLayoutPanel2.Controls.Add(this.tableLayoutPanel4, 0, 1); - this.tableLayoutPanel2.Location = new System.Drawing.Point(12, 12); + this.tableLayoutPanel2.Location = new System.Drawing.Point(15, 15); this.tableLayoutPanel2.Margin = new System.Windows.Forms.Padding(0); this.tableLayoutPanel2.Name = "tableLayoutPanel2"; this.tableLayoutPanel2.RowCount = 3; this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel2.Size = new System.Drawing.Size(468, 426); + this.tableLayoutPanel2.Size = new System.Drawing.Size(631, 528); this.tableLayoutPanel2.TabIndex = 7; // // tableLayoutPanel6 @@ -490,21 +492,21 @@ this.tableLayoutPanel6.Controls.Add(this.MoveDownButton, 1, 0); this.tableLayoutPanel6.Controls.Add(this.MoveUpButton, 0, 0); this.tableLayoutPanel6.Dock = System.Windows.Forms.DockStyle.Top; - this.tableLayoutPanel6.Location = new System.Drawing.Point(0, 394); + this.tableLayoutPanel6.Location = new System.Drawing.Point(0, 487); this.tableLayoutPanel6.Margin = new System.Windows.Forms.Padding(0); this.tableLayoutPanel6.Name = "tableLayoutPanel6"; this.tableLayoutPanel6.RowCount = 1; this.tableLayoutPanel6.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel6.Size = new System.Drawing.Size(166, 32); + this.tableLayoutPanel6.Size = new System.Drawing.Size(208, 41); this.tableLayoutPanel6.TabIndex = 10; // // MoveDownButton // this.MoveDownButton.Dock = System.Windows.Forms.DockStyle.Right; - this.MoveDownButton.Location = new System.Drawing.Point(86, 6); - this.MoveDownButton.Margin = new System.Windows.Forms.Padding(3, 6, 0, 3); + this.MoveDownButton.Location = new System.Drawing.Point(108, 8); + this.MoveDownButton.Margin = new System.Windows.Forms.Padding(4, 8, 0, 4); this.MoveDownButton.Name = "MoveDownButton"; - this.MoveDownButton.Size = new System.Drawing.Size(80, 23); + this.MoveDownButton.Size = new System.Drawing.Size(100, 29); this.MoveDownButton.TabIndex = 16; this.MoveDownButton.Text = "Move D&own"; this.MoveDownButton.UseVisualStyleBackColor = true; @@ -513,10 +515,10 @@ // MoveUpButton // this.MoveUpButton.Dock = System.Windows.Forms.DockStyle.Left; - this.MoveUpButton.Location = new System.Drawing.Point(0, 6); - this.MoveUpButton.Margin = new System.Windows.Forms.Padding(0, 6, 3, 3); + this.MoveUpButton.Location = new System.Drawing.Point(0, 8); + this.MoveUpButton.Margin = new System.Windows.Forms.Padding(0, 8, 4, 4); this.MoveUpButton.Name = "MoveUpButton"; - this.MoveUpButton.Size = new System.Drawing.Size(80, 23); + this.MoveUpButton.Size = new System.Drawing.Size(100, 29); this.MoveUpButton.TabIndex = 15; this.MoveUpButton.Text = "Move &Up"; this.MoveUpButton.UseVisualStyleBackColor = true; @@ -534,23 +536,24 @@ this.tableLayoutPanel5.Controls.Add(this.ProxyPortTextBox, 1, 0); this.tableLayoutPanel5.Controls.Add(this.ProxyPortLabel, 0, 0); this.tableLayoutPanel5.Controls.Add(this.PortableModeCheckBox, 0, 1); - this.tableLayoutPanel5.Location = new System.Drawing.Point(166, 330); + this.tableLayoutPanel5.Location = new System.Drawing.Point(208, 405); this.tableLayoutPanel5.Margin = new System.Windows.Forms.Padding(0); this.tableLayoutPanel5.Name = "tableLayoutPanel5"; - this.tableLayoutPanel5.Padding = new System.Windows.Forms.Padding(3); + this.tableLayoutPanel5.Padding = new System.Windows.Forms.Padding(4, 4, 4, 4); this.tableLayoutPanel5.RowCount = 2; this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel5.Size = new System.Drawing.Size(196, 64); + this.tableLayoutPanel5.Size = new System.Drawing.Size(251, 82); this.tableLayoutPanel5.TabIndex = 9; // // ProxyPortTextBox // this.ProxyPortTextBox.Anchor = System.Windows.Forms.AnchorStyles.Left; - this.ProxyPortTextBox.Location = new System.Drawing.Point(77, 6); + this.ProxyPortTextBox.Location = new System.Drawing.Point(103, 8); + this.ProxyPortTextBox.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.ProxyPortTextBox.MaxLength = 10; this.ProxyPortTextBox.Name = "ProxyPortTextBox"; - this.ProxyPortTextBox.Size = new System.Drawing.Size(113, 21); + this.ProxyPortTextBox.Size = new System.Drawing.Size(140, 25); this.ProxyPortTextBox.TabIndex = 10; this.ProxyPortTextBox.WordWrap = false; // @@ -558,9 +561,10 @@ // this.ProxyPortLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.ProxyPortLabel.AutoSize = true; - this.ProxyPortLabel.Location = new System.Drawing.Point(6, 10); + this.ProxyPortLabel.Location = new System.Drawing.Point(8, 13); + this.ProxyPortLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.ProxyPortLabel.Name = "ProxyPortLabel"; - this.ProxyPortLabel.Size = new System.Drawing.Size(65, 12); + this.ProxyPortLabel.Size = new System.Drawing.Size(87, 15); this.ProxyPortLabel.TabIndex = 10; this.ProxyPortLabel.Text = "Proxy Port"; // @@ -569,9 +573,10 @@ this.PortableModeCheckBox.Anchor = System.Windows.Forms.AnchorStyles.Left; this.PortableModeCheckBox.AutoSize = true; this.tableLayoutPanel5.SetColumnSpan(this.PortableModeCheckBox, 2); - this.PortableModeCheckBox.Location = new System.Drawing.Point(6, 37); + this.PortableModeCheckBox.Location = new System.Drawing.Point(8, 48); + this.PortableModeCheckBox.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.PortableModeCheckBox.Name = "PortableModeCheckBox"; - this.PortableModeCheckBox.Size = new System.Drawing.Size(102, 16); + this.PortableModeCheckBox.Size = new System.Drawing.Size(133, 19); this.PortableModeCheckBox.TabIndex = 11; this.PortableModeCheckBox.Text = "Portable Mode"; this.toolTip1.SetToolTip(this.PortableModeCheckBox, "restart required"); @@ -585,17 +590,17 @@ this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); - this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F)); + this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 25F)); this.tableLayoutPanel3.Controls.Add(this.MyCancelButton, 1, 0); this.tableLayoutPanel3.Controls.Add(this.OKButton, 0, 0); this.tableLayoutPanel3.Controls.Add(this.ApplyButton, 2, 0); this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Right; - this.tableLayoutPanel3.Location = new System.Drawing.Point(228, 397); - this.tableLayoutPanel3.Margin = new System.Windows.Forms.Padding(3, 3, 0, 3); + this.tableLayoutPanel3.Location = new System.Drawing.Point(329, 491); + this.tableLayoutPanel3.Margin = new System.Windows.Forms.Padding(4, 4, 0, 4); this.tableLayoutPanel3.Name = "tableLayoutPanel3"; this.tableLayoutPanel3.RowCount = 1; this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel3.Size = new System.Drawing.Size(240, 26); + this.tableLayoutPanel3.Size = new System.Drawing.Size(302, 33); this.tableLayoutPanel3.TabIndex = 8; // // tableLayoutPanel4 @@ -609,22 +614,22 @@ this.tableLayoutPanel4.Controls.Add(this.DeleteButton, 1, 0); this.tableLayoutPanel4.Controls.Add(this.AddButton, 0, 0); this.tableLayoutPanel4.Dock = System.Windows.Forms.DockStyle.Top; - this.tableLayoutPanel4.Location = new System.Drawing.Point(0, 330); + this.tableLayoutPanel4.Location = new System.Drawing.Point(0, 405); this.tableLayoutPanel4.Margin = new System.Windows.Forms.Padding(0); this.tableLayoutPanel4.Name = "tableLayoutPanel4"; this.tableLayoutPanel4.RowCount = 2; this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel4.Size = new System.Drawing.Size(166, 64); + this.tableLayoutPanel4.Size = new System.Drawing.Size(208, 82); this.tableLayoutPanel4.TabIndex = 8; // // DuplicateButton // this.DuplicateButton.Dock = System.Windows.Forms.DockStyle.Left; - this.DuplicateButton.Location = new System.Drawing.Point(0, 38); - this.DuplicateButton.Margin = new System.Windows.Forms.Padding(0, 6, 3, 3); + this.DuplicateButton.Location = new System.Drawing.Point(0, 49); + this.DuplicateButton.Margin = new System.Windows.Forms.Padding(0, 8, 4, 4); this.DuplicateButton.Name = "DuplicateButton"; - this.DuplicateButton.Size = new System.Drawing.Size(80, 23); + this.DuplicateButton.Size = new System.Drawing.Size(100, 29); this.DuplicateButton.TabIndex = 14; this.DuplicateButton.Text = "Dupli&cate"; this.DuplicateButton.UseVisualStyleBackColor = true; @@ -633,19 +638,20 @@ // ConfigForm // this.AcceptButton = this.OKButton; - this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); + this.AutoScaleDimensions = new System.Drawing.SizeF(120F, 120F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; this.AutoSize = true; this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; this.CancelButton = this.MyCancelButton; - this.ClientSize = new System.Drawing.Size(491, 438); + this.ClientSize = new System.Drawing.Size(614, 548); this.Controls.Add(this.tableLayoutPanel2); this.Controls.Add(this.panel2); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "ConfigForm"; - this.Padding = new System.Windows.Forms.Padding(12, 12, 12, 9); + this.Padding = new System.Windows.Forms.Padding(15, 15, 15, 11); this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this.Text = "Edit Servers"; this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.ConfigForm_FormClosed); diff --git a/shadowsocks-csharp/View/ConfigForm.cs b/shadowsocks-csharp/View/ConfigForm.cs index 379edc29..1d94ec79 100755 --- a/shadowsocks-csharp/View/ConfigForm.cs +++ b/shadowsocks-csharp/View/ConfigForm.cs @@ -2,7 +2,9 @@ using Shadowsocks.Controller; using Shadowsocks.Model; using Shadowsocks.Properties; using System; +using System.Collections.Generic; using System.Drawing; +using System.Linq; using System.Windows.Forms; namespace Shadowsocks.View @@ -17,10 +19,86 @@ namespace Shadowsocks.View private bool isChange = false; + private class EncryptionMethod + { + public readonly string name; + public readonly bool deprecated; + + // Edit here to add/delete encryption method displayed in UI + private static string[] deprecatedMethod = new string[] + { + "rc4-md5", + "salsa20", + "chacha20", + "bf-cfb", + }; + private static string[] inuseMethod = new string[] + { + "aes-256-gcm", + "aes-192-gcm", + "aes-128-gcm", + "chacha20-ietf-poly1305", + "xchacha20-ietf-poly1305", + "chacha20-ietf", + "aes-256-cfb", + "aes-192-cfb", + "aes-128-cfb", + "aes-256-ctr", + "aes-192-ctr", + "aes-128-ctr", + "camellia-256-cfb", + "camellia-192-cfb", + "camellia-128-cfb", + }; + public static EncryptionMethod[] AllMethods + { + get + { + if (!init) Init(); + return allMethods; + } + } + private static bool init = false; + private static EncryptionMethod[] allMethods; + private static Dictionary methodByName = new Dictionary(); + private static void Init() + { + var all = new List(); + + all.AddRange(inuseMethod.Select(i => new EncryptionMethod(i, false))); + all.AddRange(deprecatedMethod.Select(d => new EncryptionMethod(d, true))); + + allMethods = all.ToArray(); + foreach (var item in all) + { + methodByName[item.name] = item; + } + init = true; + } + + public static EncryptionMethod GetMethod(string name) + { + if (!init) Init(); + return methodByName[name]; + } + + private EncryptionMethod(string name, bool deprecated) + { + this.name = name; + this.deprecated = deprecated; + } + + public override string ToString() + { + return deprecated ? $"{name} ({I18N.GetString("deprecated")})" : name; + } + } + public ConfigForm(ShadowsocksController controller) { Font = SystemFonts.MessageBoxFont; InitializeComponent(); + EncryptionSelect.Items.AddRange(EncryptionMethod.AllMethods); // a dirty hack ServersListBox.Dock = DockStyle.Fill; @@ -115,7 +193,7 @@ namespace Shadowsocks.View server = address, server_port = addressPort.Value, password = serverPassword, - method = EncryptionSelect.Text, + method = ((EncryptionMethod)EncryptionSelect.SelectedItem).name, plugin = PluginTextBox.Text, plugin_opts = PluginOptionsTextBox.Text, plugin_args = PluginArgumentsTextBox.Text, @@ -316,7 +394,7 @@ namespace Shadowsocks.View IPTextBox.Text = server.server; ServerPortTextBox.Text = server.server_port.ToString(); PasswordTextBox.Text = server.password; - EncryptionSelect.Text = server.method ?? Server.DefaultMethod; + EncryptionSelect.SelectedItem = EncryptionMethod.GetMethod(server.method ?? Server.DefaultMethod); PluginTextBox.Text = server.plugin; PluginOptionsTextBox.Text = server.plugin_opts; PluginArgumentsTextBox.Text = server.plugin_args; From cc71e3009fd77c4ba0d8319dbd4298015065d058 Mon Sep 17 00:00:00 2001 From: celeron533 Date: Thu, 30 Jan 2020 10:31:53 +0800 Subject: [PATCH 14/19] Update translation --- shadowsocks-csharp/Data/i18n.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shadowsocks-csharp/Data/i18n.csv b/shadowsocks-csharp/Data/i18n.csv index f6be9f33..f2bf8a29 100644 --- a/shadowsocks-csharp/Data/i18n.csv +++ b/shadowsocks-csharp/Data/i18n.csv @@ -75,7 +75,7 @@ Apply,Применить,应用,應用,適用 New server,Новый сервер,未配置的服务器,新伺服器,新規サーバー Move &Up,Выше,上移(&U),上移 (&U),上に移動 (&U) Move D&own,Ниже,下移(&O),下移 (&O),下に移動 (&O) -deprecated,不推荐,, +deprecated,Устаревшее,不推荐,不推薦,非推奨 ,,,, #Statistics Config,,,, ,,,, From e15cfacacd4901ea22e83b39eaee2e93ac70f5d5 Mon Sep 17 00:00:00 2001 From: celeron533 Date: Mon, 27 Jan 2020 17:33:58 +0800 Subject: [PATCH 15/19] Refind code and comments --- shadowsocks-csharp/Data/NLog.config | 10 ++++++---- shadowsocks-csharp/Model/Configuration.cs | 5 +++-- shadowsocks-csharp/Model/NlogConfig.cs | 23 ++++++++++++++++------- shadowsocks-csharp/Util/Util.cs | 2 +- shadowsocks-csharp/View/LogForm.cs | 23 +++++++++++++++++++---- 5 files changed, 45 insertions(+), 18 deletions(-) diff --git a/shadowsocks-csharp/Data/NLog.config b/shadowsocks-csharp/Data/NLog.config index 4f9d27e3..05509cff 100644 --- a/shadowsocks-csharp/Data/NLog.config +++ b/shadowsocks-csharp/Data/NLog.config @@ -1,11 +1,13 @@  - + + + - + + + \ No newline at end of file diff --git a/shadowsocks-csharp/Model/Configuration.cs b/shadowsocks-csharp/Model/Configuration.cs index db686288..200cd20c 100644 --- a/shadowsocks-csharp/Model/Configuration.cs +++ b/shadowsocks-csharp/Model/Configuration.cs @@ -127,7 +127,8 @@ namespace Shadowsocks.Model } catch (Exception e) { - logger.Error(e, "Cannot get the log level from NLog config file."); + // todo: route the error to UI since there is no log file in this scenario + logger.Error(e, "Cannot get the log level from NLog config file. Please check if the nlog config file exists with corresponding XML nodes."); } return config; @@ -179,7 +180,7 @@ namespace Shadowsocks.Model } catch(Exception e) { - logger.Error(e, "Cannot set the log level"); + logger.Error(e, "Cannot set the log level to NLog config file. Please check if the nlog config file exists with corresponding XML nodes."); } } catch (IOException e) diff --git a/shadowsocks-csharp/Model/NlogConfig.cs b/shadowsocks-csharp/Model/NlogConfig.cs index fe460a5f..11d6d858 100644 --- a/shadowsocks-csharp/Model/NlogConfig.cs +++ b/shadowsocks-csharp/Model/NlogConfig.cs @@ -22,12 +22,12 @@ namespace Shadowsocks.Model } const string NLOG_CONFIG_FILE_NAME = "NLog.config"; - const string MIN_LEVEL_ATTRIBUTE = "minlevel"; - const string FILE_NAME_ATTRIBUTE = "fileName"; + const string TARGET_MIN_LEVEL_ATTRIBUTE = "minlevel"; + const string LOGGER_FILE_NAME_ATTRIBUTE = "fileName"; XmlDocument doc = new XmlDocument(); - XmlElement logLevelElement; XmlElement logFileNameElement; + XmlElement logLevelElement; /// /// Load the NLog config xml file content @@ -57,7 +57,7 @@ namespace Shadowsocks.Model public LogLevel GetLogLevel() { LogLevel level = LogLevel.Warn; - string levelStr = logLevelElement.GetAttribute(MIN_LEVEL_ATTRIBUTE); + string levelStr = logLevelElement.GetAttribute(TARGET_MIN_LEVEL_ATTRIBUTE); Enum.TryParse(levelStr, out level); return level; } @@ -68,7 +68,7 @@ namespace Shadowsocks.Model /// public string GetLogFileName() { - return logFileNameElement.GetAttribute(FILE_NAME_ATTRIBUTE); + return logFileNameElement.GetAttribute(LOGGER_FILE_NAME_ATTRIBUTE); } /// @@ -77,7 +77,7 @@ namespace Shadowsocks.Model /// public void SetLogLevel(LogLevel logLevel) { - logLevelElement.SetAttribute(MIN_LEVEL_ATTRIBUTE, logLevel.ToString("G")); + logLevelElement.SetAttribute(TARGET_MIN_LEVEL_ATTRIBUTE, logLevel.ToString("G")); } /// @@ -86,9 +86,15 @@ namespace Shadowsocks.Model /// public void SetLogFileName(string fileName) { - logFileNameElement.SetAttribute(FILE_NAME_ATTRIBUTE, fileName); + logFileNameElement.SetAttribute(LOGGER_FILE_NAME_ATTRIBUTE, fileName); } + /// + /// Select a single XML node/elemant + /// + /// + /// + /// private static XmlNode SelectSingleNode(XmlDocument doc, string xpath) { XmlNamespaceManager manager = new XmlNamespaceManager(doc.NameTable); @@ -109,6 +115,9 @@ namespace Shadowsocks.Model } } + /// + /// NLog reload the config file and apply to current LogManager + /// public static void LoadConfiguration() { LogManager.LoadConfiguration(NLOG_CONFIG_FILE_NAME); diff --git a/shadowsocks-csharp/Util/Util.cs b/shadowsocks-csharp/Util/Util.cs index dffd5271..8912eb68 100755 --- a/shadowsocks-csharp/Util/Util.cs +++ b/shadowsocks-csharp/Util/Util.cs @@ -82,7 +82,7 @@ namespace Shadowsocks.Util catch { - logger.Info( + logger.Debug( $"Cannot get Windows 10 system theme mode, return default value 0 (dark mode)."); } diff --git a/shadowsocks-csharp/View/LogForm.cs b/shadowsocks-csharp/View/LogForm.cs index 16f2ad6e..87dffa4b 100644 --- a/shadowsocks-csharp/View/LogForm.cs +++ b/shadowsocks-csharp/View/LogForm.cs @@ -49,7 +49,18 @@ namespace Shadowsocks.View Icon = Icon.FromHandle(Resources.ssw128.GetHicon()); var nLogConfig = NLogConfig.LoadXML(); - this.filename = nLogConfig.GetLogFileName(); + try + { + this.filename = nLogConfig.GetLogFileName(); + } + catch(Exception) + { + // failed to get the file name + } + if (string.IsNullOrEmpty(this.filename)) + { + LogMessageTextBox.AppendText("Cannot get the log file name from NLog config file. Please check if the nlog config file exists with corresponding XML nodes."); + } LogViewerConfig config = controller.GetConfigurationCopy().logViewer; @@ -164,6 +175,8 @@ namespace Shadowsocks.View private void InitContent() { + if (string.IsNullOrEmpty(filename)) + return; using (StreamReader reader = new StreamReader(new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))) { @@ -187,6 +200,11 @@ namespace Shadowsocks.View private void UpdateContent() { + this.Text = I18N.GetString("Log Viewer") + + $" [in: {Utils.FormatBytes(controller.InboundCounter)}, out: {Utils.FormatBytes(controller.OutboundCounter)}]"; + + if (string.IsNullOrEmpty(filename)) + return; try { using (StreamReader reader = new StreamReader(new FileStream(filename, @@ -215,9 +233,6 @@ namespace Shadowsocks.View catch (FileNotFoundException) { } - - this.Text = I18N.GetString("Log Viewer") + - $" [in: {Utils.FormatBytes(controller.InboundCounter)}, out: {Utils.FormatBytes(controller.OutboundCounter)}]"; } private void LogForm_Load(object sender, EventArgs e) From 6922ba164661b893534b2ba26d73bcd0f0a19d3b Mon Sep 17 00:00:00 2001 From: celeron533 Date: Thu, 30 Jan 2020 11:01:31 +0800 Subject: [PATCH 16/19] Fix "clear log" function --- shadowsocks-csharp/View/LogForm.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/shadowsocks-csharp/View/LogForm.cs b/shadowsocks-csharp/View/LogForm.cs index 87dffa4b..ec5751a7 100644 --- a/shadowsocks-csharp/View/LogForm.cs +++ b/shadowsocks-csharp/View/LogForm.cs @@ -308,7 +308,11 @@ namespace Shadowsocks.View #region Clean up the content in LogMessageTextBox. private void DoClearLogs() { - //logger.Clear(); + try + { + File.Delete(filename); + } + catch { } lastOffset = 0; LogMessageTextBox.Clear(); } From 0bda62d9e8807c75bf86773d489d85e969205993 Mon Sep 17 00:00:00 2001 From: Student Main Date: Thu, 13 Feb 2020 09:26:05 +0800 Subject: [PATCH 17/19] deprecate all stream cipher https://github.com/shadowsocks/shadowsocks-org/issues/154 --- shadowsocks-csharp/View/ConfigForm.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/shadowsocks-csharp/View/ConfigForm.cs b/shadowsocks-csharp/View/ConfigForm.cs index 1d94ec79..caab2f6d 100755 --- a/shadowsocks-csharp/View/ConfigForm.cs +++ b/shadowsocks-csharp/View/ConfigForm.cs @@ -31,14 +31,6 @@ namespace Shadowsocks.View "salsa20", "chacha20", "bf-cfb", - }; - private static string[] inuseMethod = new string[] - { - "aes-256-gcm", - "aes-192-gcm", - "aes-128-gcm", - "chacha20-ietf-poly1305", - "xchacha20-ietf-poly1305", "chacha20-ietf", "aes-256-cfb", "aes-192-cfb", @@ -50,6 +42,14 @@ namespace Shadowsocks.View "camellia-192-cfb", "camellia-128-cfb", }; + private static string[] inuseMethod = new string[] + { + "aes-256-gcm", + "aes-192-gcm", + "aes-128-gcm", + "chacha20-ietf-poly1305", + "xchacha20-ietf-poly1305", + }; public static EncryptionMethod[] AllMethods { get From 3f5e308df702a800f81269f7e0c1acaee8c18ce5 Mon Sep 17 00:00:00 2001 From: Student Main Date: Fri, 14 Feb 2020 12:32:22 +0800 Subject: [PATCH 18/19] Use monospace font in PasswordTextBox --- .../View/ConfigForm.Designer.cs | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/shadowsocks-csharp/View/ConfigForm.Designer.cs b/shadowsocks-csharp/View/ConfigForm.Designer.cs index 0642fa77..bc21915a 100755 --- a/shadowsocks-csharp/View/ConfigForm.Designer.cs +++ b/shadowsocks-csharp/View/ConfigForm.Designer.cs @@ -109,7 +109,7 @@ this.tableLayoutPanel1.Location = new System.Drawing.Point(10, 26); this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(0); this.tableLayoutPanel1.Name = "tableLayoutPanel1"; - this.tableLayoutPanel1.Padding = new System.Windows.Forms.Padding(4, 4, 4, 4); + this.tableLayoutPanel1.Padding = new System.Windows.Forms.Padding(4); this.tableLayoutPanel1.RowCount = 12; this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); @@ -142,7 +142,7 @@ // this.PluginTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); this.PluginTextBox.Location = new System.Drawing.Point(151, 165); - this.PluginTextBox.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); + this.PluginTextBox.Margin = new System.Windows.Forms.Padding(4); this.PluginTextBox.MaxLength = 256; this.PluginTextBox.Name = "PluginTextBox"; this.PluginTextBox.Size = new System.Drawing.Size(235, 25); @@ -153,7 +153,7 @@ // this.RemarksTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); this.RemarksTextBox.Location = new System.Drawing.Point(151, 291); - this.RemarksTextBox.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); + this.RemarksTextBox.Margin = new System.Windows.Forms.Padding(4); this.RemarksTextBox.MaxLength = 32; this.RemarksTextBox.Name = "RemarksTextBox"; this.RemarksTextBox.Size = new System.Drawing.Size(235, 25); @@ -198,7 +198,7 @@ // this.IPTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); this.IPTextBox.Location = new System.Drawing.Point(151, 8); - this.IPTextBox.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); + this.IPTextBox.Margin = new System.Windows.Forms.Padding(4); this.IPTextBox.MaxLength = 512; this.IPTextBox.Name = "IPTextBox"; this.IPTextBox.Size = new System.Drawing.Size(235, 25); @@ -209,7 +209,7 @@ // this.ServerPortTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); this.ServerPortTextBox.Location = new System.Drawing.Point(151, 41); - this.ServerPortTextBox.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); + this.ServerPortTextBox.Margin = new System.Windows.Forms.Padding(4); this.ServerPortTextBox.MaxLength = 10; this.ServerPortTextBox.Name = "ServerPortTextBox"; this.ServerPortTextBox.Size = new System.Drawing.Size(235, 25); @@ -219,8 +219,9 @@ // PasswordTextBox // this.PasswordTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); + this.PasswordTextBox.Font = new System.Drawing.Font("Consolas", 9F); this.PasswordTextBox.Location = new System.Drawing.Point(151, 74); - this.PasswordTextBox.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); + this.PasswordTextBox.Margin = new System.Windows.Forms.Padding(4); this.PasswordTextBox.MaxLength = 256; this.PasswordTextBox.Name = "PasswordTextBox"; this.PasswordTextBox.Size = new System.Drawing.Size(235, 25); @@ -248,7 +249,7 @@ this.EncryptionSelect.ImeMode = System.Windows.Forms.ImeMode.NoControl; this.EncryptionSelect.ItemHeight = 15; this.EncryptionSelect.Location = new System.Drawing.Point(151, 134); - this.EncryptionSelect.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); + this.EncryptionSelect.Margin = new System.Windows.Forms.Padding(4); this.EncryptionSelect.Name = "EncryptionSelect"; this.EncryptionSelect.Size = new System.Drawing.Size(235, 23); this.EncryptionSelect.TabIndex = 4; @@ -269,7 +270,7 @@ // this.TimeoutTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); this.TimeoutTextBox.Location = new System.Drawing.Point(151, 324); - this.TimeoutTextBox.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); + this.TimeoutTextBox.Margin = new System.Windows.Forms.Padding(4); this.TimeoutTextBox.MaxLength = 5; this.TimeoutTextBox.Name = "TimeoutTextBox"; this.TimeoutTextBox.Size = new System.Drawing.Size(235, 25); @@ -290,7 +291,7 @@ // this.PluginOptionsTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); this.PluginOptionsTextBox.Location = new System.Drawing.Point(151, 198); - this.PluginOptionsTextBox.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); + this.PluginOptionsTextBox.Margin = new System.Windows.Forms.Padding(4); this.PluginOptionsTextBox.MaxLength = 256; this.PluginOptionsTextBox.Name = "PluginOptionsTextBox"; this.PluginOptionsTextBox.Size = new System.Drawing.Size(235, 25); @@ -303,7 +304,7 @@ | System.Windows.Forms.AnchorStyles.Left))); this.ShowPasswdCheckBox.AutoSize = true; this.ShowPasswdCheckBox.Location = new System.Drawing.Point(151, 107); - this.ShowPasswdCheckBox.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); + this.ShowPasswdCheckBox.Margin = new System.Windows.Forms.Padding(4); this.ShowPasswdCheckBox.Name = "ShowPasswdCheckBox"; this.ShowPasswdCheckBox.Size = new System.Drawing.Size(133, 19); this.ShowPasswdCheckBox.TabIndex = 3; @@ -316,7 +317,7 @@ // this.PluginArgumentsTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); this.PluginArgumentsTextBox.Location = new System.Drawing.Point(151, 258); - this.PluginArgumentsTextBox.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); + this.PluginArgumentsTextBox.Margin = new System.Windows.Forms.Padding(4); this.PluginArgumentsTextBox.MaxLength = 512; this.PluginArgumentsTextBox.Name = "PluginArgumentsTextBox"; this.PluginArgumentsTextBox.Size = new System.Drawing.Size(235, 25); @@ -351,7 +352,7 @@ // this.NeedPluginArgCheckBox.AutoSize = true; this.NeedPluginArgCheckBox.Location = new System.Drawing.Point(151, 231); - this.NeedPluginArgCheckBox.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); + this.NeedPluginArgCheckBox.Margin = new System.Windows.Forms.Padding(4); this.NeedPluginArgCheckBox.Name = "NeedPluginArgCheckBox"; this.NeedPluginArgCheckBox.Size = new System.Drawing.Size(189, 19); this.NeedPluginArgCheckBox.TabIndex = 10; @@ -365,7 +366,7 @@ this.panel2.AutoSize = true; this.panel2.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; this.panel2.Location = new System.Drawing.Point(206, 234); - this.panel2.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); + this.panel2.Margin = new System.Windows.Forms.Padding(4); this.panel2.Name = "panel2"; this.panel2.Size = new System.Drawing.Size(0, 0); this.panel2.TabIndex = 1; @@ -441,7 +442,7 @@ this.ServerGroupBox.Location = new System.Drawing.Point(223, 0); this.ServerGroupBox.Margin = new System.Windows.Forms.Padding(15, 0, 0, 0); this.ServerGroupBox.Name = "ServerGroupBox"; - this.ServerGroupBox.Padding = new System.Windows.Forms.Padding(4, 4, 4, 4); + this.ServerGroupBox.Padding = new System.Windows.Forms.Padding(4); this.ServerGroupBox.Size = new System.Drawing.Size(408, 405); this.ServerGroupBox.TabIndex = 0; this.ServerGroupBox.TabStop = false; @@ -539,7 +540,7 @@ this.tableLayoutPanel5.Location = new System.Drawing.Point(208, 405); this.tableLayoutPanel5.Margin = new System.Windows.Forms.Padding(0); this.tableLayoutPanel5.Name = "tableLayoutPanel5"; - this.tableLayoutPanel5.Padding = new System.Windows.Forms.Padding(4, 4, 4, 4); + this.tableLayoutPanel5.Padding = new System.Windows.Forms.Padding(4); this.tableLayoutPanel5.RowCount = 2; this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle()); @@ -550,7 +551,7 @@ // this.ProxyPortTextBox.Anchor = System.Windows.Forms.AnchorStyles.Left; this.ProxyPortTextBox.Location = new System.Drawing.Point(103, 8); - this.ProxyPortTextBox.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); + this.ProxyPortTextBox.Margin = new System.Windows.Forms.Padding(4); this.ProxyPortTextBox.MaxLength = 10; this.ProxyPortTextBox.Name = "ProxyPortTextBox"; this.ProxyPortTextBox.Size = new System.Drawing.Size(140, 25); @@ -574,7 +575,7 @@ this.PortableModeCheckBox.AutoSize = true; this.tableLayoutPanel5.SetColumnSpan(this.PortableModeCheckBox, 2); this.PortableModeCheckBox.Location = new System.Drawing.Point(8, 48); - this.PortableModeCheckBox.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); + this.PortableModeCheckBox.Margin = new System.Windows.Forms.Padding(4); this.PortableModeCheckBox.Name = "PortableModeCheckBox"; this.PortableModeCheckBox.Size = new System.Drawing.Size(133, 19); this.PortableModeCheckBox.TabIndex = 11; @@ -647,7 +648,7 @@ this.Controls.Add(this.tableLayoutPanel2); this.Controls.Add(this.panel2); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; - this.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); + this.Margin = new System.Windows.Forms.Padding(4); this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "ConfigForm"; From a03e9a5b0a8ce13f1d72a7a23b261a694d3f0e70 Mon Sep 17 00:00:00 2001 From: celeron533 Date: Thu, 20 Feb 2020 21:03:04 +0800 Subject: [PATCH 19/19] Fix LogForm error after deleted log file --- shadowsocks-csharp/View/LogForm.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shadowsocks-csharp/View/LogForm.cs b/shadowsocks-csharp/View/LogForm.cs index ec5751a7..06b0f678 100644 --- a/shadowsocks-csharp/View/LogForm.cs +++ b/shadowsocks-csharp/View/LogForm.cs @@ -175,7 +175,7 @@ namespace Shadowsocks.View private void InitContent() { - if (string.IsNullOrEmpty(filename)) + if (string.IsNullOrEmpty(filename) || !File.Exists(filename)) return; using (StreamReader reader = new StreamReader(new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))) @@ -203,7 +203,7 @@ namespace Shadowsocks.View this.Text = I18N.GetString("Log Viewer") + $" [in: {Utils.FormatBytes(controller.InboundCounter)}, out: {Utils.FormatBytes(controller.OutboundCounter)}]"; - if (string.IsNullOrEmpty(filename)) + if (string.IsNullOrEmpty(filename) || !File.Exists(filename)) return; try {