├── .gitignore ├── LICENSE ├── README.md ├── kcptun-gui.sln └── kcptun-gui ├── 3rd └── Tar │ ├── License.txt │ ├── Readme.txt │ └── Tar.cs ├── App.config ├── Common ├── I18N.cs ├── MyBooleanConverter.cs ├── MyEnumConverter.cs ├── Tar.cs ├── TrafficSize.cs ├── TrafficSpeed.cs └── Utils.cs ├── Controller ├── ConfigurationController.cs ├── FileManager.cs ├── KCPTunnelController.cs ├── Logging.cs ├── MainController.cs ├── Relay │ ├── IRelay.cs │ ├── TcpPipe.cs │ ├── TcpRelay.cs │ ├── UDPPipe.cs │ └── UdpRelay.cs ├── System │ └── AutoStartup.cs └── UpdateChecker.cs ├── FodyWeavers.xml ├── Model ├── Configuration.cs ├── PropertyCategories.cs ├── SNMPConfiguration.cs ├── Server.cs ├── Traffic.cs ├── TrafficLog.cs ├── TrafficStatistics.cs ├── kcptun_crypt.cs └── kcptun_mode.cs ├── Program.cs ├── Properties ├── AssemblyInfo.cs ├── Resources.Designer.cs ├── Resources.resx ├── Settings.Designer.cs └── Settings.settings ├── View ├── Forms │ ├── AboutForm.Designer.cs │ ├── AboutForm.cs │ ├── AboutForm.resx │ ├── CustomKCPTunForm.Designer.cs │ ├── CustomKCPTunForm.cs │ ├── CustomKCPTunForm.resx │ ├── EditServersForm.Designer.cs │ ├── EditServersForm.cs │ ├── EditServersForm.resx │ ├── LogForm.Designer.cs │ ├── LogForm.cs │ ├── LogForm.resx │ ├── SNMPConfigurationForm.Designer.cs │ ├── SNMPConfigurationForm.cs │ ├── SNMPConfigurationForm.resx │ ├── StatisticsForm.Designer.cs │ ├── StatisticsForm.cs │ └── StatisticsForm.resx ├── MenuViewController.cs └── UserControls │ ├── AboutUserControl.Designer.cs │ ├── AboutUserControl.cs │ ├── AboutUserControl.resx │ ├── LogViewerUserControl.Designer.cs │ ├── LogViewerUserControl.cs │ └── LogViewerUserControl.resx ├── data ├── cn.txt ├── en.txt ├── logo-small.ico ├── logo-small.png └── logo.png ├── kcptun-gui.csproj └── packages.config /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | *.VC.VC.opendb 85 | 86 | # Visual Studio profiler 87 | *.psess 88 | *.vsp 89 | *.vspx 90 | *.sap 91 | 92 | # TFS 2012 Local Workspace 93 | $tf/ 94 | 95 | # Guidance Automation Toolkit 96 | *.gpState 97 | 98 | # ReSharper is a .NET coding add-in 99 | _ReSharper*/ 100 | *.[Rr]e[Ss]harper 101 | *.DotSettings.user 102 | 103 | # JustCode is a .NET coding add-in 104 | .JustCode 105 | 106 | # TeamCity is a build add-in 107 | _TeamCity* 108 | 109 | # DotCover is a Code Coverage Tool 110 | *.dotCover 111 | 112 | # NCrunch 113 | _NCrunch_* 114 | .*crunch*.local.xml 115 | nCrunchTemp_* 116 | 117 | # MightyMoose 118 | *.mm.* 119 | AutoTest.Net/ 120 | 121 | # Web workbench (sass) 122 | .sass-cache/ 123 | 124 | # Installshield output folder 125 | [Ee]xpress/ 126 | 127 | # DocProject is a documentation generator add-in 128 | DocProject/buildhelp/ 129 | DocProject/Help/*.HxT 130 | DocProject/Help/*.HxC 131 | DocProject/Help/*.hhc 132 | DocProject/Help/*.hhk 133 | DocProject/Help/*.hhp 134 | DocProject/Help/Html2 135 | DocProject/Help/html 136 | 137 | # Click-Once directory 138 | publish/ 139 | 140 | # Publish Web Output 141 | *.[Pp]ublish.xml 142 | *.azurePubxml 143 | # TODO: Comment the next line if you want to checkin your web deploy settings 144 | # but database connection strings (with potential passwords) will be unencrypted 145 | *.pubxml 146 | *.publishproj 147 | 148 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 149 | # checkin your Azure Web App publish settings, but sensitive information contained 150 | # in these scripts will be unencrypted 151 | PublishScripts/ 152 | 153 | # NuGet Packages 154 | *.nupkg 155 | # The packages folder can be ignored because of Package Restore 156 | **/packages/* 157 | # except build/, which is used as an MSBuild target. 158 | !**/packages/build/ 159 | # Uncomment if necessary however generally it will be regenerated when needed 160 | #!**/packages/repositories.config 161 | # NuGet v3's project.json files produces more ignoreable files 162 | *.nuget.props 163 | *.nuget.targets 164 | 165 | # Microsoft Azure Build Output 166 | csx/ 167 | *.build.csdef 168 | 169 | # Microsoft Azure Emulator 170 | ecf/ 171 | rcf/ 172 | 173 | # Windows Store app package directories and files 174 | AppPackages/ 175 | BundleArtifacts/ 176 | Package.StoreAssociation.xml 177 | _pkginfo.txt 178 | 179 | # Visual Studio cache files 180 | # files ending in .cache can be ignored 181 | *.[Cc]ache 182 | # but keep track of directories ending in .cache 183 | !*.[Cc]ache/ 184 | 185 | # Others 186 | ClientBin/ 187 | ~$* 188 | *~ 189 | *.dbmdl 190 | *.dbproj.schemaview 191 | *.pfx 192 | *.publishsettings 193 | node_modules/ 194 | orleans.codegen.cs 195 | 196 | # Since there are multiple workflows, uncomment next line to ignore bower_components 197 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 198 | #bower_components/ 199 | 200 | # RIA/Silverlight projects 201 | Generated_Code/ 202 | 203 | # Backup & report files from converting an old project file 204 | # to a newer Visual Studio version. Backup files are not needed, 205 | # because we have git ;-) 206 | _UpgradeReport_Files/ 207 | Backup*/ 208 | UpgradeLog*.XML 209 | UpgradeLog*.htm 210 | 211 | # SQL Server files 212 | *.mdf 213 | *.ldf 214 | 215 | # Business Intelligence projects 216 | *.rdl.data 217 | *.bim.layout 218 | *.bim_*.settings 219 | 220 | # Microsoft Fakes 221 | FakesAssemblies/ 222 | 223 | # GhostDoc plugin setting file 224 | *.GhostDoc.xml 225 | 226 | # Node.js Tools for Visual Studio 227 | .ntvs_analysis.dat 228 | 229 | # Visual Studio 6 build log 230 | *.plg 231 | 232 | # Visual Studio 6 workspace options file 233 | *.opt 234 | 235 | # Visual Studio LightSwitch build output 236 | **/*.HTMLClient/GeneratedArtifacts 237 | **/*.DesktopClient/GeneratedArtifacts 238 | **/*.DesktopClient/ModelManifest.xml 239 | **/*.Server/GeneratedArtifacts 240 | **/*.Server/ModelManifest.xml 241 | _Pvt_Extensions 242 | 243 | # Paket dependency manager 244 | .paket/paket.exe 245 | paket-files/ 246 | 247 | # FAKE - F# Make 248 | .fake/ 249 | 250 | # JetBrains Rider 251 | .idea/ 252 | *.sln.iml 253 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Gang Zhuo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # kcptun-gui 2 | GUI for [kcptun]. ([.NET framework 4.5]) 3 | 4 | [![Build Status]][Appveyor] 5 | 6 | ### 功能 7 | 8 | * 可视化参数设置 9 | * 多服务器切换 10 | * 开机启动 11 | * 流量统计(实验性) 12 | * 自动升级 kcptun 客户端 13 | * 支持直接转发 [shadowsocks] UDP 流量到 [shadowsocks] 服务器 14 | * 导入 [kcptun] 配置文件 15 | * 导出服务器配置到 [kcptun] 配置文件 16 | 17 | ### 帮助 18 | 19 | * [Wiki](https://github.com/GangZhuo/kcptun-gui-windows/wiki) 20 | * [使用帮助](https://github.com/GangZhuo/kcptun-gui-windows/wiki/How-to%3F) 21 | * [右键菜单说明](https://github.com/GangZhuo/kcptun-gui-windows/wiki/Context-Menu) 22 | 23 | ### 引用 24 | 25 | * kcptun https://github.com/xtaci/kcptun 26 | * Shadowsocks https://github.com/shadowsocks 27 | 28 | 29 | [Appveyor]: https://ci.appveyor.com/project/GangZhuo/kcptun-gui-windows/branch/master 30 | [Build Status]: https://ci.appveyor.com/api/projects/status/nutdkl99jgj2ryda/branch/master?svg=true 31 | [shadowsocks]: https://github.com/shadowsocks/shadowsocks-windows 32 | [kcptun]: https://github.com/xtaci/kcptun 33 | [.NET framework 4.5]: https://www.microsoft.com/en-us/download/details.aspx?id=30653 34 | 35 | -------------------------------------------------------------------------------- /kcptun-gui.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "kcptun-gui", "kcptun-gui\kcptun-gui.csproj", "{DBBEA80B-2740-4388-B24F-575B0CE922D9}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {DBBEA80B-2740-4388-B24F-575B0CE922D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {DBBEA80B-2740-4388-B24F-575B0CE922D9}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {DBBEA80B-2740-4388-B24F-575B0CE922D9}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {DBBEA80B-2740-4388-B24F-575B0CE922D9}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /kcptun-gui/3rd/Tar/License.txt: -------------------------------------------------------------------------------- 1 | The Microsoft Public License (Ms-PL) 2 | 3 | This license governs use of the accompanying software, the Ionic Tar 4 | library and program ("the software"). If you use the software, you 5 | accept this license. If you do not accept the license, do not use the 6 | software. 7 | 8 | 1. Definitions 9 | 10 | The terms "reproduce," "reproduction," "derivative works," and 11 | "distribution" have the same meaning here as under U.S. copyright 12 | law. 13 | 14 | A "contribution" is the original software, or any additions or 15 | changes to the software. 16 | 17 | A "contributor" is any person that distributes its contribution under 18 | this license. 19 | 20 | "Licensed patents" are a contributor's patent claims that read 21 | directly on its contribution. 22 | 23 | 2. Grant of Rights 24 | 25 | (A) Copyright Grant- Subject to the terms of this license, including 26 | the license conditions and limitations in section 3, each contributor 27 | grants you a non-exclusive, worldwide, royalty-free copyright license 28 | to reproduce its contribution, prepare derivative works of its 29 | contribution, and distribute its contribution or any derivative works 30 | that you create. 31 | 32 | (B) Patent Grant- Subject to the terms of this license, including the 33 | license conditions and limitations in section 3, each contributor 34 | grants you a non-exclusive, worldwide, royalty-free license under its 35 | licensed patents to make, have made, use, sell, offer for sale, 36 | import, and/or otherwise dispose of its contribution in the software 37 | or derivative works of the contribution in the software. 38 | 39 | 3. Conditions and Limitations 40 | 41 | (A) No Trademark License- This license does not grant you rights to 42 | use any contributors' name, logo, or trademarks. 43 | 44 | (B) If you bring a patent claim against any contributor over patents 45 | that you claim are infringed by the software, your patent license 46 | from such contributor to the software ends automatically. 47 | 48 | (C) If you distribute any portion of the software, you must retain 49 | all copyright, patent, trademark, and attribution notices that are 50 | present in the software. 51 | 52 | (D) If you distribute any portion of the software in source code 53 | form, you may do so only under this license by including a complete 54 | copy of this license with your distribution. If you distribute any 55 | portion of the software in compiled or object code form, you may only 56 | do so under a license that complies with this license. 57 | 58 | (E) The software is licensed "as-is." You bear the risk of using 59 | it. The contributors give no express warranties, guarantees or 60 | conditions. You may have additional consumer rights under your local 61 | laws which this license cannot change. To the extent permitted under 62 | your local laws, the contributors exclude the implied warranties of 63 | merchantability, fitness for a particular purpose and 64 | non-infringement. 65 | 66 | -------------------------------------------------------------------------------- /kcptun-gui/3rd/Tar/Readme.txt: -------------------------------------------------------------------------------- 1 | Mon, 16 Nov 2009 09:45 2 | 3 | This is a simple TAR library and command-line tool (application). 4 | 5 | It is implemented in C#, in the source file Tar.cs. It requires .NET 6 | 3.5 at a minimum. It is licensed under the MS-PL, see the License.txt 7 | file. 8 | 9 | If you compile the Tar.cs module with the symbol "EXE" defined (/d:EXE 10 | on the csc.exe command line), then the result will be a console-based 11 | Tar application, much like the one shipped in Unix. Compiled this way, 12 | it has no dependencies on an external Tar dll. This tool can read or 13 | write standard tar files. 14 | 15 | If you compile the Tar.cs module with no EXE symbol defined, then the 16 | result will be a Tar dll, Ionic.Tar.dll, that provides a Tar class, that 17 | can then be used from other applications. 18 | 19 | The supplied makefile builds both of these targets by default. 20 | 21 | 22 | Also included in this package is a source module for a VB tar example 23 | application, supplied in TarApp.vb. When you compile the VB 24 | application, you must reference the Ionic.Tar.dll library. (using 25 | /R:Ionic.Tar.dll on the vbc.exe command line, for example) 26 | 27 | 28 | The Tar.shfbproj file defines the Sandcastle Helpfile Builder project, 29 | which can be used to produce the .chm file. To do this, you need 30 | Sandcastle Helpfile Builder, from http://shfb.codeplex.com/ . 31 | 32 | 33 | The Tar.exe, Ionic.Tar.dll, Ionic.Tar.chm, and VBTarApp.exe targets can be 34 | built from the supplied makefile. 35 | 36 | 37 | 38 | Your Comments are Welcome 39 | --------------------------------- 40 | 41 | Go to this URL to send a comment: 42 | http://cheeso.members.winisp.net/SendComment.aspx?t=Tar 43 | 44 | -------------------------------------------------------------------------------- /kcptun-gui/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /kcptun-gui/Common/I18N.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.ObjectModel; 4 | using System.Globalization; 5 | using System.IO; 6 | using System.Xml; 7 | 8 | using kcptun_gui.Properties; 9 | 10 | namespace kcptun_gui 11 | { 12 | public static class I18N 13 | { 14 | private static ReadOnlyDictionary _langs; 15 | private static Lang _current; 16 | 17 | public static event EventHandler LangChanged; 18 | 19 | public static Lang Current 20 | { 21 | get 22 | { 23 | lock (_langs) 24 | return _current; 25 | } 26 | } 27 | 28 | static I18N() 29 | { 30 | Dictionary langs = new Dictionary(); 31 | Lang en = loadLang("en", "English", Resources.en); 32 | Lang zh_cn = loadLang("zh_CN", "Chinese (Simplified)", Resources.cn); 33 | langs.Add(en.name, en); 34 | langs.Add(zh_cn.name, zh_cn); 35 | 36 | _langs = new ReadOnlyDictionary(langs); 37 | 38 | _current = en; 39 | 40 | if (CultureInfo.CurrentCulture.IetfLanguageTag.StartsWith("zh", StringComparison.OrdinalIgnoreCase)) 41 | _current = zh_cn; 42 | } 43 | 44 | private static Lang loadLang(string name, string fullname, string content) 45 | { 46 | Dictionary strings = new Dictionary(); 47 | 48 | using (var sr = new StringReader(content)) 49 | { 50 | string line; 51 | while ((line = sr.ReadLine()) != null) 52 | { 53 | if (line.Length == 0 || line[0] == '#') 54 | continue; 55 | 56 | int pos = line.IndexOf('='); 57 | if (pos < 1) 58 | continue; 59 | strings[line.Substring(0, pos)] = line.Substring(pos + 1); 60 | } 61 | } 62 | return new Lang(name, fullname, strings); 63 | } 64 | 65 | public static IList GetLangList() 66 | { 67 | return new List(_langs.Values); 68 | } 69 | 70 | public static Lang GetLang(string name) 71 | { 72 | if (name != null && _langs.ContainsKey(name)) 73 | return _langs[name]; 74 | return null; 75 | } 76 | 77 | public static void SetLang(string name) 78 | { 79 | if (name != null && _langs.ContainsKey(name)) 80 | { 81 | Lang lang = _langs[name]; 82 | bool fireEvent = false; 83 | if (_current != lang) 84 | { 85 | lock (_langs) 86 | { 87 | if (_current != lang) 88 | { 89 | _current = lang; 90 | fireEvent = true; 91 | } 92 | } 93 | } 94 | if (fireEvent && LangChanged != null) 95 | LangChanged.Invoke(null, new EventArgs()); 96 | } 97 | else 98 | { 99 | SetLang("en"); 100 | } 101 | } 102 | 103 | public static string GetString(string key) 104 | { 105 | if (_current.strings.ContainsKey(key)) 106 | { 107 | return _current.strings[key]; 108 | } 109 | else 110 | { 111 | return key; 112 | } 113 | } 114 | 115 | public class Lang 116 | { 117 | public string name { get; private set; } 118 | 119 | public string fullname { get; private set; } 120 | 121 | public ReadOnlyDictionary strings { get; private set; } 122 | 123 | public Lang(string name, string fullname, IDictionary strings) 124 | { 125 | this.name = name; 126 | this.fullname = fullname; 127 | this.strings = new ReadOnlyDictionary(strings); 128 | } 129 | } 130 | } 131 | 132 | } 133 | -------------------------------------------------------------------------------- /kcptun-gui/Common/MyBooleanConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Globalization; 4 | using System.Reflection; 5 | 6 | namespace kcptun_gui.Common 7 | { 8 | public class MyBooleanConverter : BooleanConverter 9 | { 10 | public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) 11 | { 12 | return sourceType == typeof(string); 13 | } 14 | 15 | public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) 16 | { 17 | if (string.Equals((string)value, "True", StringComparison.InvariantCultureIgnoreCase) || 18 | string.Equals((string)value, "Yes", StringComparison.InvariantCultureIgnoreCase)) 19 | return true; 20 | return false; 21 | } 22 | 23 | public override bool CanConvertTo(ITypeDescriptorContext context, Type destType) 24 | { 25 | return destType == typeof(string); 26 | } 27 | 28 | public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, 29 | object value, Type destType) 30 | { 31 | if ((bool)value) 32 | return I18N.GetString("Yes"); 33 | else 34 | return I18N.GetString("No"); 35 | } 36 | 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /kcptun-gui/Common/MyEnumConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Globalization; 4 | using System.Reflection; 5 | 6 | namespace kcptun_gui.Common 7 | { 8 | public class MyEnumConverter : EnumConverter 9 | { 10 | private Type enumType; 11 | 12 | public MyEnumConverter(Type type) : base(type) 13 | { 14 | enumType = type; 15 | } 16 | 17 | public override bool CanConvertTo(ITypeDescriptorContext context, Type destType) 18 | { 19 | return destType == typeof(string); 20 | } 21 | 22 | public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, 23 | object value, Type destType) 24 | { 25 | FieldInfo fi = enumType.GetField(Enum.GetName(enumType, value)); 26 | DescriptionAttribute dna = (DescriptionAttribute)Attribute.GetCustomAttribute(fi, 27 | typeof(DescriptionAttribute)); 28 | if (dna != null) 29 | return dna.Description; 30 | else 31 | return value.ToString(); 32 | } 33 | 34 | public override bool CanConvertFrom(ITypeDescriptorContext context, Type srcType) 35 | { 36 | return srcType == typeof(string); 37 | } 38 | 39 | public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, 40 | object value) 41 | { 42 | foreach (FieldInfo fi in enumType.GetFields()) 43 | { 44 | DescriptionAttribute dna = (DescriptionAttribute)Attribute.GetCustomAttribute(fi, 45 | typeof(DescriptionAttribute)); 46 | if ((dna != null) && ((string)value == dna.Description)) 47 | return Enum.Parse(enumType, fi.Name); 48 | } 49 | return Enum.Parse(enumType, (string)value); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /kcptun-gui/Common/Tar.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace kcptun_gui.Common 8 | { 9 | class Tar 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /kcptun-gui/Common/TrafficSize.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace kcptun_gui.Common 4 | { 5 | public class TrafficSize 6 | { 7 | private readonly static string[] units = new string[] { "B", "KiB", "MiB", "GiB", "TiB" }; 8 | 9 | private long _rawValue; 10 | 11 | public long rawValue 12 | { 13 | get { return _rawValue; } 14 | set { SetRawValue(value); } 15 | } 16 | 17 | public long scale { get; private set; } 18 | public float value { get; private set; } 19 | public string unit { get; private set; } 20 | 21 | public TrafficSize() { } 22 | 23 | public TrafficSize(long n) 24 | { 25 | SetRawValue(n); 26 | } 27 | 28 | protected virtual void SetRawValue(long n) 29 | { 30 | _rawValue = n; 31 | long scale = 1; 32 | float f = n; 33 | int unit = 0; 34 | while(f > 1024 && unit < units.Length) 35 | { 36 | f = f / 1024; 37 | scale <<= 10; 38 | unit++; 39 | } 40 | this.scale = scale; 41 | this.value = f; 42 | this.unit = GetUnitName(unit); 43 | } 44 | 45 | protected virtual string GetUnitName(int index) 46 | { 47 | return units[index]; 48 | } 49 | 50 | public override string ToString() 51 | { 52 | return value.ToString("F2") + " " + unit; 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /kcptun-gui/Common/TrafficSpeed.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace kcptun_gui.Common 4 | { 5 | public class TrafficSpeed : TrafficSize 6 | { 7 | public TrafficSpeed() : base() { } 8 | 9 | public TrafficSpeed(long n) : base(n) { } 10 | 11 | protected override string GetUnitName(int index) 12 | { 13 | return base.GetUnitName(index) + "/s"; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /kcptun-gui/Common/Utils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.IO.Compression; 5 | using System.Windows.Forms; 6 | using System.Net; 7 | using System.Net.NetworkInformation; 8 | using kcptun_gui.Controller; 9 | using System.Drawing; 10 | using Microsoft.Win32; 11 | using System.Net.Sockets; 12 | 13 | namespace kcptun_gui.Common 14 | { 15 | public class Utils 16 | { 17 | private static string TempPath = null; 18 | 19 | public static string GetTempPath() 20 | { 21 | if (TempPath == null) 22 | { 23 | if (File.Exists(Path.Combine(Application.StartupPath, "kcptun_portable_mode.txt")) || 24 | File.Exists(Path.Combine(Application.StartupPath, "shadowsocks_portable_mode.txt"))) 25 | try 26 | { 27 | TempPath = Path.Combine(Application.StartupPath, "temp"); 28 | if (!Directory.Exists(TempPath)) 29 | Directory.CreateDirectory(TempPath); 30 | } 31 | catch (Exception e) 32 | { 33 | TempPath = Path.GetTempPath(); 34 | Logging.LogUsefulException(e); 35 | } 36 | else 37 | TempPath = Path.GetTempPath(); 38 | } 39 | return TempPath; 40 | } 41 | 42 | public static string GetTempPath(string filename) 43 | { 44 | return Path.Combine(GetTempPath(), filename); 45 | } 46 | 47 | public static string UnGzip(byte[] buf) 48 | { 49 | byte[] buffer = new byte[1024]; 50 | int n; 51 | using (MemoryStream sb = new MemoryStream()) 52 | { 53 | using (GZipStream input = new GZipStream(new MemoryStream(buf), 54 | CompressionMode.Decompress, 55 | false)) 56 | { 57 | while ((n = input.Read(buffer, 0, buffer.Length)) > 0) 58 | { 59 | sb.Write(buffer, 0, n); 60 | } 61 | } 62 | return System.Text.Encoding.UTF8.GetString(sb.ToArray()); 63 | } 64 | } 65 | 66 | public static int GetFreePort(ProtocolType protocol, int defaultPort = 12948) 67 | { 68 | try 69 | { 70 | IPGlobalProperties properties = IPGlobalProperties.GetIPGlobalProperties(); 71 | IPEndPoint[] activeEndPoints = protocol == ProtocolType.Tcp ? properties.GetActiveTcpListeners() : properties.GetActiveUdpListeners(); 72 | 73 | List usedPorts = new List(); 74 | foreach (IPEndPoint endPoint in activeEndPoints) 75 | { 76 | usedPorts.Add(endPoint.Port); 77 | } 78 | for (int port = defaultPort; port <= 65535; port++) 79 | { 80 | if (!usedPorts.Contains(port)) 81 | { 82 | return port; 83 | } 84 | } 85 | } 86 | catch (Exception e) 87 | { 88 | // in case access denied 89 | Logging.LogUsefulException(e); 90 | return defaultPort; 91 | } 92 | throw new Exception("No free port found."); 93 | } 94 | 95 | public static bool CheckIfTcpPortInUse(int port) 96 | { 97 | IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties(); 98 | IPEndPoint[] ipEndPoints = ipProperties.GetActiveTcpListeners(); 99 | 100 | foreach (IPEndPoint endPoint in ipEndPoints) 101 | { 102 | if (endPoint.Port == port) 103 | { 104 | return true; 105 | } 106 | } 107 | return false; 108 | } 109 | 110 | public static bool CheckIfUdpPortInUse(int port) 111 | { 112 | IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties(); 113 | IPEndPoint[] ipEndPoints = ipProperties.GetActiveUdpListeners(); 114 | 115 | foreach (IPEndPoint endPoint in ipEndPoints) 116 | { 117 | if (endPoint.Port == port) 118 | { 119 | return true; 120 | } 121 | } 122 | return false; 123 | } 124 | 125 | public static string FormatSize(long n) 126 | { 127 | TrafficSize size = new TrafficSize(n); 128 | return size.ToString(); 129 | } 130 | 131 | public static Bitmap ToGray(Bitmap bmp) 132 | { 133 | for (int i = 0; i < bmp.Width; i++) 134 | { 135 | for (int j = 0; j < bmp.Height; j++) 136 | { 137 | Color color = bmp.GetPixel(i, j); 138 | int gray = (int)(color.R * 0.3 + color.G * 0.59 + color.B * 0.11); 139 | Color newColor = Color.FromArgb(color.A, gray, gray, gray); 140 | bmp.SetPixel(i, j, newColor); 141 | } 142 | } 143 | return bmp; 144 | } 145 | 146 | private static Color flyBlue = Color.FromArgb(25, 125, 191); 147 | 148 | public static Bitmap ToBlue(Bitmap bmp) 149 | { 150 | for (int i = 0; i < bmp.Width; i++) 151 | { 152 | for (int j = 0; j < bmp.Height; j++) 153 | { 154 | Color color = bmp.GetPixel(i, j); 155 | // Muliply with flyBlue 156 | int red = color.R * flyBlue.R / 255; 157 | int green = color.G * flyBlue.G / 255; 158 | int blue = color.B * flyBlue.B / 255; 159 | Color newColor = Color.FromArgb(color.A, red, green, blue); 160 | bmp.SetPixel(i, j, newColor); 161 | } 162 | } 163 | return bmp; 164 | } 165 | 166 | public static RegistryKey OpenUserRegKey(string name, bool writable) 167 | { 168 | // we are building x86 binary for both x86 and x64, which will 169 | // cause problem when opening registry key 170 | // detect operating system instead of CPU 171 | RegistryKey userKey = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, 172 | Environment.Is64BitOperatingSystem ? RegistryView.Registry64 : RegistryView.Registry32); 173 | userKey = userKey.OpenSubKey(name, writable); 174 | return userKey; 175 | } 176 | 177 | public static IPEndPoint ToEndPoint(string address) 178 | { 179 | int index = address.LastIndexOf(':'); 180 | string host = address.Substring(0, index); 181 | string port = address.Substring(index + 1); 182 | IPAddress ipAddress; 183 | if (string.IsNullOrEmpty(host)) 184 | ipAddress = IPAddress.Any; 185 | else if (!IPAddress.TryParse(host, out ipAddress)) 186 | ipAddress = Dns.GetHostEntry(host).AddressList[0]; 187 | IPEndPoint ep = new IPEndPoint(ipAddress, Convert.ToInt32(port)); 188 | return ep; 189 | } 190 | } 191 | } 192 | -------------------------------------------------------------------------------- /kcptun-gui/Controller/ConfigurationController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | using kcptun_gui.Model; 4 | 5 | namespace kcptun_gui.Controller 6 | { 7 | public class ConfigurationController 8 | { 9 | private MainController controller; 10 | 11 | private Configuration _config; 12 | 13 | public event EventHandler ConfigChanged; 14 | public event EventHandler EnableChanged; 15 | public event EventHandler VerboseChanged; 16 | public event EventHandler ServerIndexChanged; 17 | public event EventHandler KCPTunPathChanged; 18 | public event EventHandler StatisticsEnableChanged; 19 | public event EventHandler CheckGUIUpdateChanged; 20 | public event EventHandler CheckKCPTunUpdateChanged; 21 | public event EventHandler AutoUpgradeKCPTunChanged; 22 | public event EventHandler LanguageChanged; 23 | public event EventHandler SNMPConfigChanged; 24 | 25 | public ConfigurationController(MainController controller) 26 | { 27 | this.controller = controller; 28 | _config = Configuration.Load(); 29 | if (_config.servers.Count == 0) 30 | { 31 | _config.servers.Add(Configuration.GetDefaultServer()); 32 | _config.index = 0; 33 | } 34 | } 35 | 36 | public Server GetCurrentServer() 37 | { 38 | return _config.GetCurrentServer(); 39 | } 40 | 41 | // always return copy 42 | public Configuration GetConfigurationCopy() 43 | { 44 | return Configuration.Load(); 45 | } 46 | 47 | // always return current instance 48 | public Configuration GetCurrentConfiguration() 49 | { 50 | return _config; 51 | } 52 | 53 | public void ToggleEnable(bool enabled) 54 | { 55 | if (_config.enabled != enabled) 56 | { 57 | _config.enabled = enabled; 58 | SaveConfig(_config); 59 | if (EnableChanged != null) 60 | EnableChanged.Invoke(this, new EventArgs()); 61 | } 62 | } 63 | 64 | public void ToggleVerboseLogging(bool enabled) 65 | { 66 | if (_config.verbose != enabled) 67 | { 68 | _config.verbose = enabled; 69 | SaveConfig(_config); 70 | if (VerboseChanged != null) 71 | VerboseChanged.Invoke(this, new EventArgs()); 72 | } 73 | } 74 | 75 | public void ToggleCheckGUIUpdate(bool enabled) 76 | { 77 | if (_config.check_gui_update != enabled) 78 | { 79 | _config.check_gui_update = enabled; 80 | SaveConfig(_config); 81 | if (CheckGUIUpdateChanged != null) 82 | CheckGUIUpdateChanged.Invoke(this, new EventArgs()); 83 | } 84 | } 85 | 86 | public void ToggleCheckKCPTunUpdate(bool enabled) 87 | { 88 | if (_config.check_kcptun_update != enabled) 89 | { 90 | _config.check_kcptun_update = enabled; 91 | SaveConfig(_config); 92 | if (CheckKCPTunUpdateChanged != null) 93 | CheckKCPTunUpdateChanged.Invoke(this, new EventArgs()); 94 | } 95 | } 96 | 97 | public void ToggleAutoUpgradeKCPTun(bool enabled) 98 | { 99 | if (_config.auto_upgrade_kcptun != enabled) 100 | { 101 | _config.auto_upgrade_kcptun = enabled; 102 | SaveConfig(_config); 103 | if (AutoUpgradeKCPTunChanged != null) 104 | AutoUpgradeKCPTunChanged.Invoke(this, new EventArgs()); 105 | } 106 | } 107 | 108 | public void SelectServerIndex(int index) 109 | { 110 | if (_config.index != index) 111 | { 112 | _config.index = index; 113 | SaveConfig(_config); 114 | if (ServerIndexChanged != null) 115 | ServerIndexChanged.Invoke(this, new EventArgs()); 116 | } 117 | } 118 | 119 | public void SelectLanguage(I18N.Lang lang) 120 | { 121 | if (_config.language != lang.name) 122 | { 123 | _config.language = lang.name; 124 | SaveConfig(_config); 125 | if (LanguageChanged != null) 126 | LanguageChanged.Invoke(this, new EventArgs()); 127 | } 128 | } 129 | 130 | public void ChangeKCPTunPath(string kcptunPath) 131 | { 132 | if (_config.kcptun_path != kcptunPath) 133 | { 134 | _config.kcptun_path = kcptunPath; 135 | SaveConfig(_config); 136 | if (KCPTunPathChanged != null) 137 | KCPTunPathChanged.Invoke(this, new EventArgs()); 138 | } 139 | } 140 | 141 | public void ToggleStatisticsEnable(bool enabled) 142 | { 143 | if (_config.statistics_enabled != enabled) 144 | { 145 | _config.statistics_enabled = enabled; 146 | SaveConfig(_config); 147 | if (StatisticsEnableChanged != null) 148 | StatisticsEnableChanged.Invoke(this, new EventArgs()); 149 | } 150 | } 151 | 152 | public void ChangeSNMPConfig(SNMPConfiguration config) 153 | { 154 | if (!_config.snmp.Equals(config)) 155 | { 156 | _config.snmp = config; 157 | SaveConfig(_config); 158 | if (SNMPConfigChanged != null) 159 | SNMPConfigChanged.Invoke(this, new EventArgs()); 160 | } 161 | } 162 | 163 | public void SaveConfig(Configuration config) 164 | { 165 | Configuration.Save(config); 166 | this._config = config; 167 | if (config.isDefault) 168 | config.isDefault = false; 169 | if (ConfigChanged != null) 170 | ConfigChanged.Invoke(this, new EventArgs()); 171 | } 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /kcptun-gui/Controller/FileManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.IO.Compression; 4 | 5 | namespace kcptun_gui.Controller 6 | { 7 | public class FileManager 8 | { 9 | public static bool ByteArrayToFile(string fileName, byte[] content) 10 | { 11 | try 12 | { 13 | using (var fs = new FileStream(fileName, FileMode.Create, FileAccess.Write)) 14 | fs.Write(content, 0, content.Length); 15 | return true; 16 | } 17 | catch (Exception ex) 18 | { 19 | Console.WriteLine("Exception caught in process: {0}", 20 | ex.ToString()); 21 | } 22 | return false; 23 | } 24 | 25 | public static void UncompressFile(string fileName, byte[] content) 26 | { 27 | // Because the uncompressed size of the file is unknown, 28 | // we are using an arbitrary buffer size. 29 | byte[] buffer = new byte[4096]; 30 | int n; 31 | 32 | using(var fs = File.Create(fileName)) 33 | using (var input = new GZipStream(new MemoryStream(content), 34 | CompressionMode.Decompress, false)) 35 | { 36 | while ((n = input.Read(buffer, 0, buffer.Length)) > 0) 37 | { 38 | fs.Write(buffer, 0, n); 39 | } 40 | } 41 | } 42 | 43 | public static void UncompressFile(string dstFilename, string srcFilename) 44 | { 45 | // Because the uncompressed size of the file is unknown, 46 | // we are using an arbitrary buffer size. 47 | byte[] buffer = new byte[4096]; 48 | int n; 49 | 50 | using (var dst = File.Create(dstFilename)) 51 | using (var src = File.OpenRead(srcFilename)) 52 | using (var input = new GZipStream(src, 53 | CompressionMode.Decompress, false)) 54 | { 55 | while ((n = input.Read(buffer, 0, buffer.Length)) > 0) 56 | { 57 | dst.Write(buffer, 0, n); 58 | } 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /kcptun-gui/Controller/KCPTunnelController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.IO; 4 | using System.Text; 5 | 6 | using kcptun_gui.Model; 7 | using kcptun_gui.Common; 8 | 9 | namespace kcptun_gui.Controller 10 | { 11 | public class KCPTunnelController 12 | { 13 | const string FILENAME = "kcptun-client.exe"; 14 | 15 | private MainController controller; 16 | 17 | private MyProcess _process; 18 | private Server _server; 19 | 20 | public Server Server 21 | { 22 | get 23 | { 24 | return _server; 25 | } 26 | set 27 | { 28 | _server = value; 29 | } 30 | } 31 | 32 | public bool IsRunning 33 | { 34 | get 35 | { 36 | return _process != null; 37 | } 38 | } 39 | 40 | public string localaddr { get; set; } 41 | public string remoteaddr { get; set; } 42 | 43 | public event EventHandler Started; 44 | public event EventHandler Stoped; 45 | 46 | public KCPTunnelController(MainController controller) 47 | { 48 | this.controller = controller; 49 | } 50 | 51 | public string GetKCPTunPath() 52 | { 53 | Configuration config = controller.ConfigController.GetCurrentConfiguration(); 54 | if (string.IsNullOrEmpty(config.kcptun_path)) 55 | { 56 | string path = null; 57 | if (Environment.Is64BitOperatingSystem) 58 | path = "client_windows_amd64.exe"; 59 | else 60 | path = "client_windows_386.exe"; 61 | return path; 62 | } 63 | else 64 | return config.kcptun_path; 65 | } 66 | 67 | public void Start() 68 | { 69 | if (IsRunning) 70 | throw new Exception("Kcptun running"); 71 | if (_server == null) 72 | throw new Exception("No Server"); 73 | 74 | try 75 | { 76 | Configuration config = controller.ConfigController.GetCurrentConfiguration(); 77 | string filename = GetKCPTunPath(); 78 | Console.WriteLine($"kcptun client: {filename}"); 79 | MyProcess p = new MyProcess(_server); 80 | p.StartInfo.FileName = filename; 81 | p.StartInfo.Arguments = BuildArguments(config.snmp, _server, localaddr, remoteaddr); 82 | p.StartInfo.WorkingDirectory = Utils.GetTempPath(); 83 | p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; 84 | p.StartInfo.UseShellExecute = false; 85 | p.StartInfo.CreateNoWindow = true; 86 | p.StartInfo.RedirectStandardError = true; 87 | p.StartInfo.RedirectStandardOutput = true; 88 | p.ErrorDataReceived += OnProcessErrorDataReceived; 89 | p.OutputDataReceived += OnProcessOutputDataReceived; 90 | p.Exited += OnProcessExited; 91 | p.EnableRaisingEvents = true; 92 | p.Start(); 93 | _process = p; 94 | p.BeginOutputReadLine(); 95 | p.BeginErrorReadLine(); 96 | 97 | Console.WriteLine("kcptun client started - " + p.server.FriendlyName()); 98 | 99 | if (Started != null) 100 | Started.Invoke(this, new EventArgs()); 101 | } 102 | catch (Exception e) 103 | { 104 | Logging.LogUsefulException(e); 105 | } 106 | } 107 | 108 | public void Stop() 109 | { 110 | try 111 | { 112 | MyProcess p = _process; 113 | if (p != null) 114 | { 115 | _process = null; 116 | KillProcess(p); 117 | p.Dispose(); 118 | 119 | Console.WriteLine("kcptun client stoped - " + p.server.FriendlyName()); 120 | 121 | if (Stoped != null) 122 | Stoped.Invoke(this, new EventArgs()); 123 | } 124 | } 125 | catch (Exception e) 126 | { 127 | Logging.LogUsefulException(e); 128 | } 129 | } 130 | 131 | private void WriteToLogFile(MyProcess process, string s, bool error) 132 | { 133 | if (s != null) 134 | { 135 | using (StringReader sr = new StringReader(s)) 136 | { 137 | string line; 138 | while ((line = sr.ReadLine()) != null) 139 | { 140 | error = line.IndexOf("[ERR]") >= 0; 141 | if (controller.ConfigController.GetCurrentConfiguration().verbose || error) 142 | { 143 | string formatedMessage = process.server.FriendlyName() + " - " + line; 144 | if (error) 145 | Logging.Error(formatedMessage); 146 | else 147 | Logging.Info(formatedMessage); 148 | } 149 | } 150 | } 151 | } 152 | } 153 | 154 | private void OnProcessOutputDataReceived(object sender, DataReceivedEventArgs e) 155 | { 156 | if (controller.ConfigController.GetCurrentConfiguration().verbose) 157 | WriteToLogFile(sender as MyProcess, e.Data, false); 158 | } 159 | 160 | private void OnProcessErrorDataReceived(object sender, DataReceivedEventArgs e) 161 | { 162 | WriteToLogFile(sender as MyProcess, e.Data, true); 163 | } 164 | 165 | private void OnProcessExited(object sender, EventArgs e) 166 | { 167 | if (sender == _process) 168 | Stop(); 169 | } 170 | 171 | private void KillProcess(Process p) 172 | { 173 | try 174 | { 175 | if (!p.HasExited) 176 | { 177 | p.CloseMainWindow(); 178 | p.WaitForExit(100); 179 | if (!p.HasExited) 180 | { 181 | p.Kill(); 182 | p.WaitForExit(); 183 | } 184 | } 185 | } 186 | catch (Exception e) 187 | { 188 | Logging.LogUsefulException(e); 189 | } 190 | } 191 | 192 | public void KillAll() 193 | { 194 | string filename = Path.GetFileNameWithoutExtension(GetKCPTunPath()); 195 | Process[] processes = Process.GetProcessesByName(filename); 196 | foreach (Process p in processes) 197 | { 198 | KillProcess(p); 199 | } 200 | } 201 | 202 | public string GetKcptunVersion() 203 | { 204 | string version = ""; 205 | try 206 | { 207 | string filename = GetKCPTunPath(); 208 | Console.WriteLine($"kcptun client: {filename}"); 209 | Process p = new Process(); 210 | // Configure the process using the StartInfo properties. 211 | p.StartInfo.FileName = filename; 212 | p.StartInfo.Arguments = "-v"; 213 | p.StartInfo.WorkingDirectory = Utils.GetTempPath(); 214 | p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; 215 | p.StartInfo.UseShellExecute = false; 216 | p.StartInfo.CreateNoWindow = true; 217 | p.StartInfo.RedirectStandardError = true; 218 | p.StartInfo.RedirectStandardOutput = true; 219 | p.Start(); 220 | int count = 300; 221 | while (!p.HasExited && count > 0) 222 | { 223 | p.WaitForExit(100); 224 | count--; 225 | } 226 | if (count == 0) 227 | { 228 | Console.WriteLine("Can't get kcptun client version."); 229 | return version; 230 | } 231 | version = p.StandardOutput.ReadToEnd(); 232 | } 233 | catch (Exception e) 234 | { 235 | Logging.LogUsefulException(e); 236 | } 237 | return version; 238 | } 239 | 240 | public string GetKcptunVersionNumber() 241 | { 242 | string version = GetKcptunVersion(); 243 | string[] sv = version.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); 244 | if (sv.Length == 3) 245 | version = sv[2]; 246 | else 247 | version = "0.0.0"; 248 | return version; 249 | } 250 | 251 | public static string BuildArguments(SNMPConfiguration snmp, Server server) 252 | { 253 | return BuildArguments(snmp, server, null, null); 254 | } 255 | 256 | private static string BuildArguments(SNMPConfiguration snmp, Server server, string localaddr, string remoteaddr) 257 | { 258 | if (string.IsNullOrEmpty(localaddr)) 259 | localaddr = server.localaddr; 260 | if (string.IsNullOrEmpty(remoteaddr)) 261 | remoteaddr = server.remoteaddr; 262 | StringBuilder arguments = new StringBuilder(); 263 | if (server.mode == kcptun_mode.manual_all) 264 | { 265 | arguments.Append($" --localaddr \"{localaddr}\""); 266 | arguments.Append($" --remoteaddr \"{remoteaddr}\""); 267 | arguments.Append($" {server.extend_arguments}"); 268 | } 269 | else 270 | { 271 | MyEnumConverter cryptConverter = new MyEnumConverter(typeof(kcptun_crypt)); 272 | MyEnumConverter modeConverter = new MyEnumConverter(typeof(kcptun_mode)); 273 | arguments.Append($" --localaddr \"{localaddr}\""); 274 | arguments.Append($" --remoteaddr \"{remoteaddr}\""); 275 | if (server.conn >= 0) arguments.Append($" --conn {server.conn}"); 276 | arguments.Append($" --crypt {cryptConverter.ConvertToString(server.crypt)}"); 277 | if (server.crypt != kcptun_crypt.none) 278 | arguments.Append($" --key \"{server.key}\""); 279 | if (server.nocomp) 280 | arguments.Append($" --nocomp"); 281 | arguments.Append($" --mode {modeConverter.ConvertToString(server.mode)}"); 282 | if (server.mode == kcptun_mode.manual) 283 | { 284 | if (server.nodelay >= 0) arguments.Append($" --nodelay {server.nodelay}"); 285 | if (server.resend >= 0) arguments.Append($" --resend {server.resend}"); 286 | if (server.nc >= 0) arguments.Append($" --nc {server.nc}"); 287 | if (server.interval >= 0) arguments.Append($" --interval {server.interval}"); 288 | } 289 | if (server.datashard >= 0) arguments.Append($" --datashard {server.datashard}"); 290 | if (server.parityshard >= 0) arguments.Append($" --parityshard {server.parityshard}"); 291 | if (server.sndwnd >= 0) arguments.Append($" --sndwnd {server.sndwnd}"); 292 | if (server.rcvwnd >= 0) arguments.Append($" --rcvwnd {server.rcvwnd}"); 293 | if (server.mtu >= 0) arguments.Append($" --mtu {server.mtu}"); 294 | if (server.dscp >= 0) arguments.Append($" --dscp {server.dscp}"); 295 | if (server.autoexpire >= 0) arguments.Append($" --autoexpire {server.autoexpire}"); 296 | if (server.sockbuf >= 0) arguments.Append($" --sockbuf {server.sockbuf}"); 297 | arguments.Append($" --acknodelay={server.acknodelay.ToString().ToLower()}"); 298 | if (server.keepalive >= 0) arguments.Append($" --keepalive {server.keepalive}"); 299 | if (!string.IsNullOrEmpty(server.extend_arguments)) 300 | arguments.Append($" {server.extend_arguments}"); 301 | } 302 | if (snmp != null && snmp.enabled) 303 | { 304 | arguments.Append($" --snmplog=\"{snmp.snmplog}\""); 305 | arguments.Append($" --snmpperiod {snmp.snmpperiod}"); 306 | } 307 | return arguments.ToString().Trim(); 308 | } 309 | 310 | class MyProcess: Process 311 | { 312 | public Server server { get; private set; } 313 | 314 | public MyProcess(Server server) 315 | { 316 | this.server = server; 317 | } 318 | } 319 | } 320 | } 321 | -------------------------------------------------------------------------------- /kcptun-gui/Controller/Logging.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Diagnostics; 4 | 5 | using kcptun_gui.Common; 6 | 7 | namespace kcptun_gui.Controller 8 | { 9 | public class Logging 10 | { 11 | public static string LogFilePath; 12 | 13 | private static FileStream fs; 14 | private static StreamWriterWithTimestamp sw; 15 | 16 | public static bool OpenLogFile() 17 | { 18 | try 19 | { 20 | LogFilePath = Utils.GetTempPath("kcptun.log"); 21 | 22 | fs = new FileStream(LogFilePath, FileMode.Append); 23 | sw = new StreamWriterWithTimestamp(fs); 24 | sw.AutoFlush = true; 25 | Console.SetOut(sw); 26 | Console.SetError(sw); 27 | 28 | return true; 29 | } 30 | catch (IOException e) 31 | { 32 | Console.WriteLine(e.ToString()); 33 | return false; 34 | } 35 | } 36 | 37 | private static void WriteToLogFile(object o) 38 | { 39 | try 40 | { 41 | Console.WriteLine(o); 42 | } 43 | catch (ObjectDisposedException) 44 | { 45 | } 46 | } 47 | 48 | public static void Error(object o) 49 | { 50 | WriteToLogFile("[E] " + o); 51 | } 52 | 53 | public static void Info(object o) 54 | { 55 | WriteToLogFile(o); 56 | } 57 | 58 | public static void clear() { 59 | sw.Close(); 60 | sw.Dispose(); 61 | fs.Close(); 62 | fs.Dispose(); 63 | File.Delete(LogFilePath); 64 | OpenLogFile(); 65 | } 66 | 67 | [Conditional("DEBUG")] 68 | public static void Debug(object o) 69 | { 70 | WriteToLogFile("[D] " + o); 71 | } 72 | 73 | public static void LogUsefulException(Exception e) 74 | { 75 | Info(e); 76 | } 77 | } 78 | 79 | // Simply extended System.IO.StreamWriter for adding timestamp workaround 80 | public class StreamWriterWithTimestamp : StreamWriter 81 | { 82 | public StreamWriterWithTimestamp(Stream stream) : base(stream) 83 | { 84 | } 85 | 86 | private string GetTimestamp() 87 | { 88 | return "[" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "] "; 89 | } 90 | 91 | public override void WriteLine(string value) 92 | { 93 | base.WriteLine(GetTimestamp() + value); 94 | } 95 | 96 | public override void Write(string value) 97 | { 98 | base.Write(GetTimestamp() + value); 99 | } 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /kcptun-gui/Controller/MainController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | using System.Net.Sockets; 4 | using System.Threading; 5 | using System.Collections.Generic; 6 | 7 | using kcptun_gui.Model; 8 | using kcptun_gui.Common; 9 | 10 | namespace kcptun_gui.Controller 11 | { 12 | public class MainController 13 | { 14 | private IRelay _tcpRelay; 15 | private IRelay _udpRelay; 16 | private IRelay _ssudpRelay; 17 | private System.Timers.Timer timer; 18 | 19 | private TrafficStatistics _trafficStatistics; 20 | private LinkedList _trafficLogList = new LinkedList(); 21 | 22 | public TrafficLog traffic { get; private set; } = new TrafficLog(); 23 | public LinkedList trafficLogList { get { return _trafficLogList; } } 24 | public int trafficLogSize { get; set; } = 60; // 1 minutes 25 | 26 | public ConfigurationController ConfigController { get; private set; } 27 | public KCPTunnelController KCPTunnelController { get; private set; } 28 | public UpdateChecker UpdateChecker { get; private set; } 29 | 30 | public event EventHandler TrafficChanged; 31 | 32 | public bool IsKcptunRunning 33 | { 34 | get { return KCPTunnelController.IsRunning; } 35 | } 36 | 37 | public MainController() 38 | { 39 | ConfigController = new ConfigurationController(this); 40 | ConfigController.ConfigChanged += OnConfigChanged; 41 | 42 | KCPTunnelController = new KCPTunnelController(this); 43 | UpdateChecker = new UpdateChecker(this); 44 | 45 | _trafficStatistics = TrafficStatistics.Load(); 46 | 47 | } 48 | 49 | public void Start() 50 | { 51 | Reload(); 52 | } 53 | 54 | public void Stop() 55 | { 56 | try 57 | { 58 | if (timer != null) 59 | { 60 | timer.Stop(); 61 | timer.Dispose(); 62 | timer = null; 63 | } 64 | if (_ssudpRelay != null) 65 | { 66 | _ssudpRelay.Stop(); 67 | _ssudpRelay = null; 68 | } 69 | if (_tcpRelay != null) 70 | { 71 | _tcpRelay.Stop(); 72 | _tcpRelay = null; 73 | } 74 | if (_udpRelay != null) 75 | { 76 | _udpRelay.Stop(); 77 | _udpRelay = null; 78 | } 79 | if (KCPTunnelController.IsRunning) 80 | KCPTunnelController.Stop(); 81 | 82 | TrafficStatistics.Save(_trafficStatistics); 83 | } 84 | catch(Exception e) 85 | { 86 | Logging.LogUsefulException(e); 87 | } 88 | } 89 | 90 | public void Reload() 91 | { 92 | try 93 | { 94 | if (timer != null) 95 | { 96 | timer.Stop(); 97 | timer.Dispose(); 98 | timer = null; 99 | } 100 | if (_ssudpRelay != null) 101 | { 102 | _ssudpRelay.Stop(); 103 | _ssudpRelay = null; 104 | } 105 | if (_tcpRelay != null) 106 | { 107 | _tcpRelay.Stop(); 108 | _tcpRelay = null; 109 | } 110 | if (_udpRelay != null) 111 | { 112 | _udpRelay.Stop(); 113 | _udpRelay = null; 114 | } 115 | if (KCPTunnelController.IsRunning) 116 | { 117 | KCPTunnelController.Stop(); 118 | } 119 | Configuration config = ConfigController.GetCurrentConfiguration(); 120 | Server server = config.GetCurrentServer(); 121 | traffic = _trafficStatistics.GetTrafficLog(server); 122 | if (config.enabled) 123 | { 124 | if (server.ss_relay_udp) 125 | { 126 | RelaySSUDPData(server); 127 | } 128 | 129 | KCPTunnelController.Server = server; 130 | KCPTunnelController.localaddr = null; 131 | KCPTunnelController.remoteaddr = null; 132 | if (config.statistics_enabled) 133 | { 134 | RegistStatistics(); 135 | StartTrafficLogger(); 136 | } 137 | KCPTunnelController.Start(); 138 | } 139 | } 140 | catch (Exception e) 141 | { 142 | Logging.LogUsefulException(e); 143 | } 144 | } 145 | 146 | public void ClearTrafficList() 147 | { 148 | lock (_trafficLogList) 149 | { 150 | int trafficLogSize = this.trafficLogSize; 151 | if (trafficLogSize < 1) trafficLogSize = 1; 152 | _trafficLogList.Clear(); 153 | while (_trafficLogList.Count < trafficLogSize) _trafficLogList.AddLast(new TrafficLog()); 154 | } 155 | } 156 | 157 | private void RelaySSUDPData(Server server) 158 | { 159 | try 160 | { 161 | IPEndPoint localEP = Utils.ToEndPoint(server.localaddr); 162 | localEP = new IPEndPoint(IPAddress.Loopback, localEP.Port); 163 | IPEndPoint remoteEP = Utils.ToEndPoint(server.ss_server); 164 | _ssudpRelay = new UDPRelay(this, localEP, remoteEP); 165 | _ssudpRelay.Start(); 166 | } 167 | catch(Exception e) 168 | { 169 | Logging.LogUsefulException(e); 170 | } 171 | } 172 | 173 | private void RegistLeftStatistics() 174 | { 175 | Server server = KCPTunnelController.Server; 176 | IPEndPoint localEP = Utils.ToEndPoint(server.localaddr); 177 | IPEndPoint remoteEP = new IPEndPoint( 178 | IPAddress.Loopback, 179 | Utils.GetFreePort(ProtocolType.Tcp, localEP.Port + 1)); 180 | 181 | KCPTunnelController.localaddr = remoteEP.ToString(); 182 | Logging.Debug($"Left: localEP={localEP.ToString()}, remoteEP={remoteEP.ToString()}"); 183 | _tcpRelay = new TCPRelay(this, localEP, remoteEP); 184 | _tcpRelay.Inbound += _tcpRelay_Inbound; 185 | _tcpRelay.Outbound += _tcpRelay_Outbound; 186 | _tcpRelay.Start(); 187 | } 188 | 189 | private void RegistRightStatistics() 190 | { 191 | Server server = KCPTunnelController.Server; 192 | IPEndPoint localEP = Utils.ToEndPoint(server.localaddr); 193 | localEP = new IPEndPoint( 194 | IPAddress.Loopback, 195 | Utils.GetFreePort(ProtocolType.Udp, localEP.Port + 1)); // Do not use same TCP port, since shadowsocks maybe send data to this port. 196 | IPEndPoint remoteEP = Utils.ToEndPoint(server.remoteaddr); 197 | 198 | KCPTunnelController.remoteaddr = localEP.ToString(); 199 | Logging.Debug($"right: localEP={localEP.ToString()}, remoteEP={remoteEP.ToString()}"); 200 | _udpRelay = new UDPRelay(this, localEP, remoteEP); 201 | _udpRelay.Inbound += _udpRelay_Inbound; 202 | _udpRelay.Outbound += _udpRelay_Outbound; 203 | _udpRelay.Start(); 204 | } 205 | 206 | private void _tcpRelay_Inbound(object sender, RelayEventArgs e) 207 | { 208 | traffic.raw.onInbound(e.Value); 209 | } 210 | 211 | private void _tcpRelay_Outbound(object sender, RelayEventArgs e) 212 | { 213 | traffic.raw.onOutbound(e.Value); 214 | } 215 | 216 | private void _udpRelay_Inbound(object sender, RelayEventArgs e) 217 | { 218 | traffic.kcp.onInbound(e.Value); 219 | } 220 | 221 | private void _udpRelay_Outbound(object sender, RelayEventArgs e) 222 | { 223 | traffic.kcp.onOutbound(e.Value); 224 | } 225 | 226 | private void RegistStatistics() 227 | { 228 | RegistLeftStatistics(); 229 | RegistRightStatistics(); 230 | } 231 | 232 | private void OnConfigChanged(object sender, EventArgs e) 233 | { 234 | Reload(); 235 | } 236 | 237 | private void StartTrafficLogger() 238 | { 239 | ClearTrafficList(); 240 | if (timer == null) 241 | { 242 | timer = new System.Timers.Timer(1000); 243 | timer.Elapsed += Timer_Elapsed; 244 | timer.AutoReset = true; 245 | timer.Enabled = true; 246 | } 247 | timer.Start(); 248 | } 249 | 250 | private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 251 | { 252 | UpdateTrafficList(); 253 | TrafficChanged?.Invoke(this, new EventArgs()); 254 | } 255 | 256 | private void UpdateTrafficList() 257 | { 258 | lock (_trafficLogList) 259 | { 260 | int trafficLogSize = this.trafficLogSize; 261 | if (trafficLogSize < 1) trafficLogSize = 1; 262 | TrafficLog previous = _trafficLogList.Last.Value; 263 | TrafficLog current = new TrafficLog( 264 | new Traffic(traffic.raw), 265 | new Traffic(traffic.raw, previous.raw), 266 | new Traffic(traffic.kcp), 267 | new Traffic(traffic.kcp, previous.kcp)); 268 | _trafficLogList.AddLast(current); 269 | 270 | while (_trafficLogList.Count > trafficLogSize) _trafficLogList.RemoveFirst(); 271 | while (_trafficLogList.Count < trafficLogSize) _trafficLogList.AddFirst(new TrafficLog()); 272 | } 273 | } 274 | } 275 | } 276 | -------------------------------------------------------------------------------- /kcptun-gui/Controller/Relay/IRelay.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | 4 | namespace kcptun_gui.Controller 5 | { 6 | public interface IRelay 7 | { 8 | event EventHandler Inbound; 9 | event EventHandler Outbound; 10 | 11 | void Start(); 12 | void Stop(); 13 | 14 | void onInbound(long n); 15 | void onOutbound(long n); 16 | } 17 | 18 | public class RelayEventArgs : EventArgs 19 | { 20 | public long Value { get; private set; } 21 | 22 | public RelayEventArgs(long value) 23 | { 24 | Value = value; 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /kcptun-gui/Controller/Relay/TcpPipe.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | using System.Net.Sockets; 4 | 5 | namespace kcptun_gui.Controller.Relay 6 | { 7 | public class TCPPipe 8 | { 9 | private IRelay _relay; 10 | private EndPoint _localEP; 11 | private EndPoint _remoteEP; 12 | 13 | public TCPPipe(IRelay relay, EndPoint localEP, EndPoint remoteEP) 14 | { 15 | _relay = relay; 16 | _localEP = localEP; 17 | _remoteEP = remoteEP; 18 | } 19 | 20 | public bool CreatePipe(Socket socket) 21 | { 22 | new Handler(_relay, _localEP, _remoteEP).Start(socket); 23 | return true; 24 | } 25 | 26 | class Handler 27 | { 28 | private IRelay _relay; 29 | private EndPoint _localEP; 30 | private EndPoint _remoteEP; 31 | 32 | private Socket _local; 33 | private Socket _remote; 34 | private bool _closed = false; 35 | public const int RecvSize = 16384; 36 | // remote receive buffer 37 | private byte[] remoteRecvBuffer = new byte[RecvSize]; 38 | // connection receive buffer 39 | private byte[] connetionRecvBuffer = new byte[RecvSize]; 40 | 41 | public Handler(IRelay relay, EndPoint localEP, EndPoint remoteEP) 42 | { 43 | _relay = relay; 44 | _localEP = localEP; 45 | _remoteEP = remoteEP; 46 | } 47 | 48 | public void Start(Socket socket) 49 | { 50 | this._local = socket; 51 | try 52 | { 53 | _remote = new Socket(_remoteEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp); 54 | _remote.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); 55 | 56 | // Connect to the remote endpoint. 57 | _remote.BeginConnect(_remoteEP, new AsyncCallback(ConnectCallback), null); 58 | } 59 | catch (Exception e) 60 | { 61 | Logging.LogUsefulException(e); 62 | this.Close(); 63 | } 64 | } 65 | 66 | private void ConnectCallback(IAsyncResult ar) 67 | { 68 | if (_closed) return; 69 | try 70 | { 71 | _remote.EndConnect(ar); 72 | StartPipe(); 73 | } 74 | catch (Exception e) 75 | { 76 | Logging.LogUsefulException(e); 77 | this.Close(); 78 | } 79 | } 80 | 81 | private void StartPipe() 82 | { 83 | if (_closed) return; 84 | try 85 | { 86 | _remote.BeginReceive(remoteRecvBuffer, 0, RecvSize, 0, new AsyncCallback(PipeRemoteReceiveCallback), null); 87 | _local.BeginReceive(connetionRecvBuffer, 0, RecvSize, 0, new AsyncCallback(PipeConnectionReceiveCallback), null); 88 | } 89 | catch (Exception e) 90 | { 91 | Logging.LogUsefulException(e); 92 | this.Close(); 93 | } 94 | } 95 | 96 | private void PipeRemoteReceiveCallback(IAsyncResult ar) 97 | { 98 | if (_closed) return; 99 | try 100 | { 101 | int bytesRead = _remote.EndReceive(ar); 102 | 103 | if (bytesRead > 0) 104 | { 105 | _relay.onInbound(bytesRead); 106 | _local.BeginSend(remoteRecvBuffer, 0, bytesRead, 0, new AsyncCallback(PipeConnectionSendCallback), null); 107 | } 108 | else 109 | { 110 | this.Close(); 111 | } 112 | } 113 | catch (Exception e) 114 | { 115 | Logging.LogUsefulException(e); 116 | this.Close(); 117 | } 118 | } 119 | 120 | private void PipeConnectionReceiveCallback(IAsyncResult ar) 121 | { 122 | if (_closed) return; 123 | try 124 | { 125 | int bytesRead = _local.EndReceive(ar); 126 | 127 | if (bytesRead > 0) 128 | { 129 | _relay.onOutbound(bytesRead); 130 | _remote.BeginSend(connetionRecvBuffer, 0, bytesRead, 0, new AsyncCallback(PipeRemoteSendCallback), null); 131 | } 132 | else 133 | { 134 | this.Close(); 135 | } 136 | } 137 | catch (Exception e) 138 | { 139 | Logging.LogUsefulException(e); 140 | this.Close(); 141 | } 142 | } 143 | 144 | private void PipeRemoteSendCallback(IAsyncResult ar) 145 | { 146 | if (_closed) return; 147 | try 148 | { 149 | _remote.EndSend(ar); 150 | _local.BeginReceive(this.connetionRecvBuffer, 0, RecvSize, 0, 151 | new AsyncCallback(PipeConnectionReceiveCallback), null); 152 | } 153 | catch (Exception e) 154 | { 155 | Logging.LogUsefulException(e); 156 | this.Close(); 157 | } 158 | } 159 | 160 | private void PipeConnectionSendCallback(IAsyncResult ar) 161 | { 162 | if (_closed) return; 163 | try 164 | { 165 | _local.EndSend(ar); 166 | _remote.BeginReceive(this.remoteRecvBuffer, 0, RecvSize, 0, 167 | new AsyncCallback(PipeRemoteReceiveCallback), null); 168 | } 169 | catch (Exception e) 170 | { 171 | Logging.LogUsefulException(e); 172 | this.Close(); 173 | } 174 | } 175 | 176 | public void Close() 177 | { 178 | if (_closed) return; 179 | _closed = true; 180 | if (_local != null) 181 | { 182 | try 183 | { 184 | // Shutdown ensures that all data is sent and received on the connected socket before it is closed. 185 | // See: 186 | // https://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.shutdown(v=vs.110).aspx 187 | // https://msdn.microsoft.com/en-us/library/windows/desktop/ms738547(v=vs.85).aspx 188 | _local.Shutdown(SocketShutdown.Both); 189 | _local.Close(); 190 | _local = null; 191 | connetionRecvBuffer = null; 192 | } 193 | catch (Exception e) 194 | { 195 | Logging.LogUsefulException(e); 196 | } 197 | } 198 | if (_remote != null) 199 | { 200 | try 201 | { 202 | _remote.Shutdown(SocketShutdown.Both); 203 | _remote.Close(); 204 | _remote = null; 205 | remoteRecvBuffer = null; 206 | } 207 | catch (SocketException e) 208 | { 209 | Logging.LogUsefulException(e); 210 | } 211 | } 212 | } 213 | } 214 | } 215 | } 216 | -------------------------------------------------------------------------------- /kcptun-gui/Controller/Relay/TcpRelay.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Net; 4 | using System.Net.Sockets; 5 | 6 | using kcptun_gui.Controller.Relay; 7 | 8 | namespace kcptun_gui.Controller 9 | { 10 | public class TCPRelay : IRelay 11 | { 12 | private Socket _socket; 13 | private TCPPipe _pipe; 14 | 15 | private MainController _controller; 16 | private EndPoint _localEP; 17 | private EndPoint _remoteEP; 18 | 19 | public event EventHandler Inbound; 20 | public event EventHandler Outbound; 21 | 22 | public TCPRelay(MainController controller, EndPoint localEP, EndPoint remoteEP) 23 | { 24 | _controller = controller; 25 | _localEP = localEP; 26 | _remoteEP = remoteEP; 27 | this._pipe = new TCPPipe(this, localEP, remoteEP); 28 | } 29 | 30 | public void Start() 31 | { 32 | try 33 | { 34 | // Create a TCP/IP socket. 35 | _socket = new Socket(_localEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp); 36 | _socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); 37 | // Bind the socket to the local endpoint and listen for incoming connections. 38 | _socket.Bind(_localEP); 39 | _socket.Listen(1024); 40 | // Start an asynchronous socket to listen for connections. 41 | Console.WriteLine($"TCPRelay listen on {_localEP}, relay to {_remoteEP}"); 42 | _socket.BeginAccept(new AsyncCallback(AcceptCallback), _socket); 43 | } 44 | catch (SocketException) 45 | { 46 | _socket.Close(); 47 | throw; 48 | } 49 | } 50 | 51 | public void Stop() 52 | { 53 | if (_socket != null) 54 | { 55 | _socket.Close(); 56 | _socket = null; 57 | } 58 | } 59 | 60 | public void onInbound(long n) 61 | { 62 | Inbound?.Invoke(this, new Controller.RelayEventArgs(n)); 63 | } 64 | 65 | public void onOutbound(long n) 66 | { 67 | Outbound?.Invoke(this, new Controller.RelayEventArgs(n)); 68 | } 69 | 70 | private void AcceptCallback(IAsyncResult ar) 71 | { 72 | Socket listener = (Socket)ar.AsyncState; 73 | try 74 | { 75 | Socket conn = listener.EndAccept(ar); 76 | if (_pipe.CreatePipe(conn)) 77 | return; 78 | // do nothing 79 | } 80 | catch (ObjectDisposedException) 81 | { 82 | } 83 | catch (Exception e) 84 | { 85 | Logging.LogUsefulException(e); 86 | } 87 | finally 88 | { 89 | try 90 | { 91 | listener.BeginAccept( new AsyncCallback(AcceptCallback), listener); 92 | } 93 | catch (ObjectDisposedException) 94 | { 95 | // do nothing 96 | } 97 | catch (Exception e) 98 | { 99 | Logging.LogUsefulException(e); 100 | } 101 | } 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /kcptun-gui/Controller/Relay/UdpRelay.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Net; 4 | using System.Net.Sockets; 5 | 6 | using kcptun_gui.Controller.Relay; 7 | using System.Threading; 8 | 9 | namespace kcptun_gui.Controller 10 | { 11 | public class UDPRelay : IRelay 12 | { 13 | public class State 14 | { 15 | public byte[] buffer; 16 | public EndPoint remoteEP; 17 | 18 | public State() 19 | { 20 | buffer = new byte[4096]; 21 | remoteEP = (EndPoint)(new IPEndPoint(IPAddress.Any, 0)); 22 | } 23 | } 24 | 25 | private Socket _local; 26 | private UDPPipe _pipe; 27 | private State state = new State(); 28 | 29 | private MainController _controller; 30 | private EndPoint _localEP; 31 | private EndPoint _remoteEP; 32 | 33 | public event EventHandler Inbound; 34 | public event EventHandler Outbound; 35 | 36 | public UDPRelay(MainController controller, EndPoint localEP, EndPoint remoteEP) 37 | { 38 | _controller = controller; 39 | _localEP = localEP; 40 | _remoteEP = remoteEP; 41 | this._pipe = new UDPPipe(this, localEP, remoteEP); 42 | } 43 | 44 | public void Start() 45 | { 46 | try 47 | { 48 | // Create a TCP/IP socket. 49 | _local = new Socket(_localEP.AddressFamily, SocketType.Dgram, ProtocolType.Udp); 50 | _local.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); 51 | const int SIP_UDP_CONNRESET = -1744830452; 52 | // Fix WinSock library bug, See https://support.microsoft.com/en-us/kb/263823 53 | _local.IOControl(SIP_UDP_CONNRESET, new byte[] { 0, 0, 0, 0 }, null); 54 | // Bind the socket to the local endpoint and listen for incoming connections. 55 | _local.Bind(_localEP); 56 | 57 | // Start an asynchronous socket to listen for connections. 58 | Console.WriteLine($"UDPRelay listen on {_localEP}, relay to {_remoteEP}"); 59 | localStartReceive(); 60 | } 61 | catch (SocketException e) 62 | { 63 | Logging.LogUsefulException(e); 64 | Stop(); 65 | } 66 | } 67 | 68 | public void Stop() 69 | { 70 | if (_local != null) 71 | { 72 | try 73 | { 74 | Logging.Debug($"stop udp listen"); 75 | _local.Shutdown(SocketShutdown.Both); 76 | _local.Close(); 77 | } 78 | catch (Exception e) 79 | { 80 | Logging.LogUsefulException(e); 81 | } 82 | _local = null; 83 | } 84 | } 85 | 86 | public void onInbound(long n) 87 | { 88 | Inbound?.Invoke(this, new Controller.RelayEventArgs(n)); 89 | } 90 | 91 | public void onOutbound(long n) 92 | { 93 | Outbound?.Invoke(this, new Controller.RelayEventArgs(n)); 94 | } 95 | 96 | private void localStartReceive() 97 | { 98 | if (_local == null) return; 99 | try 100 | { 101 | _local.BeginReceiveFrom(state.buffer, 0, state.buffer.Length, SocketFlags.None, 102 | ref state.remoteEP, new AsyncCallback(localReceiveCallback), state); 103 | } 104 | catch (Exception e) 105 | { 106 | Logging.LogUsefulException(e); 107 | } 108 | } 109 | 110 | private void localReceiveCallback(IAsyncResult ar) 111 | { 112 | if (_local == null) return; 113 | State state = (State)ar.AsyncState; 114 | try 115 | { 116 | EndPoint remoteEP = (EndPoint)(new IPEndPoint(IPAddress.Any, 0)); 117 | int bytesRead = _local.EndReceiveFrom(ar, ref remoteEP); 118 | Logging.Debug($"recv {bytesRead} bytes from {remoteEP}"); 119 | _pipe.CreatePipe(state.buffer, bytesRead, _local, remoteEP); 120 | } 121 | catch (Exception e) 122 | { 123 | Logging.LogUsefulException(e); 124 | } 125 | finally 126 | { 127 | localStartReceive(); 128 | } 129 | } 130 | 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /kcptun-gui/Controller/System/AutoStartup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | using Microsoft.Win32; 4 | using kcptun_gui.Common; 5 | 6 | namespace kcptun_gui.Controller 7 | { 8 | class AutoStartup 9 | { 10 | static string Key = "kcptun_" + Application.StartupPath.GetHashCode(); 11 | 12 | public static bool Set(bool enabled) 13 | { 14 | RegistryKey runKey = null; 15 | try 16 | { 17 | string path = Application.ExecutablePath; 18 | runKey = Utils.OpenUserRegKey(@"Software\Microsoft\Windows\CurrentVersion\Run", true); 19 | if ( runKey == null ) { 20 | Logging.Error( @"Cannot find HKCU\Software\Microsoft\Windows\CurrentVersion\Run" ); 21 | return false; 22 | } 23 | if (enabled) 24 | { 25 | runKey.SetValue(Key, path); 26 | } 27 | else 28 | { 29 | runKey.DeleteValue(Key); 30 | } 31 | return true; 32 | } 33 | catch (Exception e) 34 | { 35 | Logging.LogUsefulException(e); 36 | return false; 37 | } 38 | finally 39 | { 40 | if (runKey != null) 41 | { 42 | try { runKey.Close(); } 43 | catch (Exception e) 44 | { Logging.LogUsefulException(e); } 45 | } 46 | } 47 | } 48 | 49 | public static bool Check() 50 | { 51 | RegistryKey runKey = null; 52 | try 53 | { 54 | string path = Application.ExecutablePath; 55 | runKey = Utils.OpenUserRegKey(@"Software\Microsoft\Windows\CurrentVersion\Run", true); 56 | if (runKey == null) { 57 | Logging.Error(@"Cannot find HKCU\Software\Microsoft\Windows\CurrentVersion\Run"); 58 | return false; 59 | } 60 | string[] runList = runKey.GetValueNames(); 61 | foreach (string item in runList) 62 | { 63 | if (item.Equals(Key, StringComparison.OrdinalIgnoreCase)) 64 | return true; 65 | } 66 | return false; 67 | } 68 | catch (Exception e) 69 | { 70 | Logging.LogUsefulException(e); 71 | return false; 72 | } 73 | finally 74 | { 75 | if (runKey != null) 76 | { 77 | try { runKey.Close(); } 78 | catch (Exception e) 79 | { Logging.LogUsefulException(e); } 80 | } 81 | } 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /kcptun-gui/FodyWeavers.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /kcptun-gui/Model/Configuration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | using Newtonsoft.Json; 6 | using kcptun_gui.Controller; 7 | 8 | namespace kcptun_gui.Model 9 | { 10 | [Serializable] 11 | public class Configuration 12 | { 13 | public List servers; 14 | 15 | public int index; 16 | 17 | public bool enabled; 18 | 19 | public bool verbose; 20 | 21 | public string kcptun_path; 22 | 23 | public bool statistics_enabled; 24 | 25 | public bool check_gui_update; 26 | 27 | public bool check_kcptun_update; 28 | 29 | public bool auto_upgrade_kcptun; 30 | 31 | public string language; 32 | 33 | public SNMPConfiguration snmp; 34 | 35 | [JsonIgnore] 36 | public bool isDefault; 37 | 38 | private static string CONFIG_FILE = "kcptun-gui-config.json"; 39 | 40 | public Server GetCurrentServer() 41 | { 42 | if (index >= 0 && index < servers.Count) 43 | return servers[index]; 44 | else 45 | return GetDefaultServer(); 46 | } 47 | 48 | public static Configuration Load() 49 | { 50 | try 51 | { 52 | string configContent = File.ReadAllText(CONFIG_FILE); 53 | Configuration config = JsonConvert.DeserializeObject(configContent); 54 | if (config.servers == null) config.servers = new List(); 55 | if (config.snmp == null) config.snmp = new SNMPConfiguration(); 56 | return config; 57 | } 58 | catch (Exception e) 59 | { 60 | if (!(e is FileNotFoundException)) 61 | Logging.LogUsefulException(e); 62 | return new Configuration 63 | { 64 | index = 0, 65 | enabled = false, 66 | isDefault = true, 67 | kcptun_path = "", 68 | statistics_enabled = false, 69 | check_gui_update = true, 70 | check_kcptun_update = true, 71 | auto_upgrade_kcptun = false, 72 | snmp = new SNMPConfiguration(), 73 | servers = new List() 74 | { 75 | GetDefaultServer() 76 | } 77 | }; 78 | } 79 | } 80 | 81 | public static void Save(Configuration config) 82 | { 83 | if (config.index >= config.servers.Count) 84 | config.index = config.servers.Count - 1; 85 | if (config.index <= -1) 86 | config.index = 0; 87 | try 88 | { 89 | using (StreamWriter sw = new StreamWriter(File.Open(CONFIG_FILE, FileMode.Create))) 90 | { 91 | string jsonString = JsonConvert.SerializeObject(config, Formatting.Indented); 92 | sw.Write(jsonString); 93 | sw.Flush(); 94 | } 95 | } 96 | catch (IOException e) 97 | { 98 | Console.Error.WriteLine(e); 99 | } 100 | } 101 | 102 | public static Server GetDefaultServer() 103 | { 104 | return new Server(); 105 | } 106 | 107 | public static Server GetServerFromConfigFile(string file) 108 | { 109 | string configContent = File.ReadAllText(file); 110 | Server server = JsonConvert.DeserializeObject(configContent); 111 | return server; 112 | } 113 | 114 | public static void SaveServer(Server server, string filename) 115 | { 116 | try 117 | { 118 | using (StreamWriter sw = new StreamWriter(File.Open(filename, FileMode.Create))) 119 | { 120 | string jsonString = JsonConvert.SerializeObject(server, Formatting.Indented); 121 | sw.Write(jsonString); 122 | sw.Flush(); 123 | } 124 | } 125 | catch (IOException e) 126 | { 127 | Console.Error.WriteLine(e); 128 | } 129 | } 130 | 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /kcptun-gui/Model/PropertyCategories.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace kcptun_gui.Model 4 | { 5 | public static class PropertyCategories 6 | { 7 | public const string General = "General"; 8 | public const string Security = "Security"; 9 | public const string Mode = "Mode"; 10 | public const string ErrorCorrecting = "Error-correcting"; 11 | public const string WindowSize = "Window size"; 12 | public const string Advance = "Advance"; 13 | public const string Shadowsocks = "Shadowsocks"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /kcptun-gui/Model/SNMPConfiguration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace kcptun_gui.Model 4 | { 5 | public class SNMPConfiguration 6 | { 7 | public bool enabled; 8 | 9 | public string snmplog; 10 | 11 | public int snmpperiod; 12 | 13 | public SNMPConfiguration() 14 | { 15 | enabled = false; 16 | snmplog = ""; 17 | snmpperiod = 60; 18 | } 19 | 20 | public override int GetHashCode() 21 | { 22 | return $"{enabled},{snmplog},{snmpperiod}".GetHashCode(); 23 | } 24 | 25 | public override bool Equals(object obj) 26 | { 27 | if (obj is SNMPConfiguration) 28 | { 29 | SNMPConfiguration a = obj as SNMPConfiguration; 30 | return a.enabled == this.enabled && 31 | a.snmplog == this.snmplog && 32 | a.snmpperiod == this.snmpperiod; 33 | } 34 | return false; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /kcptun-gui/Model/Server.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using kcptun_gui.Common; 4 | using Newtonsoft.Json; 5 | using Newtonsoft.Json.Converters; 6 | 7 | namespace kcptun_gui.Model 8 | { 9 | [Serializable] 10 | [DefaultProperty("remoteaddr")] 11 | public class Server 12 | { 13 | #region Properties 14 | 15 | #region General 16 | 17 | [MyCategory(PropertyCategories.General)] 18 | [MyDescription("mnemonic-name for server")] 19 | public string remarks { get; set; } 20 | 21 | [MyCategory(PropertyCategories.General)] 22 | [MyDescription("local listen address")] 23 | public string localaddr { get; set; } 24 | 25 | [MyCategory(PropertyCategories.General)] 26 | [MyDescription("kcp server address")] 27 | public string remoteaddr { get; set; } 28 | 29 | [MyCategory(PropertyCategories.General)] 30 | [MyDescription("set num of UDP connections to server")] 31 | public int conn { get; set; } 32 | 33 | #endregion 34 | 35 | #region Security 36 | 37 | [MyCategory(PropertyCategories.Security)] 38 | [MyDescription("method for encryption")] 39 | [TypeConverter(typeof(MyEnumConverter))] 40 | [JsonConverter(typeof(StringEnumConverter))] 41 | public kcptun_crypt crypt { get; set; } 42 | 43 | [MyCategory(PropertyCategories.Security)] 44 | [MyDescription("key for communcation")] 45 | public string key { get; set; } 46 | 47 | [MyCategory(PropertyCategories.Security)] 48 | [MyDescription("disable compression")] 49 | [TypeConverter(typeof(MyBooleanConverter))] 50 | public bool nocomp { get; set; } 51 | 52 | #endregion 53 | 54 | #region Mode 55 | 56 | [MyCategory(PropertyCategories.Mode)] 57 | [MyDescription("mode for communication. Ignore all other parameters exclude 'extend arguments', when select 'manual-all'")] 58 | [TypeConverter(typeof(MyEnumConverter))] 59 | [JsonConverter(typeof(StringEnumConverter))] 60 | public kcptun_mode mode { get; set; } 61 | 62 | [MyCategory(PropertyCategories.Mode)] 63 | [MyDescription("enabled on 'manual' mode, ref https://github.com/xtaci/kcptun")] 64 | public int nodelay { get; set; } 65 | 66 | [MyCategory(PropertyCategories.Mode)] 67 | [MyDescription("enabled on 'manual' mode, ref https://github.com/xtaci/kcptun")] 68 | public int resend { get; set; } 69 | 70 | [MyCategory(PropertyCategories.Mode)] 71 | [MyDescription("enabled on 'manual' mode, ref https://github.com/xtaci/kcptun")] 72 | public int nc { get; set; } 73 | 74 | [MyCategory(PropertyCategories.Mode)] 75 | [MyDescription("enabled on 'manual' mode, ref https://github.com/xtaci/kcptun")] 76 | public int interval { get; set; } 77 | 78 | #endregion 79 | 80 | #region Error-correcting 81 | 82 | [MyCategory(PropertyCategories.ErrorCorrecting)] 83 | [MyDescription("Reed-solomon erasure coding - datashard")] 84 | public int datashard { get; set; } 85 | 86 | [MyCategory(PropertyCategories.ErrorCorrecting)] 87 | [MyDescription("Reed-solomon erasure coding - parityshard")] 88 | public int parityshard { get; set; } 89 | 90 | #endregion 91 | 92 | #region Window size 93 | 94 | [MyCategory(PropertyCategories.WindowSize)] 95 | [MyDescription("send window size (num of packets)")] 96 | public int sndwnd { get; set; } 97 | 98 | [MyCategory(PropertyCategories.WindowSize)] 99 | [MyDescription("receive window size (num of packets)")] 100 | public int rcvwnd { get; set; } 101 | 102 | #endregion 103 | 104 | #region Advance 105 | 106 | [MyCategory(PropertyCategories.Advance)] 107 | [MyDescription("set maximum transmission unit for UDP packets")] 108 | public int mtu { get; set; } 109 | 110 | [MyCategory(PropertyCategories.Advance)] 111 | [MyDescription("DSCP(6bit). Ref https://en.wikipedia.org/wiki/Differentiated_services#Commonly_used_DSCP_values")] 112 | public int dscp { get; set; } 113 | 114 | [MyCategory(PropertyCategories.Advance)] 115 | [MyDescription("set auto expiration time(in seconds) for a single UDP connection, 0 to disable")] 116 | public int autoexpire { get; set; } 117 | 118 | [MyCategory(PropertyCategories.Advance)] 119 | [MyDescription("socket buffer size in bytes")] 120 | public int sockbuf { get; set; } 121 | 122 | [MyCategory(PropertyCategories.Advance)] 123 | [MyDescription("nat keepalive interval in seconds")] 124 | public int keepalive { get; set; } 125 | 126 | [MyCategory(PropertyCategories.Advance)] 127 | [MyDescription("flush ack immediately when a packet is received")] 128 | [TypeConverter(typeof(MyBooleanConverter))] 129 | public bool acknodelay { get; set; } 130 | 131 | [MyCategory(PropertyCategories.Advance)] 132 | [MyDisplayName("extend arguments")] 133 | [MyDescription("extend arguments which are append to end of command line")] 134 | public string extend_arguments { get; set; } 135 | 136 | #endregion 137 | 138 | #region Window size 139 | 140 | [MyCategory(PropertyCategories.Shadowsocks)] 141 | [MyDescription("relay udp data which is come from shadowsocks")] 142 | [TypeConverter(typeof(MyBooleanConverter))] 143 | public bool ss_relay_udp { get; set; } 144 | 145 | [MyCategory(PropertyCategories.Shadowsocks)] 146 | [MyDescription("shadowsocks server address")] 147 | public string ss_server { get; set; } 148 | 149 | #endregion 150 | 151 | #endregion 152 | 153 | public Server() 154 | { 155 | localaddr = ":12948"; 156 | remoteaddr = "192.168.1.1:29900"; 157 | key = "it's a secrect"; 158 | crypt = kcptun_crypt.aes; 159 | mode = kcptun_mode.fast; 160 | conn = 1; 161 | mtu = 1350; 162 | sndwnd = 128; 163 | rcvwnd = 1024; 164 | nocomp = false; 165 | datashard = 10; 166 | parityshard = 3; 167 | dscp = 0; 168 | 169 | nodelay = 1; 170 | resend = 2; 171 | nc = 1; 172 | interval = 20; 173 | 174 | remarks = ""; 175 | 176 | autoexpire = 0; 177 | sockbuf = 4194304; 178 | acknodelay = false; 179 | keepalive = 10; 180 | 181 | ss_relay_udp = false; 182 | ss_server = "192.168.1.1:8388"; 183 | } 184 | 185 | public string FriendlyName() 186 | { 187 | if (string.IsNullOrEmpty(remarks)) 188 | return remoteaddr; 189 | else 190 | return $"{remarks} ({remoteaddr})"; 191 | } 192 | 193 | public override int GetHashCode() 194 | { 195 | return remoteaddr.GetHashCode(); 196 | } 197 | 198 | public override bool Equals(object obj) 199 | { 200 | Server o2 = (Server)obj; 201 | return remoteaddr == o2.remoteaddr; 202 | } 203 | 204 | public override string ToString() 205 | { 206 | return FriendlyName(); 207 | } 208 | 209 | public class MyCategoryAttribute: CategoryAttribute 210 | { 211 | public MyCategoryAttribute() { } 212 | 213 | public MyCategoryAttribute(string category) 214 | : base(category) { } 215 | 216 | protected override string GetLocalizedString(string value) 217 | { 218 | return I18N.GetString(value); 219 | } 220 | } 221 | 222 | public class MyDescriptionAttribute: DescriptionAttribute 223 | { 224 | public MyDescriptionAttribute() { } 225 | 226 | public MyDescriptionAttribute(string description) 227 | : base(description) { } 228 | 229 | public override string Description 230 | { 231 | get 232 | { 233 | return I18N.GetString(DescriptionValue); 234 | } 235 | } 236 | } 237 | 238 | public class MyDisplayNameAttribute : DisplayNameAttribute 239 | { 240 | public MyDisplayNameAttribute() { } 241 | 242 | public MyDisplayNameAttribute(string displayName) 243 | : base(displayName) { } 244 | 245 | public override string DisplayName 246 | { 247 | get 248 | { 249 | return I18N.GetString(DisplayNameValue); 250 | } 251 | } 252 | } 253 | } 254 | } 255 | -------------------------------------------------------------------------------- /kcptun-gui/Model/Traffic.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | 4 | namespace kcptun_gui.Model 5 | { 6 | public class Traffic 7 | { 8 | public long inbound = 0; 9 | public long outbound = 0; 10 | 11 | public Traffic() { } 12 | 13 | public Traffic(Traffic t) 14 | { 15 | inbound = t.inbound; 16 | outbound = t.outbound; 17 | } 18 | 19 | public Traffic(Traffic t1, Traffic t2) 20 | { 21 | if (t2.inbound > 0 && t1.inbound >= t2.inbound) 22 | inbound = t1.inbound - t2.inbound; 23 | if (t2.outbound > 0 && t1.outbound >= t2.outbound) 24 | outbound = t1.outbound - t2.outbound; 25 | } 26 | 27 | public void onInbound(long n) 28 | { 29 | Interlocked.Add(ref inbound, n); 30 | } 31 | 32 | public void onOutbound(long n) 33 | { 34 | Interlocked.Add(ref outbound, n); 35 | } 36 | 37 | public void reset() 38 | { 39 | Interlocked.Exchange(ref inbound, 0); 40 | Interlocked.Exchange(ref outbound, 0); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /kcptun-gui/Model/TrafficLog.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace kcptun_gui.Model 4 | { 5 | public class TrafficLog 6 | { 7 | public Traffic raw; 8 | public Traffic kcp; 9 | 10 | [JsonIgnore] 11 | public Traffic rawSpeed; 12 | [JsonIgnore] 13 | public Traffic kcpSpeed; 14 | 15 | public TrafficLog() 16 | { 17 | raw = new Traffic(); 18 | rawSpeed = new Traffic(); 19 | kcp = new Traffic(); 20 | kcpSpeed = new Traffic(); 21 | } 22 | 23 | public TrafficLog(Traffic raw, Traffic rawspeed, Traffic kcp, Traffic kcpspeed) 24 | { 25 | this.raw = raw; 26 | this.rawSpeed = rawspeed; 27 | this.kcp = kcp; 28 | this.kcpSpeed = kcpspeed; 29 | } 30 | 31 | 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /kcptun-gui/Model/TrafficStatistics.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using Newtonsoft.Json; 5 | 6 | using kcptun_gui.Common; 7 | using kcptun_gui.Controller; 8 | 9 | namespace kcptun_gui.Model 10 | { 11 | public class TrafficStatistics : Dictionary 12 | { 13 | private static string TRAFFIC_STATISTICS_FILE = "kcptun-traffic-statistics.json"; 14 | 15 | public TrafficLog GetTrafficLog(Server server) 16 | { 17 | if (this.ContainsKey(server.remoteaddr)) 18 | { 19 | return this[server.remoteaddr]; 20 | } 21 | else 22 | { 23 | TrafficLog log = new TrafficLog(); 24 | this.Add(server.remoteaddr, log); 25 | return log; 26 | } 27 | } 28 | 29 | public static TrafficStatistics Load() 30 | { 31 | try 32 | { 33 | string filename = Utils.GetTempPath(TRAFFIC_STATISTICS_FILE); 34 | string content = File.ReadAllText(filename); 35 | TrafficStatistics instance = JsonConvert.DeserializeObject(content); 36 | if (instance == null) 37 | return new TrafficStatistics(); 38 | return instance; 39 | } 40 | catch (Exception e) 41 | { 42 | if (!(e is FileNotFoundException)) 43 | Logging.LogUsefulException(e); 44 | return new TrafficStatistics(); 45 | } 46 | } 47 | 48 | public static void Save(TrafficStatistics instance) 49 | { 50 | try 51 | { 52 | string filename = Utils.GetTempPath(TRAFFIC_STATISTICS_FILE); 53 | using (StreamWriter sw = new StreamWriter(File.Open(filename, FileMode.Create))) 54 | { 55 | string jsonString = JsonConvert.SerializeObject(instance, Formatting.Indented); 56 | sw.Write(jsonString); 57 | sw.Flush(); 58 | } 59 | } 60 | catch (IOException e) 61 | { 62 | Console.Error.WriteLine(e); 63 | } 64 | } 65 | 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /kcptun-gui/Model/kcptun_crypt.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | 4 | namespace kcptun_gui.Model 5 | { 6 | public enum kcptun_crypt 7 | { 8 | none, 9 | aes, 10 | [Description("aes-128")] 11 | aes_128, 12 | [Description("aes-192")] 13 | aes_192, 14 | blowfish, 15 | cast5, 16 | [Description("3des")] 17 | _3des, 18 | tea, 19 | xor, 20 | salsa20, 21 | xtea, 22 | 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /kcptun-gui/Model/kcptun_mode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | 4 | namespace kcptun_gui.Model 5 | { 6 | public enum kcptun_mode 7 | { 8 | normal, fast3, fast2, fast, 9 | manual, 10 | [Description("manual-all")] 11 | manual_all, 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /kcptun-gui/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Windows.Forms; 4 | 5 | using kcptun_gui.Controller; 6 | using kcptun_gui.View; 7 | using Microsoft.Win32; 8 | 9 | namespace kcptun_gui 10 | { 11 | static class Program 12 | { 13 | static MainController controller; 14 | 15 | /// 16 | /// The main entry point for the application. 17 | /// 18 | [STAThread] 19 | static void Main() 20 | { 21 | Directory.SetCurrentDirectory(Application.StartupPath); 22 | 23 | Application.EnableVisualStyles(); 24 | Application.SetCompatibleTextRenderingDefault(false); 25 | 26 | if (!Logging.OpenLogFile()) 27 | { 28 | MessageBox.Show(string.Format(I18N.GetString("Can't access the file '{0}', it is maybe used by another process."), Logging.LogFilePath), 29 | I18N.GetString("Error"), MessageBoxButtons.OK, MessageBoxIcon.Warning); 30 | } 31 | controller = new MainController(); 32 | MenuViewController viewController = new MenuViewController(controller); 33 | controller.Start(); 34 | Application.ApplicationExit += Application_ApplicationExit; 35 | SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged; 36 | Application.Run(); 37 | } 38 | 39 | private static void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e) 40 | { 41 | switch (e.Mode) 42 | { 43 | case PowerModes.Resume: 44 | Console.WriteLine("os wake up"); 45 | if (controller != null) 46 | { 47 | System.Timers.Timer timer = new System.Timers.Timer(5000); 48 | timer.Elapsed += Timer_Elapsed; 49 | timer.AutoReset = false; 50 | timer.Enabled = true; 51 | timer.Start(); 52 | } 53 | break; 54 | case PowerModes.Suspend: 55 | if (controller != null) 56 | controller.Stop(); 57 | Console.WriteLine("os suspend"); 58 | break; 59 | } 60 | } 61 | 62 | private static void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 63 | { 64 | try 65 | { 66 | if (controller != null) 67 | controller.Start(); 68 | } 69 | catch (Exception ex) 70 | { 71 | Logging.LogUsefulException(ex); 72 | } 73 | finally 74 | { 75 | try 76 | { 77 | System.Timers.Timer timer = (System.Timers.Timer)sender; 78 | timer.Enabled = false; 79 | timer.Stop(); 80 | timer.Dispose(); 81 | } 82 | catch (Exception ex) 83 | { 84 | Logging.LogUsefulException(ex); 85 | } 86 | } 87 | } 88 | 89 | private static void Application_ApplicationExit(object sender, EventArgs e) 90 | { 91 | if (controller != null) 92 | { 93 | controller.Stop(); 94 | controller = null; 95 | } 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /kcptun-gui/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | using kcptun_gui.Controller; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyTitle("kcptun-gui")] 10 | [assembly: AssemblyDescription("gui for kcptun")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("Gang Zhuo")] 13 | [assembly: AssemblyProduct("kcptun-gui")] 14 | [assembly: AssemblyCopyright("Copyright © Microsoft 2016")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | 18 | // Setting ComVisible to false makes the types in this assembly not visible 19 | // to COM components. If you need to access a type in this assembly from 20 | // COM, set the ComVisible attribute to true on that type. 21 | [assembly: ComVisible(false)] 22 | 23 | // The following GUID is for the ID of the typelib if this project is exposed to COM 24 | [assembly: Guid("dbbea80b-2740-4388-b24f-575b0ce922d9")] 25 | 26 | // Version information for an assembly consists of the following four values: 27 | // 28 | // Major Version 29 | // Minor Version 30 | // Build Number 31 | // Revision 32 | // 33 | // You can specify all the values or you can default the Build and Revision Numbers 34 | // by using the '*' as shown below: 35 | // [assembly: AssemblyVersion("1.0.*")] 36 | [assembly: AssemblyVersion(UpdateChecker.GUI_VERSION)] 37 | [assembly: AssemblyFileVersion(UpdateChecker.GUI_VERSION)] 38 | -------------------------------------------------------------------------------- /kcptun-gui/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace kcptun_gui.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("kcptun_gui.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Looks up a localized string similar to # kcptun-gui-windows language file 65 | /// 66 | ///# Context menu 67 | /// 68 | ///Enable=启用/禁用 69 | ///Servers=服务器 70 | ///Edit Servers...=配置服务器... 71 | ///Start/Stop/Restart kcptun client...=启动/停止/重启 kcptun 客户端... 72 | ///Start=启动 73 | ///Restart=重启 74 | ///Stop=停止 75 | ///Kill all kcptun clients=杀死所有 kcptun 客户端 76 | ///Start on Boot=开机启动 77 | ///More...=更多... 78 | ///Turn on KCP Log=启用/禁用 kcptun 日志 79 | ///Custome KCPTun=自定义 kcptun 客户端路径 80 | ///Traffic Statistics=流量统计 81 | ///Show Logs...=查看日志... 82 | ///About...=关于... 83 | ///Quit=退出 84 | ///Update...=更新... 85 | ///Check GUI updates...=检测 GUI 版本... 86 | ///Check kcptun updates...=检测 kcptun 版本... 87 | ///Check [rest of string was truncated]";. 88 | /// 89 | internal static string cn { 90 | get { 91 | return ResourceManager.GetString("cn", resourceCulture); 92 | } 93 | } 94 | 95 | /// 96 | /// Looks up a localized string similar to # kcptun-gui-windows language file 97 | /// 98 | ///# Language 99 | /// 100 | ///Chinese (Simplified)=简体中文 101 | ///. 102 | /// 103 | internal static string en { 104 | get { 105 | return ResourceManager.GetString("en", resourceCulture); 106 | } 107 | } 108 | 109 | /// 110 | /// Looks up a localized resource of type System.Drawing.Bitmap. 111 | /// 112 | internal static System.Drawing.Bitmap logo { 113 | get { 114 | object obj = ResourceManager.GetObject("logo", resourceCulture); 115 | return ((System.Drawing.Bitmap)(obj)); 116 | } 117 | } 118 | 119 | /// 120 | /// Looks up a localized resource of type System.Drawing.Bitmap. 121 | /// 122 | internal static System.Drawing.Bitmap logo_small { 123 | get { 124 | object obj = ResourceManager.GetObject("logo_small", resourceCulture); 125 | return ((System.Drawing.Bitmap)(obj)); 126 | } 127 | } 128 | 129 | /// 130 | /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). 131 | /// 132 | internal static System.Drawing.Icon logo_small1 { 133 | get { 134 | object obj = ResourceManager.GetObject("logo_small1", resourceCulture); 135 | return ((System.Drawing.Icon)(obj)); 136 | } 137 | } 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /kcptun-gui/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | ..\data\cn.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 123 | 124 | 125 | ..\data\en.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 126 | 127 | 128 | ..\data\logo.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 129 | 130 | 131 | ..\data\logo-small.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 132 | 133 | 134 | ..\data\logo-small.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 135 | 136 | -------------------------------------------------------------------------------- /kcptun-gui/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace kcptun_gui.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /kcptun-gui/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /kcptun-gui/View/Forms/AboutForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace kcptun_gui.View 2 | { 3 | partial class AboutForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AboutForm)); 32 | this.aboutUserControl1 = new kcptun_gui.View.AboutUserControl(); 33 | this.SuspendLayout(); 34 | // 35 | // aboutUserControl1 36 | // 37 | this.aboutUserControl1.Dock = System.Windows.Forms.DockStyle.Fill; 38 | this.aboutUserControl1.KCPTunVersion = "kcptun version 20160811"; 39 | this.aboutUserControl1.Location = new System.Drawing.Point(0, 0); 40 | this.aboutUserControl1.Name = "aboutUserControl1"; 41 | this.aboutUserControl1.Size = new System.Drawing.Size(502, 259); 42 | this.aboutUserControl1.TabIndex = 0; 43 | // 44 | // AboutForm 45 | // 46 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); 47 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 48 | this.ClientSize = new System.Drawing.Size(502, 259); 49 | this.Controls.Add(this.aboutUserControl1); 50 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; 51 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 52 | this.MaximizeBox = false; 53 | this.MinimizeBox = false; 54 | this.Name = "AboutForm"; 55 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; 56 | this.Text = "About"; 57 | this.ResumeLayout(false); 58 | 59 | } 60 | 61 | #endregion 62 | 63 | private AboutUserControl aboutUserControl1; 64 | } 65 | } -------------------------------------------------------------------------------- /kcptun-gui/View/Forms/AboutForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | using kcptun_gui.Controller; 12 | 13 | namespace kcptun_gui.View 14 | { 15 | public partial class AboutForm : Form 16 | { 17 | private MainController controller; 18 | 19 | public AboutForm(MainController controller) 20 | { 21 | this.controller = controller; 22 | InitializeComponent(); 23 | UpdateText(); 24 | this.aboutUserControl1.KCPTunVersion = controller.KCPTunnelController.GetKcptunVersion(); 25 | controller.ConfigController.KCPTunPathChanged += ConfigController_KCPTunPathChanged; 26 | } 27 | 28 | private void UpdateText() 29 | { 30 | Text = I18N.GetString("About"); 31 | } 32 | 33 | protected override void OnClosing(CancelEventArgs e) 34 | { 35 | controller.ConfigController.KCPTunPathChanged -= ConfigController_KCPTunPathChanged; 36 | base.OnClosing(e); 37 | } 38 | 39 | private void ConfigController_KCPTunPathChanged(object sender, EventArgs e) 40 | { 41 | this.aboutUserControl1.KCPTunVersion = controller.KCPTunnelController.GetKcptunVersion(); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /kcptun-gui/View/Forms/CustomKCPTunForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace kcptun_gui.View.Forms 2 | { 3 | partial class CustomKCPTunForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CustomKCPTunForm)); 32 | this.KcptunClientPathLabel = new System.Windows.Forms.Label(); 33 | this.KcpTunPathTextBox = new System.Windows.Forms.TextBox(); 34 | this.BrowserButton = new System.Windows.Forms.Button(); 35 | this.OkButton = new System.Windows.Forms.Button(); 36 | this.MyCancelButton = new System.Windows.Forms.Button(); 37 | this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog(); 38 | this.SuspendLayout(); 39 | // 40 | // KcptunClientPathLabel 41 | // 42 | this.KcptunClientPathLabel.AutoSize = true; 43 | this.KcptunClientPathLabel.Location = new System.Drawing.Point(12, 19); 44 | this.KcptunClientPathLabel.Name = "KcptunClientPathLabel"; 45 | this.KcptunClientPathLabel.Size = new System.Drawing.Size(73, 13); 46 | this.KcptunClientPathLabel.TabIndex = 0; 47 | this.KcptunClientPathLabel.Text = "Kcptun Client:"; 48 | // 49 | // KcpTunPathTextBox 50 | // 51 | this.KcpTunPathTextBox.Location = new System.Drawing.Point(91, 15); 52 | this.KcpTunPathTextBox.MaxLength = 500; 53 | this.KcpTunPathTextBox.Name = "KcpTunPathTextBox"; 54 | this.KcpTunPathTextBox.Size = new System.Drawing.Size(298, 20); 55 | this.KcpTunPathTextBox.TabIndex = 1; 56 | // 57 | // BrowserButton 58 | // 59 | this.BrowserButton.Location = new System.Drawing.Point(396, 14); 60 | this.BrowserButton.Name = "BrowserButton"; 61 | this.BrowserButton.Size = new System.Drawing.Size(59, 23); 62 | this.BrowserButton.TabIndex = 2; 63 | this.BrowserButton.Text = "Browser"; 64 | this.BrowserButton.UseVisualStyleBackColor = true; 65 | this.BrowserButton.Click += new System.EventHandler(this.BrowserButton_Click); 66 | // 67 | // OkButton 68 | // 69 | this.OkButton.Location = new System.Drawing.Point(274, 54); 70 | this.OkButton.Name = "OkButton"; 71 | this.OkButton.Size = new System.Drawing.Size(75, 23); 72 | this.OkButton.TabIndex = 3; 73 | this.OkButton.Text = "OK"; 74 | this.OkButton.UseVisualStyleBackColor = true; 75 | this.OkButton.Click += new System.EventHandler(this.OkButton_Click); 76 | // 77 | // MyCancelButton 78 | // 79 | this.MyCancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; 80 | this.MyCancelButton.Location = new System.Drawing.Point(366, 54); 81 | this.MyCancelButton.Name = "MyCancelButton"; 82 | this.MyCancelButton.Size = new System.Drawing.Size(75, 23); 83 | this.MyCancelButton.TabIndex = 3; 84 | this.MyCancelButton.Text = "Cancel"; 85 | this.MyCancelButton.UseVisualStyleBackColor = true; 86 | this.MyCancelButton.Click += new System.EventHandler(this.CancelButton_Click); 87 | // 88 | // openFileDialog1 89 | // 90 | this.openFileDialog1.DefaultExt = "exe"; 91 | this.openFileDialog1.FileName = "openFileDialog1"; 92 | this.openFileDialog1.Filter = "Executable files|*.exe|All files|*.*"; 93 | this.openFileDialog1.Title = "Select kcptun executable file..."; 94 | // 95 | // CustomKCPTunForm 96 | // 97 | this.AcceptButton = this.OkButton; 98 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 99 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 100 | this.ClientSize = new System.Drawing.Size(467, 90); 101 | this.Controls.Add(this.MyCancelButton); 102 | this.Controls.Add(this.OkButton); 103 | this.Controls.Add(this.BrowserButton); 104 | this.Controls.Add(this.KcpTunPathTextBox); 105 | this.Controls.Add(this.KcptunClientPathLabel); 106 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; 107 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 108 | this.MaximizeBox = false; 109 | this.MinimizeBox = false; 110 | this.Name = "CustomKCPTunForm"; 111 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; 112 | this.Text = "Set your kcptun path..."; 113 | this.Load += new System.EventHandler(this.CustomKCPTunForm_Load); 114 | this.ResumeLayout(false); 115 | this.PerformLayout(); 116 | 117 | } 118 | 119 | #endregion 120 | 121 | private System.Windows.Forms.Label KcptunClientPathLabel; 122 | private System.Windows.Forms.TextBox KcpTunPathTextBox; 123 | private System.Windows.Forms.Button BrowserButton; 124 | private System.Windows.Forms.Button OkButton; 125 | private System.Windows.Forms.Button MyCancelButton; 126 | private System.Windows.Forms.OpenFileDialog openFileDialog1; 127 | } 128 | } -------------------------------------------------------------------------------- /kcptun-gui/View/Forms/CustomKCPTunForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | using kcptun_gui.Controller; 12 | using kcptun_gui.Model; 13 | 14 | namespace kcptun_gui.View.Forms 15 | { 16 | public partial class CustomKCPTunForm : Form 17 | { 18 | private MainController controller; 19 | private Configuration config; 20 | 21 | public CustomKCPTunForm(MainController controller) 22 | { 23 | this.controller = controller; 24 | config = controller.ConfigController.GetConfigurationCopy(); 25 | InitializeComponent(); 26 | UpdateText(); 27 | controller.ConfigController.KCPTunPathChanged += OnConfigChanged; 28 | } 29 | 30 | private void UpdateText() 31 | { 32 | Text = I18N.GetString("Set your kcptun path..."); 33 | KcptunClientPathLabel.Text = I18N.GetString("Kcptun Client:"); 34 | BrowserButton.Text = I18N.GetString("Browser"); 35 | OkButton.Text = I18N.GetString("OK"); 36 | MyCancelButton.Text = I18N.GetString("Cancel"); 37 | } 38 | 39 | private void CustomKCPTunForm_Load(object sender, EventArgs e) 40 | { 41 | KcpTunPathTextBox.Text = config.kcptun_path; 42 | } 43 | 44 | private void BrowserButton_Click(object sender, EventArgs e) 45 | { 46 | try 47 | { 48 | if (string.IsNullOrEmpty(KcpTunPathTextBox.Text)) 49 | openFileDialog1.FileName = KcpTunPathTextBox.Text; 50 | if (openFileDialog1.ShowDialog() == DialogResult.OK) 51 | { 52 | KcpTunPathTextBox.Text = openFileDialog1.FileName; 53 | } 54 | } 55 | catch(Exception ex) 56 | { 57 | Logging.LogUsefulException(ex); 58 | MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 59 | } 60 | } 61 | 62 | private void OkButton_Click(object sender, EventArgs e) 63 | { 64 | try 65 | { 66 | controller.ConfigController.ChangeKCPTunPath(KcpTunPathTextBox.Text.Trim()); 67 | this.Close(); 68 | } 69 | catch (Exception ex) 70 | { 71 | Logging.LogUsefulException(ex); 72 | MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 73 | } 74 | } 75 | 76 | private void CancelButton_Click(object sender, EventArgs e) 77 | { 78 | try 79 | { 80 | this.Close(); 81 | } 82 | catch (Exception ex) 83 | { 84 | Logging.LogUsefulException(ex); 85 | MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 86 | } 87 | } 88 | 89 | protected override void OnClosing(CancelEventArgs e) 90 | { 91 | controller.ConfigController.KCPTunPathChanged -= OnConfigChanged; 92 | base.OnClosing(e); 93 | } 94 | 95 | private void OnConfigChanged(object sender, EventArgs e) 96 | { 97 | if (KcpTunPathTextBox.Text == config.kcptun_path) 98 | { 99 | config = controller.ConfigController.GetConfigurationCopy(); 100 | KcpTunPathTextBox.Text = config.kcptun_path; 101 | } 102 | else 103 | { 104 | config = controller.ConfigController.GetConfigurationCopy(); 105 | } 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /kcptun-gui/View/Forms/EditServersForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | using kcptun_gui.Controller; 12 | using kcptun_gui.Model; 13 | 14 | namespace kcptun_gui.View 15 | { 16 | public partial class EidtServersForm : Form 17 | { 18 | private MainController controller; 19 | private Configuration _config; 20 | 21 | private int _selectedIndex; 22 | 23 | public EidtServersForm(MainController controller) 24 | { 25 | this.controller = controller; 26 | 27 | InitializeComponent(); 28 | UpdateText(); 29 | 30 | ServerListBox.SelectedIndexChanged += ServerListBox_SelectedIndexChanged; 31 | ServerPropertyGrid.PropertyValueChanged += ServerPropertyGrid_PropertyValueChanged; 32 | 33 | controller.ConfigController.ConfigChanged += OnConfigChanged; 34 | } 35 | 36 | private void UpdateText() 37 | { 38 | Text = I18N.GetString("Edit Servers"); 39 | ServerGroupBox.Text = I18N.GetString("Server"); 40 | ArgumentsLabel.Text = I18N.GetString("Arguments:"); 41 | 42 | AddButton.Text = I18N.GetString("Add"); 43 | DeleteButton.Text = I18N.GetString("Delete"); 44 | MoveUpButton.Text = I18N.GetString("Move Up"); 45 | MoveDownButton.Text = I18N.GetString("Move Down"); 46 | OkButton.Text = I18N.GetString("OK"); 47 | MyCancelButton.Text = I18N.GetString("Cancel"); 48 | ImportButton.Text = I18N.GetString("Import"); 49 | ExportButton.Text = I18N.GetString("Export"); 50 | openFileDialog1.Title = I18N.GetString("Select configuration file ..."); 51 | openFileDialog1.Filter = I18N.GetString("JSON files|*.json|All files|*.*"); 52 | saveFileDialog1.Title = I18N.GetString("Export server to a configuration file ..."); 53 | saveFileDialog1.Filter = I18N.GetString("JSON files|*.json|All files|*.*"); 54 | } 55 | 56 | private void LoadServerList() 57 | { 58 | _config = controller.ConfigController.GetConfigurationCopy(); 59 | 60 | ServerListBox.BeginUpdate(); 61 | ServerListBox.Items.Clear(); 62 | 63 | foreach (Server server in _config.servers) 64 | { 65 | ServerListBox.Items.Add(server.FriendlyName()); 66 | } 67 | 68 | ServerListBox.EndUpdate(); 69 | 70 | if (_selectedIndex >= 0 && _selectedIndex < ServerListBox.Items.Count) 71 | ServerListBox.SelectedIndex = _selectedIndex; 72 | } 73 | 74 | private Server GetSelectedServer() 75 | { 76 | int index = ServerListBox.SelectedIndex; 77 | Server server; 78 | if (index >= 0 && index < _config.servers.Count) 79 | server = _config.servers[index]; 80 | else 81 | server = null; 82 | return server; 83 | } 84 | 85 | private void LoadServer() 86 | { 87 | Server server = GetSelectedServer(); 88 | ServerPropertyGrid.SelectedObject = server; 89 | RefreshServerArgumentTextBox(); 90 | } 91 | 92 | private void RefreshServerArgumentTextBox() 93 | { 94 | Server server = GetSelectedServer(); 95 | if (server != null) 96 | ArgumentsTextBox.Text = KCPTunnelController.BuildArguments(_config.snmp, server); 97 | else 98 | ArgumentsTextBox.Text = ""; 99 | } 100 | 101 | private void RefreshButtons() 102 | { 103 | AddButton.Enabled = true; 104 | DeleteButton.Enabled = ServerListBox.SelectedIndex != -1; 105 | MoveUpButton.Enabled = ServerListBox.SelectedIndex > 0; 106 | MoveDownButton.Enabled = ServerListBox.SelectedIndex < ServerListBox.Items.Count - 1; 107 | } 108 | 109 | private void SaveOldServer() 110 | { 111 | int index = _selectedIndex; 112 | if (index >= 0 && index < _config.servers.Count) 113 | { 114 | Server server = _config.servers[index]; 115 | object prevItem = ServerListBox.Items[index]; 116 | if (prevItem.ToString() != server.FriendlyName()) 117 | { 118 | ServerListBox.Items.RemoveAt(index); 119 | ServerListBox.Items.Insert(index, server.FriendlyName()); 120 | } 121 | } 122 | } 123 | 124 | private void ServerConfigForm_Load(object sender, EventArgs e) 125 | { 126 | LoadServerList(); 127 | RefreshButtons(); 128 | } 129 | 130 | private void ServerPropertyGrid_PropertyValueChanged(object s, PropertyValueChangedEventArgs e) 131 | { 132 | RefreshServerArgumentTextBox(); 133 | } 134 | 135 | private bool indexChangeLock = false; 136 | private void ServerListBox_SelectedIndexChanged(object sender, EventArgs e) 137 | { 138 | if (!indexChangeLock) 139 | { 140 | indexChangeLock = true; 141 | 142 | SaveOldServer(); 143 | _selectedIndex = ServerListBox.SelectedIndex; 144 | LoadServer(); 145 | RefreshButtons(); 146 | 147 | indexChangeLock = false; 148 | } 149 | } 150 | 151 | private void AddButton_Click(object sender, EventArgs e) 152 | { 153 | Server server = Configuration.GetDefaultServer(); 154 | _config.servers.Add(server); 155 | ServerListBox.Items.Add("New Server"); 156 | ServerListBox.SelectedIndex = ServerListBox.Items.Count - 1; 157 | } 158 | 159 | private void DeleteButton_Click(object sender, EventArgs e) 160 | { 161 | int index = ServerListBox.SelectedIndex; 162 | if (index >= 0 && index < _config.servers.Count) 163 | { 164 | _config.servers.RemoveAt(index); 165 | ServerListBox.Items.RemoveAt(index); 166 | _selectedIndex = -1; 167 | if (index < _config.servers.Count) 168 | ServerListBox.SelectedIndex = index; 169 | else if (index > 0) 170 | ServerListBox.SelectedIndex = index - 1; 171 | else 172 | ServerListBox.SelectedIndex = -1; 173 | } 174 | } 175 | 176 | private void MoveUpButton_Click(object sender, EventArgs e) 177 | { 178 | int index = ServerListBox.SelectedIndex; 179 | if (index > 0 && index < _config.servers.Count) 180 | { 181 | Server server = _config.servers[index]; 182 | _config.servers.RemoveAt(index); 183 | _config.servers.Insert(index - 1, server); 184 | _selectedIndex = -1; 185 | ServerListBox.Items.RemoveAt(index); 186 | ServerListBox.Items.Insert(index - 1, server); 187 | ServerListBox.SelectedIndex = index - 1; 188 | } 189 | } 190 | 191 | private void MoveDownButton_Click(object sender, EventArgs e) 192 | { 193 | int index = ServerListBox.SelectedIndex; 194 | if (index >= 0 && index + 1 < _config.servers.Count) 195 | { 196 | Server server = _config.servers[index]; 197 | _config.servers.RemoveAt(index); 198 | _config.servers.Insert(index + 1, server); 199 | _selectedIndex = -1; 200 | ServerListBox.Items.RemoveAt(index); 201 | ServerListBox.Items.Insert(index + 1, server); 202 | ServerListBox.SelectedIndex = index + 1; 203 | } 204 | } 205 | 206 | private void OkButton_Click(object sender, EventArgs e) 207 | { 208 | controller.ConfigController.SaveConfig(_config); 209 | this.Close(); 210 | } 211 | 212 | private void CancelButton_Click(object sender, EventArgs e) 213 | { 214 | this.Close(); 215 | } 216 | 217 | private void ImportButton_Click(object sender, EventArgs e) 218 | { 219 | try 220 | { 221 | if (openFileDialog1.ShowDialog() == DialogResult.OK) 222 | { 223 | string[] files = openFileDialog1.FileNames; 224 | int num = 0; 225 | foreach(string file in files) 226 | { 227 | try 228 | { 229 | Server server = Configuration.GetServerFromConfigFile(file); 230 | _config.servers.Add(server); 231 | num++; 232 | } 233 | catch (Exception ex) 234 | { 235 | Logging.LogUsefulException(ex); 236 | } 237 | } 238 | if (num > 0) 239 | { 240 | controller.ConfigController.SaveConfig(_config); 241 | } 242 | } 243 | } 244 | catch(Exception ex) 245 | { 246 | Logging.LogUsefulException(ex); 247 | MessageBox.Show(ex.Message, I18N.GetString("kcptun-gui"), MessageBoxButtons.OK, MessageBoxIcon.Error); 248 | } 249 | } 250 | 251 | private void ExportButton_Click(object sender, EventArgs e) 252 | { 253 | try 254 | { 255 | Server server = GetSelectedServer(); 256 | if (server.remoteaddr != null) 257 | saveFileDialog1.FileName = server.remoteaddr.Replace(":", ",") + ".json"; 258 | if (saveFileDialog1.ShowDialog() == DialogResult.OK) 259 | { 260 | string filename = saveFileDialog1.FileName; 261 | Configuration.SaveServer(server, filename); 262 | } 263 | } 264 | catch (Exception ex) 265 | { 266 | Logging.LogUsefulException(ex); 267 | MessageBox.Show(ex.Message, I18N.GetString("kcptun-gui"), MessageBoxButtons.OK, MessageBoxIcon.Error); 268 | } 269 | } 270 | 271 | protected override void OnClosing(CancelEventArgs e) 272 | { 273 | controller.ConfigController.ConfigChanged -= OnConfigChanged; 274 | base.OnClosing(e); 275 | } 276 | 277 | private void OnConfigChanged(object sender, EventArgs e) 278 | { 279 | LoadServerList(); 280 | RefreshButtons(); 281 | } 282 | } 283 | } 284 | -------------------------------------------------------------------------------- /kcptun-gui/View/Forms/LogForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace kcptun_gui.View 2 | { 3 | partial class LogForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(LogForm)); 32 | this.menuStrip1 = new System.Windows.Forms.MenuStrip(); 33 | this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 34 | this.openLocationToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 35 | this.viewToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 36 | this.cleanLogsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 37 | this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); 38 | this.wrapTextToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 39 | this.changeFontToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 40 | this.resetFontToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 41 | this.logViewerUserControl1 = new kcptun_gui.View.LogViewerUserControl(); 42 | this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); 43 | this.topMostToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 44 | this.menuStrip1.SuspendLayout(); 45 | this.SuspendLayout(); 46 | // 47 | // menuStrip1 48 | // 49 | this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { 50 | this.fileToolStripMenuItem, 51 | this.viewToolStripMenuItem}); 52 | this.menuStrip1.Location = new System.Drawing.Point(0, 0); 53 | this.menuStrip1.Name = "menuStrip1"; 54 | this.menuStrip1.Size = new System.Drawing.Size(426, 24); 55 | this.menuStrip1.TabIndex = 2; 56 | this.menuStrip1.Text = "menuStrip1"; 57 | // 58 | // fileToolStripMenuItem 59 | // 60 | this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { 61 | this.openLocationToolStripMenuItem}); 62 | this.fileToolStripMenuItem.Name = "fileToolStripMenuItem"; 63 | this.fileToolStripMenuItem.Size = new System.Drawing.Size(35, 20); 64 | this.fileToolStripMenuItem.Text = "File"; 65 | // 66 | // openLocationToolStripMenuItem 67 | // 68 | this.openLocationToolStripMenuItem.Name = "openLocationToolStripMenuItem"; 69 | this.openLocationToolStripMenuItem.Size = new System.Drawing.Size(143, 22); 70 | this.openLocationToolStripMenuItem.Text = "Open Location"; 71 | this.openLocationToolStripMenuItem.Click += new System.EventHandler(this.openLocationToolStripMenuItem_Click); 72 | // 73 | // viewToolStripMenuItem 74 | // 75 | this.viewToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { 76 | this.cleanLogsToolStripMenuItem, 77 | this.toolStripSeparator2, 78 | this.wrapTextToolStripMenuItem, 79 | this.changeFontToolStripMenuItem, 80 | this.resetFontToolStripMenuItem, 81 | this.toolStripSeparator1, 82 | this.topMostToolStripMenuItem}); 83 | this.viewToolStripMenuItem.Name = "viewToolStripMenuItem"; 84 | this.viewToolStripMenuItem.Size = new System.Drawing.Size(41, 20); 85 | this.viewToolStripMenuItem.Text = "View"; 86 | // 87 | // cleanLogsToolStripMenuItem 88 | // 89 | this.cleanLogsToolStripMenuItem.Name = "cleanLogsToolStripMenuItem"; 90 | this.cleanLogsToolStripMenuItem.Size = new System.Drawing.Size(152, 22); 91 | this.cleanLogsToolStripMenuItem.Text = "Clean Logs"; 92 | this.cleanLogsToolStripMenuItem.Click += new System.EventHandler(this.cleanLogsToolStripMenuItem_Click); 93 | // 94 | // toolStripSeparator2 95 | // 96 | this.toolStripSeparator2.Name = "toolStripSeparator2"; 97 | this.toolStripSeparator2.Size = new System.Drawing.Size(149, 6); 98 | // 99 | // wrapTextToolStripMenuItem 100 | // 101 | this.wrapTextToolStripMenuItem.Name = "wrapTextToolStripMenuItem"; 102 | this.wrapTextToolStripMenuItem.Size = new System.Drawing.Size(152, 22); 103 | this.wrapTextToolStripMenuItem.Text = "Wrap Text"; 104 | this.wrapTextToolStripMenuItem.Click += new System.EventHandler(this.wrapTextToolStripMenuItem_Click); 105 | // 106 | // changeFontToolStripMenuItem 107 | // 108 | this.changeFontToolStripMenuItem.Name = "changeFontToolStripMenuItem"; 109 | this.changeFontToolStripMenuItem.Size = new System.Drawing.Size(152, 22); 110 | this.changeFontToolStripMenuItem.Text = "Change Font"; 111 | this.changeFontToolStripMenuItem.Click += new System.EventHandler(this.changeFontToolStripMenuItem_Click); 112 | // 113 | // resetFontToolStripMenuItem 114 | // 115 | this.resetFontToolStripMenuItem.Name = "resetFontToolStripMenuItem"; 116 | this.resetFontToolStripMenuItem.Size = new System.Drawing.Size(152, 22); 117 | this.resetFontToolStripMenuItem.Text = "Reset Font"; 118 | this.resetFontToolStripMenuItem.Click += new System.EventHandler(this.resetFontToolStripMenuItem_Click); 119 | // 120 | // logViewerUserControl1 121 | // 122 | this.logViewerUserControl1.Dock = System.Windows.Forms.DockStyle.Fill; 123 | this.logViewerUserControl1.Location = new System.Drawing.Point(0, 24); 124 | this.logViewerUserControl1.Name = "logViewerUserControl1"; 125 | this.logViewerUserControl1.Size = new System.Drawing.Size(426, 306); 126 | this.logViewerUserControl1.TabIndex = 3; 127 | // 128 | // toolStripSeparator1 129 | // 130 | this.toolStripSeparator1.Name = "toolStripSeparator1"; 131 | this.toolStripSeparator1.Size = new System.Drawing.Size(149, 6); 132 | // 133 | // topMostToolStripMenuItem 134 | // 135 | this.topMostToolStripMenuItem.Name = "topMostToolStripMenuItem"; 136 | this.topMostToolStripMenuItem.Size = new System.Drawing.Size(152, 22); 137 | this.topMostToolStripMenuItem.Text = "Top Most"; 138 | this.topMostToolStripMenuItem.Click += new System.EventHandler(this.topMostToolStripMenuItem_Click); 139 | // 140 | // LogForm 141 | // 142 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 143 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 144 | this.ClientSize = new System.Drawing.Size(426, 330); 145 | this.Controls.Add(this.logViewerUserControl1); 146 | this.Controls.Add(this.menuStrip1); 147 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 148 | this.Name = "LogForm"; 149 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; 150 | this.Text = "Log Viewer"; 151 | this.Load += new System.EventHandler(this.LogForm_Load); 152 | this.menuStrip1.ResumeLayout(false); 153 | this.menuStrip1.PerformLayout(); 154 | this.ResumeLayout(false); 155 | this.PerformLayout(); 156 | 157 | } 158 | 159 | #endregion 160 | 161 | private System.Windows.Forms.MenuStrip menuStrip1; 162 | private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem; 163 | private System.Windows.Forms.ToolStripMenuItem openLocationToolStripMenuItem; 164 | private System.Windows.Forms.ToolStripMenuItem cleanLogsToolStripMenuItem; 165 | private System.Windows.Forms.ToolStripMenuItem viewToolStripMenuItem; 166 | private System.Windows.Forms.ToolStripMenuItem wrapTextToolStripMenuItem; 167 | private System.Windows.Forms.ToolStripMenuItem changeFontToolStripMenuItem; 168 | private System.Windows.Forms.ToolStripMenuItem resetFontToolStripMenuItem; 169 | private LogViewerUserControl logViewerUserControl1; 170 | private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; 171 | private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; 172 | private System.Windows.Forms.ToolStripMenuItem topMostToolStripMenuItem; 173 | } 174 | } -------------------------------------------------------------------------------- /kcptun-gui/View/Forms/LogForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Diagnostics; 6 | using System.Drawing; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | using System.Windows.Forms; 11 | 12 | using kcptun_gui.Controller; 13 | 14 | namespace kcptun_gui.View 15 | { 16 | public partial class LogForm : Form 17 | { 18 | private MainController controller; 19 | public LogForm(MainController controller) 20 | { 21 | this.controller = controller; 22 | InitializeComponent(); 23 | UpdateText(); 24 | this.StartPosition = FormStartPosition.Manual; 25 | this.Left = GetBestLeft(); 26 | this.Top = GetBestTop(); 27 | topMostToolStripMenuItem.Checked = this.TopMost; 28 | } 29 | 30 | private void UpdateText() 31 | { 32 | Text = I18N.GetString("Log Viewer"); 33 | fileToolStripMenuItem.Text = I18N.GetString("File"); 34 | viewToolStripMenuItem.Text = I18N.GetString("View"); 35 | 36 | openLocationToolStripMenuItem.Text = I18N.GetString("Open Location"); 37 | cleanLogsToolStripMenuItem.Text = I18N.GetString("Clean Logs"); 38 | wrapTextToolStripMenuItem.Text = I18N.GetString("Wrap Text"); 39 | changeFontToolStripMenuItem.Text = I18N.GetString("Change Font"); 40 | resetFontToolStripMenuItem.Text = I18N.GetString("Reset Font"); 41 | topMostToolStripMenuItem.Text = I18N.GetString("Top Most"); 42 | } 43 | 44 | private void LogForm_Load(object sender, EventArgs e) 45 | { 46 | } 47 | 48 | protected override void OnShown(EventArgs e) 49 | { 50 | base.OnShown(e); 51 | logViewerUserControl1.ScrollToCaret(); 52 | } 53 | 54 | public int GetBestLeft() 55 | { 56 | return Screen.PrimaryScreen.WorkingArea.Width - this.Width; 57 | } 58 | 59 | public int GetBestTop() 60 | { 61 | return Screen.PrimaryScreen.WorkingArea.Height - this.Height; 62 | } 63 | 64 | private void openLocationToolStripMenuItem_Click(object sender, EventArgs e) 65 | { 66 | string argument = "/select, \"" + Logging.LogFilePath + "\""; 67 | Process.Start("explorer.exe", argument); 68 | } 69 | 70 | private void cleanLogsToolStripMenuItem_Click(object sender, EventArgs e) 71 | { 72 | logViewerUserControl1.DoCleanLogs(); 73 | } 74 | 75 | private void wrapTextToolStripMenuItem_Click(object sender, EventArgs e) 76 | { 77 | wrapTextToolStripMenuItem.Checked = logViewerUserControl1.TriggerWrapText(); 78 | } 79 | 80 | private void changeFontToolStripMenuItem_Click(object sender, EventArgs e) 81 | { 82 | logViewerUserControl1.DoChangeFont(); 83 | } 84 | 85 | private void resetFontToolStripMenuItem_Click(object sender, EventArgs e) 86 | { 87 | logViewerUserControl1.ResetViewerFont(); 88 | } 89 | 90 | private void topMostToolStripMenuItem_Click(object sender, EventArgs e) 91 | { 92 | TopMost = topMostToolStripMenuItem.Checked = !topMostToolStripMenuItem.Checked; 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /kcptun-gui/View/Forms/SNMPConfigurationForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace kcptun_gui.View.Forms 2 | { 3 | partial class SNMPConfigurationForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SNMPConfigurationForm)); 32 | this.SNMPLogFileLabel = new System.Windows.Forms.Label(); 33 | this.SNMPLogFileTextBox = new System.Windows.Forms.TextBox(); 34 | this.SNMPPeriodLabel = new System.Windows.Forms.Label(); 35 | this.SNMPPeriodNumericUpDown = new System.Windows.Forms.NumericUpDown(); 36 | this.OkButton = new System.Windows.Forms.Button(); 37 | this.CancelButton = new System.Windows.Forms.Button(); 38 | this.EnableCheckBox = new System.Windows.Forms.CheckBox(); 39 | ((System.ComponentModel.ISupportInitialize)(this.SNMPPeriodNumericUpDown)).BeginInit(); 40 | this.SuspendLayout(); 41 | // 42 | // SNMPLogFileLabel 43 | // 44 | this.SNMPLogFileLabel.AutoSize = true; 45 | this.SNMPLogFileLabel.Location = new System.Drawing.Point(12, 31); 46 | this.SNMPLogFileLabel.Name = "SNMPLogFileLabel"; 47 | this.SNMPLogFileLabel.Size = new System.Drawing.Size(81, 13); 48 | this.SNMPLogFileLabel.TabIndex = 0; 49 | this.SNMPLogFileLabel.Text = "SNMP Log File:"; 50 | // 51 | // SNMPLogFileTextBox 52 | // 53 | this.SNMPLogFileTextBox.Location = new System.Drawing.Point(31, 52); 54 | this.SNMPLogFileTextBox.Name = "SNMPLogFileTextBox"; 55 | this.SNMPLogFileTextBox.Size = new System.Drawing.Size(287, 20); 56 | this.SNMPLogFileTextBox.TabIndex = 1; 57 | // 58 | // SNMPPeriodLabel 59 | // 60 | this.SNMPPeriodLabel.AutoSize = true; 61 | this.SNMPPeriodLabel.Location = new System.Drawing.Point(12, 87); 62 | this.SNMPPeriodLabel.Name = "SNMPPeriodLabel"; 63 | this.SNMPPeriodLabel.Size = new System.Drawing.Size(125, 13); 64 | this.SNMPPeriodLabel.TabIndex = 2; 65 | this.SNMPPeriodLabel.Text = "SNMP Period (Seconds):"; 66 | // 67 | // SNMPPeriodNumericUpDown 68 | // 69 | this.SNMPPeriodNumericUpDown.Location = new System.Drawing.Point(31, 109); 70 | this.SNMPPeriodNumericUpDown.Maximum = new decimal(new int[] { 71 | 2147483647, 72 | 0, 73 | 0, 74 | 0}); 75 | this.SNMPPeriodNumericUpDown.Minimum = new decimal(new int[] { 76 | 1, 77 | 0, 78 | 0, 79 | 0}); 80 | this.SNMPPeriodNumericUpDown.Name = "SNMPPeriodNumericUpDown"; 81 | this.SNMPPeriodNumericUpDown.Size = new System.Drawing.Size(120, 20); 82 | this.SNMPPeriodNumericUpDown.TabIndex = 3; 83 | this.SNMPPeriodNumericUpDown.Value = new decimal(new int[] { 84 | 1, 85 | 0, 86 | 0, 87 | 0}); 88 | // 89 | // OkButton 90 | // 91 | this.OkButton.Location = new System.Drawing.Point(162, 140); 92 | this.OkButton.Name = "OkButton"; 93 | this.OkButton.Size = new System.Drawing.Size(75, 23); 94 | this.OkButton.TabIndex = 4; 95 | this.OkButton.Text = "OK"; 96 | this.OkButton.UseVisualStyleBackColor = true; 97 | this.OkButton.Click += new System.EventHandler(this.OkButton_Click); 98 | // 99 | // CancelButton 100 | // 101 | this.CancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; 102 | this.CancelButton.Location = new System.Drawing.Point(243, 140); 103 | this.CancelButton.Name = "CancelButton"; 104 | this.CancelButton.Size = new System.Drawing.Size(75, 23); 105 | this.CancelButton.TabIndex = 4; 106 | this.CancelButton.Text = "Cancel"; 107 | this.CancelButton.UseVisualStyleBackColor = true; 108 | this.CancelButton.Click += new System.EventHandler(this.CancelButton_Click); 109 | // 110 | // EnableCheckBox 111 | // 112 | this.EnableCheckBox.AutoSize = true; 113 | this.EnableCheckBox.Location = new System.Drawing.Point(15, 8); 114 | this.EnableCheckBox.Name = "EnableCheckBox"; 115 | this.EnableCheckBox.Size = new System.Drawing.Size(59, 17); 116 | this.EnableCheckBox.TabIndex = 5; 117 | this.EnableCheckBox.Text = "Enable"; 118 | this.EnableCheckBox.UseVisualStyleBackColor = true; 119 | // 120 | // SNMPConfigurationForm 121 | // 122 | this.AcceptButton = this.OkButton; 123 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 124 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 125 | this.ClientSize = new System.Drawing.Size(334, 175); 126 | this.Controls.Add(this.EnableCheckBox); 127 | this.Controls.Add(this.CancelButton); 128 | this.Controls.Add(this.OkButton); 129 | this.Controls.Add(this.SNMPPeriodNumericUpDown); 130 | this.Controls.Add(this.SNMPPeriodLabel); 131 | this.Controls.Add(this.SNMPLogFileTextBox); 132 | this.Controls.Add(this.SNMPLogFileLabel); 133 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; 134 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 135 | this.MaximizeBox = false; 136 | this.MinimizeBox = false; 137 | this.Name = "SNMPConfigurationForm"; 138 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; 139 | this.Text = "SNMPConfigurationForm"; 140 | this.Load += new System.EventHandler(this.SNMPConfigurationForm_Load); 141 | ((System.ComponentModel.ISupportInitialize)(this.SNMPPeriodNumericUpDown)).EndInit(); 142 | this.ResumeLayout(false); 143 | this.PerformLayout(); 144 | 145 | } 146 | 147 | #endregion 148 | 149 | private System.Windows.Forms.Label SNMPLogFileLabel; 150 | private System.Windows.Forms.TextBox SNMPLogFileTextBox; 151 | private System.Windows.Forms.Label SNMPPeriodLabel; 152 | private System.Windows.Forms.NumericUpDown SNMPPeriodNumericUpDown; 153 | private System.Windows.Forms.Button OkButton; 154 | private System.Windows.Forms.Button CancelButton; 155 | private System.Windows.Forms.CheckBox EnableCheckBox; 156 | } 157 | } -------------------------------------------------------------------------------- /kcptun-gui/View/Forms/SNMPConfigurationForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | using kcptun_gui.Controller; 12 | using kcptun_gui.Model; 13 | 14 | namespace kcptun_gui.View.Forms 15 | { 16 | public partial class SNMPConfigurationForm : Form 17 | { 18 | private MainController controller; 19 | private Configuration config; 20 | public SNMPConfigurationForm(MainController controller) 21 | { 22 | this.controller = controller; 23 | config = controller.ConfigController.GetConfigurationCopy(); 24 | InitializeComponent(); 25 | UpdateText(); 26 | controller.ConfigController.SNMPConfigChanged += OnConfigChanged; 27 | } 28 | 29 | private void UpdateText() 30 | { 31 | Text = I18N.GetString("SNMP Configuration"); 32 | EnableCheckBox.Text = I18N.GetString("Enable"); 33 | SNMPLogFileLabel.Text = I18N.GetString("SNMP Log File:"); 34 | SNMPPeriodLabel.Text = I18N.GetString("SNMP Configuration"); 35 | OkButton.Text = I18N.GetString("OK"); 36 | CancelButton.Text = I18N.GetString("Cancel"); 37 | } 38 | 39 | private void SNMPConfigurationForm_Load(object sender, EventArgs e) 40 | { 41 | EnableCheckBox.Checked = config.snmp.enabled; 42 | SNMPLogFileTextBox.Text = config.snmp.snmplog; 43 | SNMPPeriodNumericUpDown.Value = config.snmp.snmpperiod; 44 | } 45 | 46 | private void OkButton_Click(object sender, EventArgs e) 47 | { 48 | try 49 | { 50 | SNMPConfiguration snmp = new SNMPConfiguration 51 | { 52 | enabled = EnableCheckBox.Checked, 53 | snmplog = SNMPLogFileTextBox.Text.Trim(), 54 | snmpperiod = (int)SNMPPeriodNumericUpDown.Value 55 | }; 56 | controller.ConfigController.ChangeSNMPConfig(snmp); 57 | this.Close(); 58 | } 59 | catch (Exception ex) 60 | { 61 | Logging.LogUsefulException(ex); 62 | MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 63 | } 64 | } 65 | 66 | private void CancelButton_Click(object sender, EventArgs e) 67 | { 68 | try 69 | { 70 | this.Close(); 71 | } 72 | catch (Exception ex) 73 | { 74 | Logging.LogUsefulException(ex); 75 | MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 76 | } 77 | } 78 | 79 | protected override void OnClosing(CancelEventArgs e) 80 | { 81 | controller.ConfigController.SNMPConfigChanged -= OnConfigChanged; 82 | base.OnClosing(e); 83 | } 84 | 85 | private void OnConfigChanged(object sender, EventArgs e) 86 | { 87 | Configuration newconfig = controller.ConfigController.GetConfigurationCopy(); 88 | if (EnableCheckBox.Checked == config.snmp.enabled) 89 | EnableCheckBox.Checked = newconfig.snmp.enabled; 90 | if (SNMPLogFileTextBox.Text == config.snmp.snmplog) 91 | SNMPLogFileTextBox.Text = newconfig.snmp.snmplog; 92 | if (SNMPPeriodNumericUpDown.Value == config.snmp.snmpperiod) 93 | SNMPPeriodNumericUpDown.Value = newconfig.snmp.snmpperiod; 94 | config = newconfig; 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /kcptun-gui/View/UserControls/AboutUserControl.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace kcptun_gui.View 2 | { 3 | partial class AboutUserControl 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Component Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.panel1 = new System.Windows.Forms.Panel(); 32 | this.GUIVersion = new System.Windows.Forms.Label(); 33 | this.LogoPictureBox = new System.Windows.Forms.PictureBox(); 34 | this.KcptunVersion = new System.Windows.Forms.Label(); 35 | this.AboutLabel = new System.Windows.Forms.Label(); 36 | this.HomePageLabel = new System.Windows.Forms.Label(); 37 | this.kcptunHomePageLinkLabel = new System.Windows.Forms.LinkLabel(); 38 | this.KcptunHomePageLabel = new System.Windows.Forms.Label(); 39 | this.HomePageLinkLabel = new System.Windows.Forms.LinkLabel(); 40 | this.panel1.SuspendLayout(); 41 | ((System.ComponentModel.ISupportInitialize)(this.LogoPictureBox)).BeginInit(); 42 | this.SuspendLayout(); 43 | // 44 | // panel1 45 | // 46 | this.panel1.Controls.Add(this.GUIVersion); 47 | this.panel1.Controls.Add(this.LogoPictureBox); 48 | this.panel1.Controls.Add(this.KcptunVersion); 49 | this.panel1.Controls.Add(this.AboutLabel); 50 | this.panel1.Controls.Add(this.HomePageLabel); 51 | this.panel1.Controls.Add(this.kcptunHomePageLinkLabel); 52 | this.panel1.Controls.Add(this.KcptunHomePageLabel); 53 | this.panel1.Controls.Add(this.HomePageLinkLabel); 54 | this.panel1.Dock = System.Windows.Forms.DockStyle.Fill; 55 | this.panel1.Location = new System.Drawing.Point(0, 0); 56 | this.panel1.Margin = new System.Windows.Forms.Padding(0); 57 | this.panel1.Name = "panel1"; 58 | this.panel1.Size = new System.Drawing.Size(481, 247); 59 | this.panel1.TabIndex = 9; 60 | // 61 | // GUIVersion 62 | // 63 | this.GUIVersion.AutoSize = true; 64 | this.GUIVersion.Location = new System.Drawing.Point(3, 222); 65 | this.GUIVersion.Name = "GUIVersion"; 66 | this.GUIVersion.Size = new System.Drawing.Size(107, 12); 67 | this.GUIVersion.TabIndex = 8; 68 | this.GUIVersion.Text = "GUI version 1.1.1"; 69 | // 70 | // LogoPictureBox 71 | // 72 | this.LogoPictureBox.BackColor = System.Drawing.Color.Transparent; 73 | this.LogoPictureBox.Image = global::kcptun_gui.Properties.Resources.logo; 74 | this.LogoPictureBox.Location = new System.Drawing.Point(3, 3); 75 | this.LogoPictureBox.Name = "LogoPictureBox"; 76 | this.LogoPictureBox.Size = new System.Drawing.Size(352, 108); 77 | this.LogoPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; 78 | this.LogoPictureBox.TabIndex = 0; 79 | this.LogoPictureBox.TabStop = false; 80 | // 81 | // KcptunVersion 82 | // 83 | this.KcptunVersion.AutoSize = true; 84 | this.KcptunVersion.Location = new System.Drawing.Point(3, 197); 85 | this.KcptunVersion.Name = "KcptunVersion"; 86 | this.KcptunVersion.Size = new System.Drawing.Size(143, 12); 87 | this.KcptunVersion.TabIndex = 7; 88 | this.KcptunVersion.Text = "kcptun version 20160811"; 89 | // 90 | // AboutLabel 91 | // 92 | this.AboutLabel.AutoSize = true; 93 | this.AboutLabel.Location = new System.Drawing.Point(3, 115); 94 | this.AboutLabel.Name = "AboutLabel"; 95 | this.AboutLabel.Size = new System.Drawing.Size(95, 12); 96 | this.AboutLabel.TabIndex = 1; 97 | this.AboutLabel.Text = "GUI for kcptun."; 98 | // 99 | // HomePageLabel 100 | // 101 | this.HomePageLabel.AutoSize = true; 102 | this.HomePageLabel.Location = new System.Drawing.Point(3, 142); 103 | this.HomePageLabel.Name = "HomePageLabel"; 104 | this.HomePageLabel.Size = new System.Drawing.Size(125, 12); 105 | this.HomePageLabel.TabIndex = 2; 106 | this.HomePageLabel.Text = "Report GUI issues to"; 107 | // 108 | // kcptunHomePageLinkLabel 109 | // 110 | this.kcptunHomePageLinkLabel.AutoSize = true; 111 | this.kcptunHomePageLinkLabel.Location = new System.Drawing.Point(158, 170); 112 | this.kcptunHomePageLinkLabel.Name = "kcptunHomePageLinkLabel"; 113 | this.kcptunHomePageLinkLabel.Size = new System.Drawing.Size(233, 12); 114 | this.kcptunHomePageLinkLabel.TabIndex = 5; 115 | this.kcptunHomePageLinkLabel.TabStop = true; 116 | this.kcptunHomePageLinkLabel.Text = "https://github.com/xtaci/kcptun/issues"; 117 | this.kcptunHomePageLinkLabel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.OnLinkClicked); 118 | // 119 | // KcptunHomePageLabel 120 | // 121 | this.KcptunHomePageLabel.AutoSize = true; 122 | this.KcptunHomePageLabel.Location = new System.Drawing.Point(3, 170); 123 | this.KcptunHomePageLabel.Name = "KcptunHomePageLabel"; 124 | this.KcptunHomePageLabel.Size = new System.Drawing.Size(149, 12); 125 | this.KcptunHomePageLabel.TabIndex = 3; 126 | this.KcptunHomePageLabel.Text = "Report kcptun issues to "; 127 | // 128 | // HomePageLinkLabel 129 | // 130 | this.HomePageLinkLabel.AutoSize = true; 131 | this.HomePageLinkLabel.Location = new System.Drawing.Point(144, 142); 132 | this.HomePageLinkLabel.Name = "HomePageLinkLabel"; 133 | this.HomePageLinkLabel.Size = new System.Drawing.Size(323, 12); 134 | this.HomePageLinkLabel.TabIndex = 4; 135 | this.HomePageLinkLabel.TabStop = true; 136 | this.HomePageLinkLabel.Text = "https://github.com/GangZhuo/kcptun-gui-windows/issues"; 137 | this.HomePageLinkLabel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.OnLinkClicked); 138 | // 139 | // AboutUserControl 140 | // 141 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); 142 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 143 | this.Controls.Add(this.panel1); 144 | this.Name = "AboutUserControl"; 145 | this.Size = new System.Drawing.Size(481, 247); 146 | this.panel1.ResumeLayout(false); 147 | this.panel1.PerformLayout(); 148 | ((System.ComponentModel.ISupportInitialize)(this.LogoPictureBox)).EndInit(); 149 | this.ResumeLayout(false); 150 | 151 | } 152 | 153 | #endregion 154 | 155 | private System.Windows.Forms.Panel panel1; 156 | private System.Windows.Forms.PictureBox LogoPictureBox; 157 | private System.Windows.Forms.Label KcptunVersion; 158 | private System.Windows.Forms.Label AboutLabel; 159 | private System.Windows.Forms.Label HomePageLabel; 160 | private System.Windows.Forms.LinkLabel kcptunHomePageLinkLabel; 161 | private System.Windows.Forms.Label KcptunHomePageLabel; 162 | private System.Windows.Forms.LinkLabel HomePageLinkLabel; 163 | private System.Windows.Forms.Label GUIVersion; 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /kcptun-gui/View/UserControls/AboutUserControl.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Drawing; 5 | using System.Data; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | using System.Diagnostics; 11 | 12 | using kcptun_gui.Controller; 13 | 14 | namespace kcptun_gui.View 15 | { 16 | public partial class AboutUserControl : UserControl 17 | { 18 | public string KCPTunVersion 19 | { 20 | get { return KcptunVersion.Text; } 21 | set { KcptunVersion.Text = value; } 22 | } 23 | 24 | public AboutUserControl() 25 | { 26 | InitializeComponent(); 27 | UpdateText(); 28 | GUIVersion.Text = I18N.GetString("GUI version ") + UpdateChecker.GUI_VERSION; 29 | } 30 | 31 | private void UpdateText() 32 | { 33 | AboutLabel.Text = I18N.GetString("GUI for kcptun."); 34 | HomePageLabel.Text = I18N.GetString("Report GUI issues to"); 35 | KcptunHomePageLabel.Text = I18N.GetString("Report kcptun issues to"); 36 | } 37 | 38 | private void OnLinkClicked(object sender, LinkLabelLinkClickedEventArgs e) 39 | { 40 | Process.Start(((LinkLabel)sender).Text); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /kcptun-gui/View/UserControls/AboutUserControl.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /kcptun-gui/View/UserControls/LogViewerUserControl.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace kcptun_gui.View 2 | { 3 | partial class LogViewerUserControl 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Component Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.components = new System.ComponentModel.Container(); 32 | this.LogTextBox = new System.Windows.Forms.TextBox(); 33 | this.timer1 = new System.Windows.Forms.Timer(this.components); 34 | this.SuspendLayout(); 35 | // 36 | // LogTextBox 37 | // 38 | this.LogTextBox.BackColor = System.Drawing.Color.Black; 39 | this.LogTextBox.BorderStyle = System.Windows.Forms.BorderStyle.None; 40 | this.LogTextBox.Dock = System.Windows.Forms.DockStyle.Fill; 41 | this.LogTextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 42 | this.LogTextBox.ForeColor = System.Drawing.Color.White; 43 | this.LogTextBox.Location = new System.Drawing.Point(0, 0); 44 | this.LogTextBox.MaxLength = 2147483647; 45 | this.LogTextBox.Multiline = true; 46 | this.LogTextBox.Name = "LogTextBox"; 47 | this.LogTextBox.ReadOnly = true; 48 | this.LogTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Both; 49 | this.LogTextBox.Size = new System.Drawing.Size(496, 325); 50 | this.LogTextBox.TabIndex = 1; 51 | this.LogTextBox.WordWrap = false; 52 | // 53 | // timer1 54 | // 55 | this.timer1.Enabled = true; 56 | this.timer1.Interval = 300; 57 | this.timer1.Tick += new System.EventHandler(this.timer1_Tick); 58 | // 59 | // LogViewerUserControl 60 | // 61 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 62 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 63 | this.Controls.Add(this.LogTextBox); 64 | this.Name = "LogViewerUserControl"; 65 | this.Size = new System.Drawing.Size(496, 325); 66 | this.Load += new System.EventHandler(this.LogViewerUserControl_Load); 67 | this.ResumeLayout(false); 68 | this.PerformLayout(); 69 | 70 | } 71 | 72 | #endregion 73 | 74 | private System.Windows.Forms.TextBox LogTextBox; 75 | private System.Windows.Forms.Timer timer1; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /kcptun-gui/View/UserControls/LogViewerUserControl.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Drawing; 5 | using System.Data; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | using System.IO; 11 | 12 | using kcptun_gui.Controller; 13 | 14 | namespace kcptun_gui.View 15 | { 16 | public partial class LogViewerUserControl : UserControl 17 | { 18 | const int BACK_OFFSET = 65536; 19 | private long lastOffset; 20 | 21 | private Font _LogFont; 22 | 23 | public LogViewerUserControl() 24 | { 25 | InitializeComponent(); 26 | _LogFont = LogTextBox.Font; 27 | } 28 | 29 | private void LogViewerUserControl_Load(object sender, EventArgs e) 30 | { 31 | InitContent(); 32 | timer1.Enabled = true; 33 | timer1.Start(); 34 | } 35 | 36 | private void timer1_Tick(object sender, EventArgs e) 37 | { 38 | UpdateContent(); 39 | } 40 | 41 | public void ScrollToCaret() 42 | { 43 | LogTextBox.ScrollToCaret(); 44 | } 45 | 46 | public void DoCleanLogs() 47 | { 48 | bool timerEnabled = timer1.Enabled; 49 | if (timerEnabled) 50 | timer1.Stop(); 51 | try 52 | { 53 | Logging.clear(); 54 | lastOffset = 0; 55 | LogTextBox.Clear(); 56 | } 57 | catch (Exception ex) 58 | { 59 | MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 60 | } 61 | 62 | if (timerEnabled) 63 | timer1.Start(); 64 | } 65 | 66 | public void DoChangeFont() 67 | { 68 | try 69 | { 70 | FontDialog fd = new FontDialog(); 71 | fd.Font = LogTextBox.Font; 72 | if (fd.ShowDialog() == DialogResult.OK) 73 | { 74 | LogTextBox.Font = new Font(fd.Font.FontFamily, fd.Font.Size, fd.Font.Style); 75 | } 76 | } 77 | catch (Exception ex) 78 | { 79 | Logging.LogUsefulException(ex); 80 | MessageBox.Show(ex.Message); 81 | } 82 | } 83 | 84 | public void ResetViewerFont() 85 | { 86 | if (LogTextBox.WordWrap) 87 | { 88 | TriggerWrapText(); 89 | } 90 | LogTextBox.Font = _LogFont; 91 | } 92 | 93 | public bool TriggerWrapText() 94 | { 95 | LogTextBox.WordWrap = !LogTextBox.WordWrap; 96 | LogTextBox.ScrollToCaret(); 97 | return LogTextBox.WordWrap; 98 | } 99 | 100 | private void InitContent() 101 | { 102 | if (string.IsNullOrEmpty(Logging.LogFilePath)) 103 | return; 104 | using (StreamReader reader = new StreamReader(new FileStream(Logging.LogFilePath, 105 | FileMode.Open, FileAccess.Read, FileShare.ReadWrite))) 106 | { 107 | if (reader.BaseStream.Length > BACK_OFFSET) 108 | { 109 | reader.BaseStream.Seek(-BACK_OFFSET, SeekOrigin.End); 110 | reader.ReadLine(); 111 | } 112 | 113 | string line = ""; 114 | while ((line = reader.ReadLine()) != null) 115 | LogTextBox.AppendText(line + Environment.NewLine); 116 | 117 | LogTextBox.ScrollToCaret(); 118 | 119 | lastOffset = reader.BaseStream.Position; 120 | } 121 | } 122 | 123 | private void UpdateContent() 124 | { 125 | if (string.IsNullOrEmpty(Logging.LogFilePath)) 126 | return; 127 | try 128 | { 129 | using (StreamReader reader = new StreamReader(new FileStream(Logging.LogFilePath, 130 | FileMode.Open, FileAccess.Read, FileShare.ReadWrite))) 131 | { 132 | reader.BaseStream.Seek(lastOffset, SeekOrigin.Begin); 133 | 134 | string line = ""; 135 | bool changed = false; 136 | while ((line = reader.ReadLine()) != null) 137 | { 138 | changed = true; 139 | LogTextBox.AppendText(line + Environment.NewLine); 140 | } 141 | 142 | if (changed) 143 | { 144 | LogTextBox.ScrollToCaret(); 145 | } 146 | 147 | lastOffset = reader.BaseStream.Position; 148 | } 149 | } 150 | catch (FileNotFoundException) 151 | { 152 | } 153 | } 154 | 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /kcptun-gui/View/UserControls/LogViewerUserControl.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 17, 17 122 | 123 | -------------------------------------------------------------------------------- /kcptun-gui/data/cn.txt: -------------------------------------------------------------------------------- 1 | # kcptun-gui-windows language file 2 | # Name: zh_CN 3 | # Full name: Chinese (Simplified) 4 | 5 | # Context menu 6 | 7 | Enable=启用/禁用 8 | Servers=服务器 9 | Edit Servers...=配置服务器... 10 | Start/Stop/Restart kcptun client...=启动/停止/重启 kcptun 客户端... 11 | Start=启动 12 | Restart=重启 13 | Stop=停止 14 | Kill all kcptun clients=杀死所有 kcptun 客户端 15 | Start on Boot=开机启动 16 | More...=更多... 17 | Turn on KCP Log=启用/禁用 kcptun 日志 18 | Custome KCPTun=自定义 kcptun 客户端路径 19 | Traffic Statistics=流量统计 20 | Show Logs...=查看日志... 21 | About...=关于... 22 | Quit=退出 23 | Update...=更新... 24 | Check GUI updates...=检测 GUI 版本... 25 | Check kcptun updates...=升级 kcptun... 26 | Check GUI updates at startup=自动检测 GUI 版本 27 | Check kcptun updates at startup=自动检测 kcptun 版本 28 | Upgrade kcptun updates at startup=自动升级 kcptun 29 | About Form=关于窗口 30 | View SNMP...=查看 SNMP... 31 | SNMP Configurations...=配置 SNMP... 32 | 33 | # Message 34 | 35 | Running...=运行中... 36 | Local:=本地端点: 37 | Remote:=远程端点: 38 | kcptun is here=kcptun 在这里 39 | You can turn on/off kcptun in the context menu.=右击此图标可管理 kcptun 客户端。 40 | GUI version =GUI 版本 41 | New GUI version {0} is available=GUI 有新的版本 {0} 42 | New kcptun version {0} is available=kcptun 有新的版本 {0} 43 | failed to download {0}=下载 {0} 失败 44 | failed to uncompress {0}=解压 {0} 失败 45 | GUI is up to date=GUI 已经是最新版 46 | kcptun is up to date=kcptun 已经是最新版 47 | kcptun updated to {0}=升级 kcptun 到 {0} 48 | 49 | # About 50 | About=关于 51 | GUI for kcptun.=kcptun-gui 是 kcptun 客户端的一个可视化配置工具。 52 | Report GUI issues to=汇报 GUI 的错误到: 53 | Report kcptun issues to=汇报 kcptun 的错误到: 54 | 55 | # Custom kcptun path 56 | Set your kcptun path...=自定义 kcptun 客户端路径... 57 | Kcptun Client:=客户端: 58 | 59 | # Edit Servers Form 60 | Edit Servers=配置服务器 61 | Server=服务器 62 | Arguments:=客户端参数: 63 | Import=导入 64 | Export=导出 65 | Select configuration file ...=选择配置文件 ... 66 | JSON files|*.json|All files|*.*=JSON 文件|*.json|所有文件|*.* 67 | Export server to a configuration file ...=导出服务器配置 ... 68 | relay udp data which is come from shadowsocks=设置是否转发来自 Shadowsocks 的 UDP 数据包 69 | shadowsocks server address=Shadowsocks 服务器地址 70 | 71 | # Log Viewer Form 72 | Log Viewer=日志浏览器 73 | 74 | # Traffic Statistics Form 75 | Display data for last {0} minutes=显示最近 {0} 分钟的统计数据 76 | Reset Chart=重置图表 77 | Raw=原始流量 78 | KCP=KCP 流量 79 | Traffic Chart=流量图表 80 | Inbound:=入站: 81 | Outbound:=出站: 82 | {0} times={0} 倍原始流量 83 | Total {0} times=总计 {0} 倍原始流量 84 | Raw: [In {0}, Out {1}], KCP: [In {2}, Out {3}]=原始速度: [In {0}, Out {1}], KCP 速度: [In {2}, Out {3}] 85 | Raw Inbound=入站 - 原始 86 | Raw Outbound=出站 - 原始 87 | KCP Inbound=入站 - KCP 88 | KCP Outbound=出站 - KCP 89 | 90 | # SNMP Configuration 91 | SNMP Configuration=配置 SNMP 92 | SNMP Log File:=SNMP 日志文件: 93 | SNMP Period (Seconds):=SNMP 周期(秒): 94 | 95 | # Buttons 96 | Browser=浏览 97 | OK=确定 98 | Cancel=取消 99 | Add=添加 100 | Delete=删除 101 | Move Up=上移 102 | Move Down=下移 103 | 104 | # Context Menu 105 | File=文件 106 | View=查看 107 | Chart=图表 108 | Open Location=打开文件位置 109 | Clean Logs=清空日志文件 110 | Wrap Text=文本自动换行 111 | Change Font=修改字体 112 | Reset Font=重置字体 113 | Top Most=窗体置顶 114 | Reset=重置 115 | Exit=退出 116 | Toolbar=工具栏 117 | 118 | 119 | # Error 120 | 121 | Error=错误 122 | Can't access the file '{0}', it is maybe used by another process.=无法打开文件 '{0}',可能已经被其他程序打开 123 | Failed to update registry=更新注册表失败 124 | 125 | # Category 126 | 127 | General=基本 128 | Security=安全 129 | Mode=通信模式 130 | Error-correcting=纠错 131 | Window size=窗口 132 | Advance=高级 133 | #extend arguments=扩展参数 134 | remarks=备注 135 | 136 | mnemonic-name for server=设置用于帮助记忆服务的助记符 137 | local listen address=设置本地侦听地址 138 | kcp server address=设置服务器地址 139 | set num of UDP connections to server=设置连接到服务器的 UDP 连接数量 140 | method for encryption=设置加密方式 141 | key for communcation=设置通信密钥 142 | disable compression=设置是否禁用压缩 143 | mode for communication. Ignore all other parameters exclude 'extend arguments', when select 'manual-all'=设置通信方式。选择 'manual-all' 后,忽略其它参数,仅使用 'extend arguments'。 144 | enabled on 'manual' mode, ref https://github.com/xtaci/kcptun=仅在 'manual' 模式下有效,参考 https://github.com/xtaci/kcptun 145 | Reed-solomon erasure coding - datashard=Reed-Solomon 纠错算法的 'datashard' 参数 146 | Reed-solomon erasure coding - parityshard=Reed-Solomon 纠错算法的 'parityshard' 参数 147 | send window size (num of packets)=设置发送窗口的大小(值为包的数量) 148 | receive window size (num of packets)=设置接收窗口的大小(值为包的数量) 149 | set maximum transmission unit for UDP packets=设置 UDP 包的最大传输单元 150 | DSCP(6bit). Ref https://en.wikipedia.org/wiki/Differentiated_services#Commonly_used_DSCP_values=设置 DSCP(6bit)值,参考 https://en.wikipedia.org/wiki/Differentiated_services#Commonly_used_DSCP_values 151 | extend arguments which are append to end of command line=设置扩展参数,值将会添加到客户端参数的最后 152 | set auto expiration time(in seconds) for a single UDP connection, 0 to disable=设置单个 UDP 连接的过期时间(单位为秒),设置为 0 则禁用此功能 153 | config from json file, which will override the command from shell=通过配置文件来启动客户端 154 | 155 | # Language 156 | 157 | Chinese (Simplified)=简体中文 158 | -------------------------------------------------------------------------------- /kcptun-gui/data/en.txt: -------------------------------------------------------------------------------- 1 | # kcptun-gui-windows language file 2 | # Name: en 3 | # Full name: English 4 | 5 | # Language 6 | 7 | Chinese (Simplified)=简体中文 8 | -------------------------------------------------------------------------------- /kcptun-gui/data/logo-small.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GangZhuo/kcptun-gui-windows/b1f08b1781b4019480c452d401cd042bc7736478/kcptun-gui/data/logo-small.ico -------------------------------------------------------------------------------- /kcptun-gui/data/logo-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GangZhuo/kcptun-gui-windows/b1f08b1781b4019480c452d401cd042bc7736478/kcptun-gui/data/logo-small.png -------------------------------------------------------------------------------- /kcptun-gui/data/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GangZhuo/kcptun-gui-windows/b1f08b1781b4019480c452d401cd042bc7736478/kcptun-gui/data/logo.png -------------------------------------------------------------------------------- /kcptun-gui/kcptun-gui.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {DBBEA80B-2740-4388-B24F-575B0CE922D9} 8 | WinExe 9 | Properties 10 | kcptun_gui 11 | kcptun-gui 12 | v4.5.2 13 | 512 14 | true 15 | 16 | 17 | 18 | 19 | AnyCPU 20 | true 21 | full 22 | false 23 | bin\Debug\ 24 | DEBUG;TRACE 25 | prompt 26 | 4 27 | 28 | 29 | AnyCPU 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | 37 | 38 | data\logo-small.ico 39 | 40 | 41 | 42 | 43 | 44 | 45 | ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll 46 | True 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | True 90 | True 91 | Resources.resx 92 | 93 | 94 | Form 95 | 96 | 97 | AboutForm.cs 98 | 99 | 100 | Form 101 | 102 | 103 | CustomKCPTunForm.cs 104 | 105 | 106 | Form 107 | 108 | 109 | SNMPConfigurationForm.cs 110 | 111 | 112 | Form 113 | 114 | 115 | StatisticsForm.cs 116 | 117 | 118 | UserControl 119 | 120 | 121 | AboutUserControl.cs 122 | 123 | 124 | Form 125 | 126 | 127 | LogForm.cs 128 | 129 | 130 | UserControl 131 | 132 | 133 | LogViewerUserControl.cs 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | Form 143 | 144 | 145 | EditServersForm.cs 146 | 147 | 148 | AboutForm.cs 149 | 150 | 151 | CustomKCPTunForm.cs 152 | 153 | 154 | EditServersForm.cs 155 | 156 | 157 | SNMPConfigurationForm.cs 158 | 159 | 160 | StatisticsForm.cs 161 | 162 | 163 | AboutUserControl.cs 164 | 165 | 166 | LogForm.cs 167 | 168 | 169 | LogViewerUserControl.cs 170 | 171 | 172 | ResXFileCodeGenerator 173 | Designer 174 | Resources.Designer.cs 175 | 176 | 177 | 178 | SettingsSingleFileGenerator 179 | Settings.Designer.cs 180 | 181 | 182 | True 183 | Settings.settings 184 | True 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 206 | 207 | 208 | 209 | 216 | -------------------------------------------------------------------------------- /kcptun-gui/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | --------------------------------------------------------------------------------