├── .editorconfig ├── .gitattributes ├── .gitignore ├── .travis.yml ├── .vs └── Slim TS3 │ └── v14 │ └── .suo ├── .vscode └── launch.json ├── LICENSE ├── README.md ├── Slim TS3.sln ├── TS3Client ├── Commands │ ├── CommandBinder.cs │ ├── CommandDeserializer.cs │ ├── CommandOption.cs │ ├── CommandParameter.cs │ ├── ParameterConverter.cs │ ├── Ts3Command.cs │ └── Ts3String.cs ├── ConnectionData.cs ├── DisconnectEventArgs.cs ├── DocumentedEnums.cs ├── EventDispatcher.cs ├── Full │ ├── BasePacket.cs │ ├── IdentityData.cs │ ├── IncomingPacket.cs │ ├── NetUtil.cs │ ├── NetworkStats.cs │ ├── OutgoingPacket.cs │ ├── PacketHandler.cs │ ├── PacketType.cs │ ├── QuickLZ.cs │ ├── RingQueue.cs │ ├── Ts3Crypt.cs │ ├── Ts3FullClient.cs │ └── VersionSign.cs ├── LazyNotification.cs ├── MessageProcessor.cs ├── Messages │ ├── BaseTypes.cs │ ├── MessageDeclarations.txt │ ├── MessageTemplates.cs │ ├── MessageTemplates.tt │ └── ResponseDictionary.cs ├── OwnEnums.cs ├── Properties │ └── AssemblyInfo.cs ├── Query │ └── Ts3QueryClient.cs ├── TS3Client.csproj ├── Ts3BaseClient.cs ├── Ts3Exceptions.cs ├── Util.cs ├── WaitBlock.cs ├── packages.config └── ts3protocol.txt ├── TS3ClientGUI ├── App.config ├── Client.cs ├── MainWindow.Designer.cs ├── MainWindow.cs ├── MainWindow.resx ├── Program.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── TS3ClientGUI.csproj ├── TS3ClientGUI.csproj.user └── ts3client.ico └── packages ├── BouncyCastle.1.8.1 ├── BouncyCastle.1.8.1.nupkg ├── Readme.txt └── lib │ └── BouncyCastle.Crypto.dll ├── Fody.1.29.4 ├── Content │ └── FodyWeavers.xml ├── Fody.1.29.4.nupkg ├── Fody.dll ├── Fody.pdb ├── FodyCommon.dll ├── FodyCommon.pdb ├── FodyIsolated.dll ├── FodyIsolated.pdb ├── Mono.Cecil.Mdb.dll ├── Mono.Cecil.Pdb.dll ├── Mono.Cecil.Rocks.dll ├── Mono.Cecil.dll └── build │ ├── dotnet │ └── Fody.targets │ └── portable-net+sl+win+wpa+wp │ └── Fody.targets ├── HtmlAgilityPack.1.4.9.5 ├── HAPIcon.png ├── HtmlAgilityPack.1.4.9.5.nupkg ├── lib │ ├── Net20 │ │ ├── HtmlAgilityPack.dll │ │ ├── HtmlAgilityPack.pdb │ │ └── HtmlAgilityPack.xml │ ├── Net40-client │ │ ├── HtmlAgilityPack.dll │ │ ├── HtmlAgilityPack.pdb │ │ └── HtmlAgilityPack.xml │ ├── Net40 │ │ ├── HtmlAgilityPack.XML │ │ ├── HtmlAgilityPack.dll │ │ └── HtmlAgilityPack.pdb │ ├── Net45 │ │ ├── HtmlAgilityPack.XML │ │ ├── HtmlAgilityPack.dll │ │ └── HtmlAgilityPack.pdb │ ├── NetCore45 │ │ ├── HtmlAgilityPack.dll │ │ ├── HtmlAgilityPack.pdb │ │ ├── HtmlAgilityPack.pri │ │ └── HtmlAgilityPack.xml │ ├── portable-net45+netcore45+wp8+MonoAndroid+MonoTouch │ │ ├── HtmlAgilityPack.dll │ │ └── HtmlAgilityPack.pdb │ ├── portable-net45+netcore45+wpa81+wp8+MonoAndroid+MonoTouch │ │ ├── HtmlAgilityPack.dll │ │ └── HtmlAgilityPack.pdb │ └── sl5 │ │ ├── HtmlAgilityPack.XML │ │ ├── HtmlAgilityPack.dll │ │ └── HtmlAgilityPack.pdb └── readme.txt ├── LiteDB.3.0.0 ├── LiteDB.3.0.0.nupkg └── lib │ ├── net35 │ ├── LiteDB.dll │ └── LiteDB.xml │ └── netstandard1.4 │ ├── LiteDB.dll │ └── LiteDB.xml ├── Mono.Cecil.0.9.6.4 ├── Mono.Cecil.0.9.6.4.nupkg └── lib │ ├── net20 │ ├── Mono.Cecil.Mdb.dll │ ├── Mono.Cecil.Pdb.dll │ └── Mono.Cecil.dll │ ├── net35 │ ├── Mono.Cecil.Mdb.dll │ ├── Mono.Cecil.Pdb.dll │ ├── Mono.Cecil.Rocks.dll │ └── Mono.Cecil.dll │ ├── net40 │ ├── Mono.Cecil.Mdb.dll │ ├── Mono.Cecil.Pdb.dll │ ├── Mono.Cecil.Rocks.dll │ └── Mono.Cecil.dll │ ├── net45 │ ├── Mono.Cecil.Mdb.dll │ ├── Mono.Cecil.Pdb.dll │ ├── Mono.Cecil.Rocks.dll │ └── Mono.Cecil.dll │ └── sl5 │ ├── Mono.Cecil.Rocks.dll │ └── Mono.Cecil.dll ├── NUnit.3.6.0 ├── CHANGES.txt ├── LICENSE.txt ├── NOTICES.txt ├── NUnit.3.6.0.nupkg └── lib │ ├── MonoAndroid │ ├── nunit.framework.dll │ └── nunit.framework.xml │ ├── Xamarin.iOS10 │ ├── nunit.framework.dll │ └── nunit.framework.xml │ ├── net20 │ ├── NUnit.System.Linq.dll │ ├── nunit.framework.dll │ └── nunit.framework.xml │ ├── net35 │ ├── nunit.framework.dll │ └── nunit.framework.xml │ ├── net40 │ ├── nunit.framework.dll │ └── nunit.framework.xml │ ├── net45 │ ├── nunit.framework.dll │ └── nunit.framework.xml │ ├── netstandard1.6 │ ├── nunit.framework.dll │ └── nunit.framework.xml │ └── portable-net45+win8+wp8+wpa81 │ ├── nunit.framework.dll │ └── nunit.framework.xml └── PropertyChanged.Fody.1.52.1 ├── Lib ├── dotnet │ ├── PropertyChanged.dll │ └── PropertyChanged.xml ├── netstandard10 │ ├── PropertyChanged.dll │ └── PropertyChanged.xml └── portable-net4+sl4+wp8+win8+wpa81+MonoAndroid16+MonoTouch40 │ ├── PropertyChanged.dll │ └── PropertyChanged.xml ├── PropertyChanged.Fody.1.52.1.nupkg ├── PropertyChanged.Fody.dll ├── PropertyChanged.Fody.pdb └── Tools ├── install.ps1 └── uninstall.ps1 /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | charset = utf-8 7 | 8 | [*.cs] 9 | indent_style = tab 10 | trim_trailing_whitespace = true -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.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 | *.userprefs 10 | .buildvars.py 11 | .sconsign.dblite 12 | .vs/config/* 13 | .idea/ 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | build/ 23 | bld/ 24 | [Bb]in/ 25 | [Oo]bj/ 26 | # Generated for fuzzying 27 | findings/ 28 | TS3AudioBob/configTS3AudioBot.cfg 29 | 30 | # C++ Build results 31 | *.o 32 | *.obj 33 | *.so 34 | *.lib 35 | *.dll 36 | 37 | # Roslyn cache directories 38 | *.ide/ 39 | 40 | # MSTest test Results 41 | [Tt]est[Rr]esult*/ 42 | [Bb]uild[Ll]og.* 43 | 44 | # NUNIT 45 | *.VisualState.xml 46 | TestResult.xml 47 | 48 | # Build Results of an ATL Project 49 | [Dd]ebugPS/ 50 | [Rr]eleasePS/ 51 | dlldata.c 52 | 53 | *_i.c 54 | *_p.c 55 | *_i.h 56 | *.ilk 57 | *.meta 58 | *.obj 59 | *.pch 60 | *.pdb 61 | *.pgc 62 | *.pgd 63 | *.rsp 64 | *.sbr 65 | *.tlb 66 | *.tli 67 | *.tlh 68 | *.tmp 69 | *.tmp_proj 70 | *.log 71 | *.vspscc 72 | *.vssscc 73 | .builds 74 | *.pidb 75 | *.svclog 76 | *.scc 77 | 78 | # Chutzpah Test files 79 | _Chutzpah* 80 | 81 | # Visual C++ cache files 82 | ipch/ 83 | *.aps 84 | *.ncb 85 | *.opensdf 86 | *.sdf 87 | *.cachefile 88 | 89 | # Visual Studio profiler 90 | *.psess 91 | *.vsp 92 | *.vspx 93 | 94 | # TFS 2012 Local Workspace 95 | $tf/ 96 | 97 | # Guidance Automation Toolkit 98 | *.gpState 99 | 100 | # ReSharper is a .NET coding add-in 101 | _ReSharper*/ 102 | *.[Rr]e[Ss]harper 103 | *.DotSettings.user 104 | 105 | # JustCode is a .NET coding addin-in 106 | .JustCode 107 | 108 | # TeamCity is a build add-in 109 | _TeamCity* 110 | 111 | # DotCover is a Code Coverage Tool 112 | *.dotCover 113 | 114 | # NCrunch 115 | _NCrunch_* 116 | .*crunch*.local.xml 117 | 118 | # MightyMoose 119 | *.mm.* 120 | AutoTest.Net/ 121 | 122 | # Web workbench (sass) 123 | .sass-cache/ 124 | 125 | # Installshield output folder 126 | [Ee]xpress/ 127 | 128 | # DocProject is a documentation generator add-in 129 | DocProject/buildhelp/ 130 | DocProject/Help/*.HxT 131 | DocProject/Help/*.HxC 132 | DocProject/Help/*.hhc 133 | DocProject/Help/*.hhk 134 | DocProject/Help/*.hhp 135 | DocProject/Help/Html2 136 | DocProject/Help/html 137 | 138 | # Click-Once directory 139 | publish/ 140 | 141 | # Publish Web Output 142 | *.[Pp]ublish.xml 143 | *.azurePubxml 144 | # TODO: Comment the next line if you want to checkin your web deploy settings 145 | # but database connection strings (with potential passwords) will be unencrypted 146 | *.pubxml 147 | *.publishproj 148 | 149 | # NuGet Packages 150 | *.nupkg 151 | # The packages folder can be ignored because of Package Restore 152 | **/packages/* 153 | # except build/, which is used as an MSBuild target. 154 | !**/packages/build/ 155 | # If using the old MSBuild-Integrated Package Restore, uncomment this: 156 | #!**/packages/repositories.config 157 | 158 | # Windows Azure Build Output 159 | csx/ 160 | *.build.csdef 161 | 162 | # Windows Store app package directory 163 | AppPackages/ 164 | 165 | # Others 166 | sql/ 167 | *.Cache 168 | ClientBin/ 169 | [Ss]tyle[Cc]op.* 170 | ~$* 171 | *~ 172 | *.dbmdl 173 | *.dbproj.schemaview 174 | *.pfx 175 | *.publishsettings 176 | node_modules/ 177 | 178 | # RIA/Silverlight projects 179 | Generated_Code/ 180 | 181 | # Backup & report files from converting an old project file 182 | # to a newer Visual Studio version. Backup files are not needed, 183 | # because we have git ;-) 184 | _UpgradeReport_Files/ 185 | Backup*/ 186 | UpgradeLog*.XML 187 | UpgradeLog*.htm 188 | 189 | # SQL Server files 190 | *.mdf 191 | *.ldf 192 | 193 | # Business Intelligence projects 194 | *.rdl.data 195 | *.bim.layout 196 | *.bim_*.settings 197 | 198 | # Microsoft Fakes 199 | FakesAssemblies/ 200 | 201 | # ========================= 202 | # Operating System Files 203 | # ========================= 204 | 205 | # OSX 206 | # ========================= 207 | 208 | .DS_Store 209 | .AppleDouble 210 | .LSOverride 211 | 212 | # Thumbnails 213 | ._* 214 | 215 | # Files that might appear on external disk 216 | .Spotlight-V100 217 | .Trashes 218 | 219 | # Directories potentially created on remote AFP share 220 | .AppleDB 221 | .AppleDesktop 222 | Network Trash Folder 223 | Temporary Items 224 | .apdisk 225 | 226 | # Windows 227 | # ========================= 228 | 229 | # Windows image file caches 230 | Thumbs.db 231 | ehthumbs.db 232 | 233 | # Folder config file 234 | Desktop.ini 235 | 236 | # Recycle Bin used on file shares 237 | $RECYCLE.BIN/ 238 | 239 | # Windows Installer files 240 | *.cab 241 | *.msi 242 | *.msm 243 | *.msp 244 | 245 | # Windows shortcuts 246 | *.lnk 247 | 248 | !packages/* 249 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: csharp 3 | 4 | notifications: 5 | email: false 6 | 7 | branches: 8 | only: 9 | - master 10 | - develop 11 | 12 | git: 13 | depth: 1 14 | 15 | install: 16 | - nuget restore TS3AudioBot.sln 17 | - nuget install NUnit.Runners -OutputDirectory nunit 18 | 19 | script: 20 | - xbuild /p:Configuration=Release /p:Platform=x86 TS3AudioBot.sln 21 | - mono ./nunit/NUnit.ConsoleRunner.*.*.*/tools/nunit3-console.exe ./TS3ABotUnitTests/bin/Release/TS3ABotUnitTests.dll 22 | 23 | after_script: 24 | - chmod u+x ts3notify.sh 25 | - ./ts3notify.sh 26 | -------------------------------------------------------------------------------- /.vs/Slim TS3/v14/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/.vs/Slim TS3/v14/.suo -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Debug", 6 | "type": "mono", 7 | "request": "launch", 8 | "program": "TS3AudioBot/bin/Debug/TS3AudioBot.exe", 9 | "args": [], 10 | "cwd": ".", 11 | "runtimeExecutable": null, 12 | "env": {} 13 | }, 14 | { 15 | "name": "Attach", 16 | "type": "mono", 17 | "request": "attach", 18 | "address": "localhost", 19 | "port": 5858 20 | } 21 | ] 22 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Slim TS3 2 | 3 | Huge Thanks to @Splamy for letting me play around with this ;D -------------------------------------------------------------------------------- /Slim TS3.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio 14 3 | VisualStudioVersion = 14.0.25123.0 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TS3Client", "TS3Client\TS3Client.csproj", "{0EB99E9D-87E5-4534-A100-55D231C2B6A6}" 6 | EndProject 7 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{ADAA5A65-0CE1-45FA-91F4-3D8D39073AB0}" 8 | ProjectSection(SolutionItems) = preProject 9 | .editorconfig = .editorconfig 10 | EndProjectSection 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TS3ClientGUI", "TS3ClientGUI\TS3ClientGUI.csproj", "{79AC094F-59FE-4198-9088-982265AB12F0}" 13 | EndProject 14 | Global 15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 16 | Debug|Any CPU = Debug|Any CPU 17 | Debug|x86 = Debug|x86 18 | Release|Any CPU = Release|Any CPU 19 | Release|x86 = Release|x86 20 | EndGlobalSection 21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 22 | {0EB99E9D-87E5-4534-A100-55D231C2B6A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {0EB99E9D-87E5-4534-A100-55D231C2B6A6}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {0EB99E9D-87E5-4534-A100-55D231C2B6A6}.Debug|x86.ActiveCfg = Debug|Any CPU 25 | {0EB99E9D-87E5-4534-A100-55D231C2B6A6}.Debug|x86.Build.0 = Debug|Any CPU 26 | {0EB99E9D-87E5-4534-A100-55D231C2B6A6}.Release|Any CPU.ActiveCfg = Release|Any CPU 27 | {0EB99E9D-87E5-4534-A100-55D231C2B6A6}.Release|Any CPU.Build.0 = Release|Any CPU 28 | {0EB99E9D-87E5-4534-A100-55D231C2B6A6}.Release|x86.ActiveCfg = Release|Any CPU 29 | {0EB99E9D-87E5-4534-A100-55D231C2B6A6}.Release|x86.Build.0 = Release|Any CPU 30 | {79AC094F-59FE-4198-9088-982265AB12F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 31 | {79AC094F-59FE-4198-9088-982265AB12F0}.Debug|Any CPU.Build.0 = Debug|Any CPU 32 | {79AC094F-59FE-4198-9088-982265AB12F0}.Debug|x86.ActiveCfg = Debug|Any CPU 33 | {79AC094F-59FE-4198-9088-982265AB12F0}.Debug|x86.Build.0 = Debug|Any CPU 34 | {79AC094F-59FE-4198-9088-982265AB12F0}.Release|Any CPU.ActiveCfg = Release|Any CPU 35 | {79AC094F-59FE-4198-9088-982265AB12F0}.Release|Any CPU.Build.0 = Release|Any CPU 36 | {79AC094F-59FE-4198-9088-982265AB12F0}.Release|x86.ActiveCfg = Release|Any CPU 37 | {79AC094F-59FE-4198-9088-982265AB12F0}.Release|x86.Build.0 = Release|Any CPU 38 | EndGlobalSection 39 | GlobalSection(SolutionProperties) = preSolution 40 | HideSolutionNode = FALSE 41 | EndGlobalSection 42 | EndGlobal 43 | -------------------------------------------------------------------------------- /TS3Client/Commands/CommandBinder.cs: -------------------------------------------------------------------------------- 1 | // TS3AudioBot - An advanced Musicbot for Teamspeak 3 2 | // Copyright (C) 2016 TS3AudioBot contributors 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU Affero General Public License as 6 | // published by the Free Software Foundation, either version 3 of the 7 | // License, or (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU Affero General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU Affero General Public License 15 | // along with this program. If not, see . 16 | 17 | namespace TS3Client.Commands 18 | { 19 | using System; 20 | using System.Collections.Generic; 21 | using System.Linq; 22 | using System.Reflection; 23 | 24 | public class CommandBinder : CommandParameter 25 | { 26 | private static readonly Dictionary ConstrBuffer = new Dictionary(); 27 | private static ConstructorInfo GetValueCtor(Type t) 28 | { 29 | ConstructorInfo ci; 30 | if (!ConstrBuffer.TryGetValue(t, out ci)) 31 | { 32 | var ctor = typeof(ParameterConverter).GetConstructors().Where(c => c.GetParameters().First().ParameterType == t).FirstOrDefault(); 33 | if (ctor == null) 34 | throw new InvalidCastException(); 35 | ci = ctor; 36 | ConstrBuffer.Add(t, ci); 37 | } 38 | return ci; 39 | } 40 | private readonly List buildList = new List(); 41 | public override string QueryString => string.Join(" ", buildList); 42 | 43 | public static CommandBinder NewBind(string key, IEnumerable parameter) => new CommandBinder().Bind(key, parameter); 44 | public CommandBinder Bind(string key, IEnumerable parameter) 45 | { 46 | var ctor = GetValueCtor(typeof(T)); 47 | var values = parameter.Select(val => (ParameterConverter)ctor.Invoke(new object[] { val })); 48 | var result = string.Join("|", values.Select(v => new CommandParameter(key, v).QueryString)); 49 | buildList.Add(result); 50 | return this; 51 | } 52 | 53 | public static CommandBinder NewBind(string key, IEnumerable parameter) => new CommandBinder().Bind(key, parameter); 54 | public CommandBinder Bind(string key, IEnumerable parameter) 55 | { 56 | throw new NotImplementedException(); 57 | //buildList.Add(result); 58 | //return this; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /TS3Client/Commands/CommandDeserializer.cs: -------------------------------------------------------------------------------- 1 | // TS3AudioBot - An advanced Musicbot for Teamspeak 3 2 | // Copyright (C) 2016 TS3AudioBot contributors 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU Affero General Public License as 6 | // published by the Free Software Foundation, either version 3 of the 7 | // License, or (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU Affero General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU Affero General Public License 15 | // along with this program. If not, see . 16 | 17 | namespace TS3Client.Commands 18 | { 19 | using Messages; 20 | using System; 21 | using System.Collections.Generic; 22 | using System.Globalization; 23 | using System.Linq; 24 | using KVEnu = System.Collections.Generic.IEnumerable>; 25 | 26 | internal static class CommandDeserializer 27 | { 28 | // data to notification 29 | public static IEnumerable GenerateNotification(string lineDataPart, NotificationType ntfyType) 30 | { 31 | if (ntfyType == NotificationType.Unknown) 32 | throw new ArgumentException("The NotificationType must not be unknown", nameof(lineDataPart)); 33 | 34 | if (lineDataPart == null) 35 | throw new ArgumentNullException(nameof(lineDataPart)); 36 | 37 | return lineDataPart.TrimStart().Split('|').Select(msg => GenerateSingleNotification(msg, ntfyType)); 38 | } 39 | 40 | public static INotification GenerateSingleNotification(string lineDataPart, NotificationType ntfyType) 41 | { 42 | if (ntfyType == NotificationType.Unknown) 43 | throw new ArgumentException("The NotificationType must not be unknown", nameof(lineDataPart)); 44 | 45 | if (lineDataPart == null) 46 | return null; 47 | 48 | var incomingData = ParseKeyValueLine(lineDataPart, false); 49 | var notification = MessageHelper.GenerateNotificationType(ntfyType); 50 | FillQueryMessage(notification, incomingData); 51 | return notification; 52 | } 53 | 54 | // data to response 55 | public static IEnumerable GenerateResponse(string line) where T : IResponse, new() 56 | { 57 | if (typeof(T) == typeof(ResponseDictionary)) 58 | { 59 | if (string.IsNullOrWhiteSpace(line)) 60 | return Enumerable.Empty(); 61 | var messageList = line.Split('|'); 62 | return (IEnumerable)messageList.Select(msg => new ResponseDictionary(ParseKeyValueLineDict(msg, false))); 63 | } 64 | else 65 | { 66 | if (string.IsNullOrWhiteSpace(line)) 67 | return Enumerable.Empty(); 68 | var messageList = line.Split('|'); 69 | return messageList.Select(msg => 70 | { 71 | var incomingData = ParseKeyValueLine(msg, false); 72 | var response = new T(); 73 | FillQueryMessage(response, incomingData); 74 | return response; 75 | }); 76 | } 77 | } 78 | 79 | // HELPER 80 | 81 | private static void FillQueryMessage(IQueryMessage qm, KVEnu kvpData) 82 | { 83 | foreach (var kvp in kvpData) 84 | { 85 | qm.SetField(kvp.Key, kvp.Value); 86 | } 87 | } 88 | 89 | private static KVEnu ParseKeyValueLine(string line, bool ignoreFirst) 90 | { 91 | if (string.IsNullOrWhiteSpace(line)) 92 | return Enumerable.Empty>(); 93 | IEnumerable splitValues = line.Split(' '); 94 | if (ignoreFirst) splitValues = splitValues.Skip(1); 95 | return from part in splitValues 96 | select part.Split(new[] { '=' }, 2) into keyValuePair 97 | select new KeyValuePair(keyValuePair[0], keyValuePair.Length > 1 ? keyValuePair[1] : string.Empty); 98 | } 99 | 100 | private static Dictionary ParseKeyValueLineDict(string line, bool ignoreFirst) 101 | => ParseKeyValueLineDict(ParseKeyValueLine(line, ignoreFirst)); 102 | 103 | private static Dictionary ParseKeyValueLineDict(KVEnu data) 104 | => data.ToDictionary(pair => pair.Key, pair => pair.Value); 105 | 106 | public static bool DeserializeBool(string v) => v != "0"; 107 | public static sbyte DeserializeInt8(string v) => sbyte.Parse(v, CultureInfo.InvariantCulture); 108 | public static byte DeserializeUInt8(string v) => byte.Parse(v, CultureInfo.InvariantCulture); 109 | public static short DeserializeInt16(string v) => short.Parse(v, CultureInfo.InvariantCulture); 110 | public static ushort DeserializeUInt16(string v) => ushort.Parse(v, CultureInfo.InvariantCulture); 111 | public static int DeserializeInt32(string v) => int.Parse(v, CultureInfo.InvariantCulture); 112 | public static uint DeserializeUInt32(string v) => uint.Parse(v, CultureInfo.InvariantCulture); 113 | public static long DeserializeInt64(string v) => long.Parse(v, CultureInfo.InvariantCulture); 114 | public static ulong DeserializeUInt64(string v) => ulong.Parse(v, CultureInfo.InvariantCulture); 115 | public static float DeserializeSingle(string v) => float.Parse(v, CultureInfo.InvariantCulture); 116 | public static double DeserializeDouble(string v) => double.Parse(v, CultureInfo.InvariantCulture); 117 | public static string DeserializeString(string v) => Ts3String.Unescape(v); 118 | public static TimeSpan DeserializeTimeSpan(string v) => TimeSpan.FromSeconds(double.Parse(v, CultureInfo.InvariantCulture)); 119 | public static DateTime DeserializeDateTime(string v) => Util.UnixTimeStart.AddSeconds(double.Parse(v, CultureInfo.InvariantCulture)); 120 | public static T DeserializeEnum(string v) where T : struct 121 | { 122 | T val; 123 | if (!Enum.TryParse(v, out val)) 124 | throw new FormatException(); 125 | return val; 126 | } 127 | public static T[] DeserializeArray(string v, Func converter) 128 | => v.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).Select(converter).ToArray(); 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /TS3Client/Commands/CommandOption.cs: -------------------------------------------------------------------------------- 1 | // TS3AudioBot - An advanced Musicbot for Teamspeak 3 2 | // Copyright (C) 2016 TS3AudioBot contributors 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU Affero General Public License as 6 | // published by the Free Software Foundation, either version 3 of the 7 | // License, or (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU Affero General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU Affero General Public License 15 | // along with this program. If not, see . 16 | 17 | namespace TS3Client.Commands 18 | { 19 | using System; 20 | using System.Text; 21 | using System.Linq; 22 | 23 | public struct CommandOption 24 | { 25 | public string Value { get; } 26 | 27 | public CommandOption(string name) { Value = string.Concat(" -", name); } 28 | public CommandOption(Enum values) 29 | { 30 | var strb = new StringBuilder(); 31 | foreach (var enu in values.GetFlags().Select(enu => enu.ToString())) 32 | strb.Append(" -").Append(enu); 33 | Value = strb.ToString(); 34 | } 35 | 36 | public static implicit operator CommandOption(string value) => new CommandOption(value); 37 | public static implicit operator CommandOption(Enum value) => new CommandOption(value); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /TS3Client/Commands/CommandParameter.cs: -------------------------------------------------------------------------------- 1 | // TS3AudioBot - An advanced Musicbot for Teamspeak 3 2 | // Copyright (C) 2016 TS3AudioBot contributors 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU Affero General Public License as 6 | // published by the Free Software Foundation, either version 3 of the 7 | // License, or (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU Affero General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU Affero General Public License 15 | // along with this program. If not, see . 16 | 17 | namespace TS3Client.Commands 18 | { 19 | using System.Diagnostics; 20 | 21 | public class CommandParameter 22 | { 23 | public string Key { get; } 24 | public string Value { get; } 25 | public virtual string QueryString => string.IsNullOrEmpty(Value) ? Key : string.Concat(Key, "=", Value); 26 | 27 | protected CommandParameter() { } 28 | 29 | [DebuggerStepThrough] 30 | public CommandParameter(string name, ParameterConverter rawValue) 31 | { 32 | Key = name; 33 | Value = rawValue.QueryValue; 34 | } 35 | 36 | public override string ToString() => QueryString; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /TS3Client/Commands/ParameterConverter.cs: -------------------------------------------------------------------------------- 1 | // TS3AudioBot - An advanced Musicbot for Teamspeak 3 2 | // Copyright (C) 2016 TS3AudioBot contributors 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU Affero General Public License as 6 | // published by the Free Software Foundation, either version 3 of the 7 | // License, or (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU Affero General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU Affero General Public License 15 | // along with this program. If not, see . 16 | 17 | namespace TS3Client.Commands 18 | { 19 | using System; 20 | using System.Globalization; 21 | 22 | public struct ParameterConverter 23 | { 24 | public string QueryValue { get; } 25 | 26 | public ParameterConverter(bool value) { QueryValue = (value ? "1" : "0"); } 27 | public ParameterConverter(sbyte value) { QueryValue = value.ToString(CultureInfo.InvariantCulture); } 28 | public ParameterConverter(byte value) { QueryValue = value.ToString(CultureInfo.InvariantCulture); } 29 | public ParameterConverter(short value) { QueryValue = value.ToString(CultureInfo.InvariantCulture); } 30 | public ParameterConverter(ushort value) { QueryValue = value.ToString(CultureInfo.InvariantCulture); } 31 | public ParameterConverter(int value) { QueryValue = value.ToString(CultureInfo.InvariantCulture); } 32 | public ParameterConverter(uint value) { QueryValue = value.ToString(CultureInfo.InvariantCulture); } 33 | public ParameterConverter(long value) { QueryValue = value.ToString(CultureInfo.InvariantCulture); } 34 | public ParameterConverter(ulong value) { QueryValue = value.ToString(CultureInfo.InvariantCulture); } 35 | public ParameterConverter(float value) { QueryValue = value.ToString(CultureInfo.InvariantCulture); } 36 | public ParameterConverter(double value) { QueryValue = value.ToString(CultureInfo.InvariantCulture); } 37 | public ParameterConverter(string value) { QueryValue = Ts3String.Escape(value); } 38 | public ParameterConverter(TimeSpan value) { QueryValue = value.TotalSeconds.ToString("F0", CultureInfo.InvariantCulture); } 39 | public ParameterConverter(DateTime value) { QueryValue = (value - Util.UnixTimeStart).TotalSeconds.ToString("F0", CultureInfo.InvariantCulture); } 40 | 41 | public static implicit operator ParameterConverter(bool value) => new ParameterConverter(value); 42 | public static implicit operator ParameterConverter(sbyte value) => new ParameterConverter(value); 43 | public static implicit operator ParameterConverter(byte value) => new ParameterConverter(value); 44 | public static implicit operator ParameterConverter(short value) => new ParameterConverter(value); 45 | public static implicit operator ParameterConverter(ushort value) => new ParameterConverter(value); 46 | public static implicit operator ParameterConverter(int value) => new ParameterConverter(value); 47 | public static implicit operator ParameterConverter(uint value) => new ParameterConverter(value); 48 | public static implicit operator ParameterConverter(long value) => new ParameterConverter(value); 49 | public static implicit operator ParameterConverter(ulong value) => new ParameterConverter(value); 50 | public static implicit operator ParameterConverter(float value) => new ParameterConverter(value); 51 | public static implicit operator ParameterConverter(double value) => new ParameterConverter(value); 52 | public static implicit operator ParameterConverter(string value) => new ParameterConverter(value); 53 | public static implicit operator ParameterConverter(TimeSpan value) => new ParameterConverter(value); 54 | public static implicit operator ParameterConverter(DateTime value) => new ParameterConverter(value); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /TS3Client/Commands/Ts3Command.cs: -------------------------------------------------------------------------------- 1 | // TS3AudioBot - An advanced Musicbot for Teamspeak 3 2 | // Copyright (C) 2016 TS3AudioBot contributors 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU Affero General Public License as 6 | // published by the Free Software Foundation, either version 3 of the 7 | // License, or (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU Affero General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU Affero General Public License 15 | // along with this program. If not, see . 16 | 17 | namespace TS3Client.Commands 18 | { 19 | using System; 20 | using System.Collections.Generic; 21 | using System.Text; 22 | using System.Text.RegularExpressions; 23 | 24 | public class Ts3Command 25 | { 26 | private static readonly Regex CommandMatch = new Regex(@"[a-z0-9_]+", RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.ECMAScript); 27 | public static List NoParameter => new List(); 28 | public static List NoOptions => new List(); 29 | 30 | public bool ExpectResponse { get; set; } 31 | public string Command { get; } 32 | private List parameter; 33 | private List options; 34 | 35 | public Ts3Command(string command) : this(command, NoParameter) { } 36 | public Ts3Command(string command, List parameter) : this(command, parameter, NoOptions) { } 37 | public Ts3Command(string command, List parameter, List options) 38 | { 39 | ExpectResponse = true; 40 | this.Command = command; 41 | this.parameter = parameter; 42 | this.options = options; 43 | } 44 | 45 | public void AppendParameter(CommandParameter addParameter) => parameter.Add(addParameter); 46 | public void AppendOption(CommandOption addOption) => options.Add(addOption); 47 | 48 | public override string ToString() => BuildToString(Command, parameter, options); 49 | 50 | public static string BuildToString(string command, IEnumerable parameter, IEnumerable options) 51 | { 52 | if (string.IsNullOrWhiteSpace(command)) 53 | throw new ArgumentNullException(nameof(command)); 54 | if (!CommandMatch.IsMatch(command)) 55 | throw new ArgumentException("Invalid command characters", nameof(command)); 56 | 57 | var strb = new StringBuilder(Ts3String.Escape(command)); 58 | 59 | foreach (var param in parameter) 60 | strb.Append(' ').Append(param.QueryString); 61 | 62 | foreach (var option in options) 63 | strb.Append(option.Value); 64 | 65 | return strb.ToString(); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /TS3Client/Commands/Ts3String.cs: -------------------------------------------------------------------------------- 1 | // TS3AudioBot - An advanced Musicbot for Teamspeak 3 2 | // Copyright (C) 2016 TS3AudioBot contributors 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU Affero General Public License as 6 | // published by the Free Software Foundation, either version 3 of the 7 | // License, or (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU Affero General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU Affero General Public License 15 | // along with this program. If not, see . 16 | 17 | namespace TS3Client.Commands 18 | { 19 | using System; 20 | using System.Linq; 21 | using System.Text; 22 | 23 | public static class Ts3String 24 | { 25 | public const int MaxMsgLength = 1024; 26 | 27 | public static string Escape(string stringToEscape) 28 | { 29 | StringBuilder strb = new StringBuilder(stringToEscape); 30 | strb = strb.Replace("\\", "\\\\"); // Backslash 31 | strb = strb.Replace("/", "\\/"); // Slash 32 | strb = strb.Replace(" ", "\\s"); // Whitespace 33 | strb = strb.Replace("|", "\\p"); // Pipe 34 | strb = strb.Replace("\f", "\\f"); // Formfeed 35 | strb = strb.Replace("\n", "\\n"); // Newline 36 | strb = strb.Replace("\r", "\\r"); // Carriage Return 37 | strb = strb.Replace("\t", "\\t"); // Horizontal Tab 38 | strb = strb.Replace("\v", "\\v"); // Vertical Tab 39 | return strb.ToString(); 40 | } 41 | 42 | public static string Unescape(string stringToUnescape) 43 | { 44 | StringBuilder strb = new StringBuilder(stringToUnescape.Length); 45 | for (int i = 0; i < stringToUnescape.Length; i++) 46 | { 47 | char c = stringToUnescape[i]; 48 | if (c == '\\') 49 | { 50 | if (++i >= stringToUnescape.Length) throw new FormatException(); 51 | switch (stringToUnescape[i]) 52 | { 53 | case 'v': strb.Append('\v'); break; // Vertical Tab 54 | case 't': strb.Append('\t'); break; // Horizontal Tab 55 | case 'r': strb.Append('\r'); break; // Carriage Return 56 | case 'n': strb.Append('\n'); break; // Newline 57 | case 'f': strb.Append('\f'); break; // Formfeed 58 | case 'p': strb.Append('|'); break; // Pipe 59 | case 's': strb.Append(' '); break; // Whitespace 60 | case '/': strb.Append('/'); break; // Slash 61 | case '\\': strb.Append('\\'); break; // Backslash 62 | default: throw new FormatException(); 63 | } 64 | } 65 | else strb.Append(c); 66 | } 67 | return strb.ToString(); 68 | } 69 | 70 | public static int TokenLength(string str) => str.Length + str.Count(IsDoubleChar); 71 | 72 | public static bool IsDoubleChar(char c) 73 | { 74 | return c == '\\' || 75 | c == '/' || 76 | c == ' ' || 77 | c == '|' || 78 | c == '\f' || 79 | c == '\n' || 80 | c == '\r' || 81 | c == '\t' || 82 | c == '\v'; 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /TS3Client/ConnectionData.cs: -------------------------------------------------------------------------------- 1 | // TS3AudioBot - An advanced Musicbot for Teamspeak 3 2 | // Copyright (C) 2016 TS3AudioBot contributors 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU Affero General Public License as 6 | // published by the Free Software Foundation, either version 3 of the 7 | // License, or (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU Affero General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU Affero General Public License 15 | // along with this program. If not, see . 16 | 17 | namespace TS3Client 18 | { 19 | using Full; 20 | 21 | public class ConnectionData 22 | { 23 | /// Hostname or Ip-Address of the server. 24 | public string Hostname { get; set; } 25 | /// Teamspeak serer port. Usually 9987. 26 | public ushort Port { get; set; } 27 | /// 28 | /// As Full Client: The display username. 29 | /// As Query Client: The query login name. 30 | /// 31 | public string Username { get; set; } 32 | /// 33 | /// As Full Client: The server password. 34 | /// As Query Client: The query login password. 35 | /// 36 | public string Password { get; set; } 37 | } 38 | 39 | public class ConnectionDataFull : ConnectionData 40 | { 41 | /// 42 | /// Secret identity of the user. 43 | /// 44 | public IdentityData Identity { get; set; } 45 | /// 46 | /// This can be set to true, when the password is already hashed. 47 | /// The hash works like this: base64(sha1(password)) 48 | /// 49 | public bool IsPasswordHashed { get; set; } = false; 50 | /// 51 | /// Set this to the TeamSpeak 3 Version this client should appear as. 52 | /// You can find predefined version data in the 53 | /// class. Please keep in mind that the version data has to have valid sign 54 | /// to be accepted by an official TeamSpeak 3 Server. 55 | /// 56 | public VersionSign VersionSign { get; set; } = VersionSign.VER_LIN_3_0_19_4; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /TS3Client/DisconnectEventArgs.cs: -------------------------------------------------------------------------------- 1 | // TS3AudioBot - An advanced Musicbot for Teamspeak 3 2 | // Copyright (C) 2016 TS3AudioBot contributors 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU Affero General Public License as 6 | // published by the Free Software Foundation, either version 3 of the 7 | // License, or (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU Affero General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU Affero General Public License 15 | // along with this program. If not, see . 16 | 17 | namespace TS3Client 18 | { 19 | using System; 20 | 21 | public class DisconnectEventArgs : EventArgs 22 | { 23 | public MoveReason ExitReason { get; } 24 | 25 | public DisconnectEventArgs(MoveReason exitReason) 26 | { 27 | ExitReason = exitReason; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /TS3Client/DocumentedEnums.cs: -------------------------------------------------------------------------------- 1 | // TS3AudioBot - An advanced Musicbot for Teamspeak 3 2 | // Copyright (C) 2016 TS3AudioBot contributors 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU Affero General Public License as 6 | // published by the Free Software Foundation, either version 3 of the 7 | // License, or (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU Affero General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU Affero General Public License 15 | // along with this program. If not, see . 16 | 17 | namespace TS3Client 18 | { 19 | // http://media.teamspeak.com/ts3_literature/TeamSpeak%203%20Server%20Query%20Manual.pdf 20 | // public_definitions.h from the ts3 plugin library 21 | 22 | public enum HostMessageMode 23 | { 24 | /// Dont display anything 25 | None = 0, 26 | /// Display message in chatlog. 27 | Log, 28 | /// Display message in modal dialog. 29 | Modal, 30 | /// Display message in modal dialog and close connection. 31 | ModalQuit 32 | } 33 | 34 | public enum HostBannerMode 35 | { 36 | ///Do not adjust. 37 | NoAdjust = 0, 38 | ///Adjust but ignore aspect ratio (like TeamSpeak 2). 39 | IgnoreAspect, 40 | ///Adjust and keep aspect ratio. 41 | KeepAspect 42 | } 43 | 44 | public enum Codec 45 | { 46 | ///mono, 16bit, 8kHz 47 | SpeexNarrowband = 0, 48 | ///mono, 16bit, 16kHz 49 | SpeexWideband, 50 | ///mono, 16bit, 32kHz 51 | SpeexUltraWideband, 52 | ///mono, 16bit, 48kHz 53 | CeltMono, 54 | ///mono, 16bit, 48kHz, optimized for voice 55 | OpusVoice, 56 | ///stereo, 16bit, 48kHz, optimized for music 57 | OpusMusic, 58 | } 59 | 60 | public enum CodecEncryptionMode 61 | { 62 | ///Configure per channel. 63 | Individual = 0, 64 | ///Globally disabled. 65 | Disabled, 66 | ///Globally enabled. 67 | Enabled 68 | } 69 | 70 | public enum LogLevel 71 | { 72 | ///Everything that is really bad. 73 | Error = 1, 74 | ///Everything that might be bad. 75 | Warning, 76 | ///Output that might help find a problem. 77 | Debug, 78 | ///Informational output. 79 | Info 80 | } 81 | 82 | public enum PermissionGroupDatabaseType 83 | { 84 | ///Template group (used for new virtual servers). 85 | Template = 0, 86 | ///Regular group (used for regular clients). 87 | Regular, 88 | ///Global query group (used for ServerQuery clients). 89 | Query 90 | } 91 | 92 | public enum PermissionGroupType 93 | { 94 | ///Server group permission. 95 | ServerGroup = 0, 96 | ///Client specific permission. 97 | GlobalClient, 98 | ///Channel specific permission. 99 | Channel, 100 | ///Channel group permission. 101 | ChannelGroup, 102 | ///Channel-client specific permission. 103 | ChannelClient 104 | } 105 | 106 | public enum TokenType 107 | { 108 | ///Server group token (id1={groupID} id2=0). 109 | ServerGroup = 0, 110 | ///Channel group token (id1={groupID} id2={channelID}). 111 | ChannelGroup 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /TS3Client/EventDispatcher.cs: -------------------------------------------------------------------------------- 1 | // TS3AudioBot - An advanced Musicbot for Teamspeak 3 2 | // Copyright (C) 2016 TS3AudioBot contributors 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU Affero General Public License as 6 | // published by the Free Software Foundation, either version 3 of the 7 | // License, or (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU Affero General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU Affero General Public License 15 | // along with this program. If not, see . 16 | 17 | namespace TS3Client 18 | { 19 | using System; 20 | using System.Collections.Concurrent; 21 | using System.Threading; 22 | 23 | internal static class EventDispatcherHelper 24 | { 25 | public static IEventDispatcher Create(EventDispatchType dispatcherType) 26 | { 27 | IEventDispatcher dispatcher; 28 | switch (dispatcherType) 29 | { 30 | case EventDispatchType.None: dispatcher = new NoEventDispatcher(); break; 31 | case EventDispatchType.CurrentThread: dispatcher = new CurrentThreadEventDisptcher(); break; 32 | case EventDispatchType.ExtraDispatchThread: dispatcher = new ExtraThreadEventDispatcher(); break; 33 | case EventDispatchType.DoubleThread: throw new NotSupportedException(); //break; 34 | case EventDispatchType.AutoThreadPooled: dispatcher = new AutoThreadPooledEventDispatcher(); break; 35 | case EventDispatchType.NewThreadEach: throw new NotSupportedException(); //break; 36 | default: throw new NotSupportedException(); 37 | } 38 | return dispatcher; 39 | } 40 | } 41 | 42 | /// Provides a function to run a receiving loop and asynchronously 43 | /// dispatch notifications. 44 | /// 45 | internal interface IEventDispatcher : IDisposable 46 | { 47 | /// Initializes the dispatcher. 48 | /// The main loop which will be receiving packets. 49 | /// The method to call asynchronously when a new 50 | /// notification comes in. 51 | void Init(Action eventLoop, Action dispatcher); 52 | /// Dispatches the notification. 53 | /// 54 | void Invoke(LazyNotification lazyNotification); 55 | /// Starts the eventLoop synchronously or asynchronous, 56 | /// depending on the dispatcher type. 57 | /// 58 | void EnterEventLoop(); 59 | void DoWork(); 60 | } 61 | 62 | internal sealed class CurrentThreadEventDisptcher : IEventDispatcher 63 | { 64 | private Action eventLoop; 65 | private Action dispatcher; 66 | 67 | public void Init(Action eventLoop, Action dispatcher) 68 | { 69 | this.eventLoop = eventLoop; 70 | this.dispatcher = dispatcher; 71 | } 72 | public void EnterEventLoop() => eventLoop(); 73 | public void Invoke(LazyNotification lazyNotification) => dispatcher.Invoke(lazyNotification); 74 | public void DoWork() { } 75 | public void Dispose() { } 76 | } 77 | 78 | internal sealed class ExtraThreadEventDispatcher : IEventDispatcher 79 | { 80 | private Action eventLoop; 81 | private Action dispatcher; 82 | private Thread readQueryThread; 83 | private readonly ConcurrentQueue eventQueue = new ConcurrentQueue(); 84 | private readonly AutoResetEvent eventBlock = new AutoResetEvent(false); 85 | private volatile bool run; 86 | 87 | public void Init(Action eventLoop, Action dispatcher) 88 | { 89 | run = true; 90 | this.eventLoop = eventLoop; 91 | this.dispatcher = dispatcher; 92 | readQueryThread = new Thread(DispatchLoop) { Name = "TS3Query MessageLoop" }; 93 | readQueryThread.Start(); 94 | } 95 | 96 | public void Invoke(LazyNotification lazyNotification) 97 | { 98 | eventQueue.Enqueue(lazyNotification); 99 | eventBlock.Set(); 100 | } 101 | 102 | public void EnterEventLoop() => eventLoop(); 103 | 104 | private void DispatchLoop() 105 | { 106 | while (run) 107 | { 108 | eventBlock.WaitOne(); 109 | while (!eventQueue.IsEmpty) 110 | { 111 | LazyNotification lazyNotification; 112 | if (eventQueue.TryDequeue(out lazyNotification)) 113 | dispatcher.Invoke(lazyNotification); 114 | } 115 | } 116 | } 117 | 118 | public void DoWork() 119 | { 120 | if (Thread.CurrentThread.ManagedThreadId != readQueryThread.ManagedThreadId) 121 | return; 122 | LazyNotification lazyNotification; 123 | if (eventQueue.TryDequeue(out lazyNotification)) 124 | dispatcher.Invoke(lazyNotification); 125 | } 126 | 127 | public void Dispose() 128 | { 129 | run = false; 130 | eventBlock.Set(); 131 | } 132 | } 133 | 134 | internal sealed class NoEventDispatcher : IEventDispatcher 135 | { 136 | public void Init(Action eventLoop, Action dispatcher) { } 137 | public void EnterEventLoop() { } 138 | public void Invoke(LazyNotification lazyNotification) { } 139 | public void DoWork() { } 140 | public void Dispose() { } 141 | } 142 | 143 | internal sealed class AutoThreadPooledEventDispatcher : IEventDispatcher 144 | { 145 | private Thread readQueryThread; 146 | private Action dispatcher; 147 | 148 | public void Init(Action eventLoop, Action dispatcher) 149 | { 150 | this.dispatcher = dispatcher; 151 | readQueryThread = new Thread(eventLoop.Invoke) { Name = "TS3Query MessageLoop" }; 152 | readQueryThread.Start(); 153 | } 154 | public void EnterEventLoop() { } 155 | public void Invoke(LazyNotification lazyNotification) => ThreadPool.QueueUserWorkItem(Call, lazyNotification); 156 | private void Call(object obj) => dispatcher.Invoke((LazyNotification)obj); 157 | public void DoWork() { } 158 | public void Dispose() { } 159 | } 160 | 161 | public enum EventDispatchType 162 | { 163 | /// 164 | /// All events will be dropped. 165 | /// 166 | None, 167 | /// 168 | /// Will use the same thread that entered the 169 | /// for receiving and invoking all events. This method is not recommended since it mostly 170 | /// only produces deadlocks. (Usually only for debugging) 171 | /// 172 | CurrentThread, 173 | /// 174 | /// Will use the thread that entered the for 175 | /// receiving and starts a second thread for invoking all events. This is the best method for 176 | /// lightweight dipatching with no parallelization. 177 | /// 178 | ExtraDispatchThread, 179 | /// 180 | /// Will start one thread for receiving and a second thread for invoking all events. 181 | /// This is the best method for lightweight asynchronous dipatching with no parallelization. 182 | /// 183 | DoubleThread, 184 | /// 185 | /// This method will use the from .NET to dispatch all events. 186 | /// This is the best method for high parallelization with low overhead when using many instances. 187 | /// 188 | AutoThreadPooled, 189 | /// 190 | /// This method will create a new Thread for each event. This method is not recommended 191 | /// due to high overhead and resource consumption. Only try it when all else fails. 192 | /// 193 | NewThreadEach, 194 | } 195 | } 196 | -------------------------------------------------------------------------------- /TS3Client/Full/BasePacket.cs: -------------------------------------------------------------------------------- 1 | // TS3AudioBot - An advanced Musicbot for Teamspeak 3 2 | // Copyright (C) 2016 TS3AudioBot contributors 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU Affero General Public License as 6 | // published by the Free Software Foundation, either version 3 of the 7 | // License, or (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU Affero General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU Affero General Public License 15 | // along with this program. If not, see . 16 | 17 | namespace TS3Client.Full 18 | { 19 | class BasePacket 20 | { 21 | public PacketType PacketType 22 | { 23 | get { return (PacketType)(PacketTypeFlagged & 0x0F); } 24 | set { PacketTypeFlagged = (byte)((PacketTypeFlagged & 0xF0) | ((byte)value & 0x0F)); } 25 | } 26 | public PacketFlags PacketFlags 27 | { 28 | get { return (PacketFlags)(PacketTypeFlagged & 0xF0); } 29 | set { PacketTypeFlagged = (byte)((PacketTypeFlagged & 0x0F) | ((byte)value & 0xF0)); } 30 | } 31 | public byte PacketTypeFlagged { get; set; } 32 | public ushort PacketId { get; set; } 33 | public int Size => Data.Length; 34 | 35 | public byte[] Raw { get; set; } 36 | public byte[] Header { get; protected set; } 37 | public byte[] Data { get; set; } 38 | 39 | public BasePacket() 40 | { 41 | } 42 | 43 | 44 | public bool FragmentedFlag 45 | { 46 | get { return (PacketFlags.HasFlag(PacketFlags.Fragmented)); } 47 | set 48 | { 49 | if (value) PacketTypeFlagged |= (byte)PacketFlags.Fragmented; 50 | else PacketTypeFlagged &= (byte)~PacketFlags.Fragmented; 51 | } 52 | } 53 | public bool NewProtocolFlag 54 | { 55 | get { return (PacketFlags.HasFlag(PacketFlags.Newprotocol)); } 56 | set 57 | { 58 | if (value) PacketTypeFlagged |= (byte)PacketFlags.Newprotocol; 59 | else PacketTypeFlagged &= (byte)~PacketFlags.Newprotocol; 60 | } 61 | } 62 | public bool CompressedFlag 63 | { 64 | get { return (PacketFlags.HasFlag(PacketFlags.Compressed)); } 65 | set 66 | { 67 | if (value) PacketTypeFlagged |= (byte)PacketFlags.Compressed; 68 | else PacketTypeFlagged &= (byte)~PacketFlags.Compressed; 69 | } 70 | } 71 | public bool UnencryptedFlag 72 | { 73 | get { return (PacketFlags.HasFlag(PacketFlags.Unencrypted)); } 74 | set 75 | { 76 | if (value) PacketTypeFlagged |= (byte)PacketFlags.Unencrypted; 77 | else PacketTypeFlagged &= (byte)~PacketFlags.Unencrypted; 78 | } 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /TS3Client/Full/IdentityData.cs: -------------------------------------------------------------------------------- 1 | // TS3AudioBot - An advanced Musicbot for Teamspeak 3 2 | // Copyright (C) 2016 TS3AudioBot contributors 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU Affero General Public License as 6 | // published by the Free Software Foundation, either version 3 of the 7 | // License, or (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU Affero General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU Affero General Public License 15 | // along with this program. If not, see . 16 | 17 | namespace TS3Client.Full 18 | { 19 | using Org.BouncyCastle.Math; 20 | using Org.BouncyCastle.Math.EC; 21 | 22 | public class IdentityData 23 | { 24 | public string PublicKeyString { get; set; } 25 | public string PrivateKeyString { get; set; } 26 | public ECPoint PublicKey { get; set; } 27 | public BigInteger PrivateKey { get; set; } 28 | public ulong ValidKeyOffset { get; set; } 29 | public ulong LastCheckedKeyOffset { get; set; } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /TS3Client/Full/IncomingPacket.cs: -------------------------------------------------------------------------------- 1 | // TS3AudioBot - An advanced Musicbot for Teamspeak 3 2 | // Copyright (C) 2016 TS3AudioBot contributors 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU Affero General Public License as 6 | // published by the Free Software Foundation, either version 3 of the 7 | // License, or (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU Affero General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU Affero General Public License 15 | // along with this program. If not, see . 16 | 17 | namespace TS3Client.Full 18 | { 19 | class IncomingPacket : BasePacket 20 | { 21 | public IncomingPacket(byte[] raw) 22 | { 23 | Raw = raw; 24 | Header = new byte[3]; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /TS3Client/Full/NetUtil.cs: -------------------------------------------------------------------------------- 1 | // TS3AudioBot - An advanced Musicbot for Teamspeak 3 2 | // Copyright (C) 2016 TS3AudioBot contributors 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU Affero General Public License as 6 | // published by the Free Software Foundation, either version 3 of the 7 | // License, or (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU Affero General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU Affero General Public License 15 | // along with this program. If not, see . 16 | 17 | namespace TS3Client.Full 18 | { 19 | using System; 20 | using System.Net; 21 | 22 | internal static class NetUtil 23 | { 24 | // Common Network to Host and Host to Network swaps 25 | public static uint H2N(uint value) => unchecked((uint)IPAddress.HostToNetworkOrder((int)value)); 26 | 27 | public static ushort N2Hushort(byte[] intArr, int inOff) 28 | { 29 | if (!BitConverter.IsLittleEndian) 30 | { 31 | return (ushort)(intArr[inOff] | (intArr[inOff + 1] << 8)); 32 | } 33 | else 34 | { 35 | return (ushort)((intArr[inOff] << 8) | intArr[inOff + 1]); 36 | } 37 | } 38 | public static void H2N(ushort value, byte[] outArr, int outOff) 39 | { 40 | if (!BitConverter.IsLittleEndian) 41 | { 42 | outArr[outOff] = (byte)(value & 0xFF); 43 | outArr[outOff + 1] = (byte)((value >> 8) & 0xFF); 44 | } 45 | else 46 | { 47 | outArr[outOff] = (byte)((value >> 8) & 0xFF); 48 | outArr[outOff + 1] = (byte)(value & 0xFF); 49 | } 50 | } 51 | 52 | public static void H2N(ulong value, byte[] outArr, int outOff) 53 | { 54 | if (!BitConverter.IsLittleEndian) 55 | { 56 | outArr[outOff + 0] = (byte)((value >> 00) & 0xFF); 57 | outArr[outOff + 1] = (byte)((value >> 08) & 0xFF); 58 | outArr[outOff + 2] = (byte)((value >> 16) & 0xFF); 59 | outArr[outOff + 3] = (byte)((value >> 24) & 0xFF); 60 | outArr[outOff + 4] = (byte)((value >> 32) & 0xFF); 61 | outArr[outOff + 5] = (byte)((value >> 40) & 0xFF); 62 | outArr[outOff + 6] = (byte)((value >> 48) & 0xFF); 63 | outArr[outOff + 7] = (byte)((value >> 56) & 0xFF); 64 | } 65 | else 66 | { 67 | outArr[outOff + 0] = (byte)((value >> 56) & 0xFF); 68 | outArr[outOff + 1] = (byte)((value >> 48) & 0xFF); 69 | outArr[outOff + 2] = (byte)((value >> 40) & 0xFF); 70 | outArr[outOff + 3] = (byte)((value >> 32) & 0xFF); 71 | outArr[outOff + 4] = (byte)((value >> 24) & 0xFF); 72 | outArr[outOff + 5] = (byte)((value >> 16) & 0xFF); 73 | outArr[outOff + 6] = (byte)((value >> 08) & 0xFF); 74 | outArr[outOff + 7] = (byte)((value >> 00) & 0xFF); 75 | } 76 | } 77 | 78 | public static int N2Hint(byte[] intArr, int inOff) 79 | { 80 | if (!BitConverter.IsLittleEndian) 81 | { 82 | return intArr[inOff] | (intArr[inOff + 1] << 8) | (intArr[inOff + 2] << 16) | (intArr[inOff + 3] << 24); 83 | } 84 | else 85 | { 86 | return (intArr[inOff] << 24) | (intArr[inOff + 1] << 16) | (intArr[inOff + 2] << 8) | intArr[inOff + 3]; 87 | } 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /TS3Client/Full/NetworkStats.cs: -------------------------------------------------------------------------------- 1 | // TS3AudioBot - An advanced Musicbot for Teamspeak 3 2 | // Copyright (C) 2016 TS3AudioBot contributors 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU Affero General Public License as 6 | // published by the Free Software Foundation, either version 3 of the 7 | // License, or (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU Affero General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU Affero General Public License 15 | // along with this program. If not, see . 16 | 17 | namespace TS3Client.Full 18 | { 19 | using Commands; 20 | using System; 21 | using System.Collections.Generic; 22 | using System.Linq; 23 | 24 | internal class NetworkStats 25 | { 26 | private long[] outPackets = new long[3]; 27 | private long[] inPackets = new long[3]; 28 | private long[] outBytes = new long[3]; 29 | private long[] inBytes = new long[3]; 30 | private Queue outBytesTime = new Queue(); 31 | private Queue inBytesTime = new Queue(); 32 | private Queue pingTimes = new Queue(60); 33 | private static readonly TimeSpan TimeSecond = TimeSpan.FromSeconds(1); 34 | private static readonly TimeSpan TimeMinute = TimeSpan.FromMinutes(1); 35 | private readonly object queueLock = new object(); 36 | 37 | public void LogOutPacket(OutgoingPacket packet) 38 | { 39 | var kind = TypeToKind(packet.PacketType); 40 | outPackets[(int)kind]++; 41 | outBytes[(int)kind] += packet.Raw.Length; 42 | lock (queueLock) 43 | { 44 | DropOver(outBytesTime, TimeMinute); 45 | outBytesTime.Enqueue(new PacketData(packet.Raw.Length, Util.Now, kind)); 46 | } 47 | } 48 | 49 | public void LogInPacket(IncomingPacket packet) 50 | { 51 | var kind = TypeToKind(packet.PacketType); 52 | inPackets[(int)kind]++; 53 | inBytes[(int)kind] += packet.Raw.Length; 54 | lock (queueLock) 55 | { 56 | DropOver(inBytesTime, TimeMinute); 57 | inBytesTime.Enqueue(new PacketData(packet.Raw.Length, Util.Now, kind)); 58 | } 59 | } 60 | 61 | public void AddPing(TimeSpan ping) 62 | { 63 | lock (queueLock) 64 | { 65 | if (pingTimes.Count >= 60) 66 | pingTimes.Dequeue(); 67 | pingTimes.Enqueue(ping); 68 | } 69 | } 70 | 71 | private static PacketKind TypeToKind(PacketType type) 72 | { 73 | switch (type) 74 | { 75 | case PacketType.Voice: 76 | case PacketType.VoiceWhisper: 77 | return PacketKind.Speech; 78 | case PacketType.Command: 79 | case PacketType.CommandLow: 80 | case PacketType.Ack: 81 | case PacketType.AckLow: 82 | case PacketType.Init1: 83 | return PacketKind.Control; 84 | case PacketType.Ping: 85 | case PacketType.Pong: 86 | return PacketKind.Keepalive; 87 | default: 88 | throw new ArgumentOutOfRangeException(nameof(type)); 89 | } 90 | } 91 | 92 | private static long[] GetWithin(Queue queue, TimeSpan time) 93 | { 94 | var now = Util.Now; 95 | long[] bandwidth = new long[3]; 96 | foreach (var pack in queue.Reverse()) 97 | if (now - pack.SendPoint <= time) 98 | bandwidth[(int)pack.Kind] += pack.Size; 99 | else 100 | break; 101 | for (int i = 0; i < 3; i++) 102 | bandwidth[i] = (long)(bandwidth[i] / time.TotalSeconds); 103 | return bandwidth; 104 | } 105 | 106 | private static void DropOver(Queue queue, TimeSpan time) 107 | { 108 | var now = Util.Now; 109 | while (queue.Any() && now - queue.Peek().SendPoint > time) 110 | queue.Dequeue(); 111 | } 112 | 113 | public Ts3Command GenerateStatusAnswer() 114 | { 115 | long[] lastSecondIn; 116 | long[] lastSecondOut; 117 | long[] lastMinuteIn; 118 | long[] lastMinuteOut; 119 | double lastPing; 120 | double avgPing; 121 | lock (queueLock) 122 | { 123 | lastSecondIn = GetWithin(inBytesTime, TimeSecond); 124 | lastSecondOut = GetWithin(outBytesTime, TimeSecond); 125 | lastMinuteIn = GetWithin(inBytesTime, TimeMinute); 126 | lastMinuteOut = GetWithin(outBytesTime, TimeMinute); 127 | if (pingTimes.Any()) 128 | { 129 | lastPing = pingTimes.Last().Milliseconds; 130 | avgPing = pingTimes.Average(ts => ts.Milliseconds); 131 | } 132 | else 133 | { 134 | lastPing = avgPing = 0; 135 | } 136 | } 137 | 138 | return new Ts3Command("setconnectioninfo", new List() 139 | { 140 | new CommandParameter("connection_ping", lastPing), 141 | new CommandParameter("connection_ping_deviation", Math.Abs(lastPing - avgPing)), 142 | new CommandParameter("connection_packets_sent_speech", outPackets[(int)PacketKind.Speech]), 143 | new CommandParameter("connection_packets_sent_keepalive", outPackets[(int)PacketKind.Keepalive]), 144 | new CommandParameter("connection_packets_sent_control", outPackets[(int)PacketKind.Control]), 145 | new CommandParameter("connection_bytes_sent_speech", outBytes[(int)PacketKind.Speech]), 146 | new CommandParameter("connection_bytes_sent_keepalive", outBytes[(int)PacketKind.Keepalive]), 147 | new CommandParameter("connection_bytes_sent_control", outBytes[(int)PacketKind.Control]), 148 | new CommandParameter("connection_packets_received_speech", inPackets[(int)PacketKind.Speech]), 149 | new CommandParameter("connection_packets_received_keepalive", inPackets[(int)PacketKind.Keepalive]), 150 | new CommandParameter("connection_packets_received_control", inPackets[(int)PacketKind.Control]), 151 | new CommandParameter("connection_bytes_received_speech", inBytes[(int)PacketKind.Speech]), 152 | new CommandParameter("connection_bytes_received_keepalive", inBytes[(int)PacketKind.Keepalive]), 153 | new CommandParameter("connection_bytes_received_control", inBytes[(int)PacketKind.Control]), 154 | new CommandParameter("connection_server2client_packetloss_speech", 42.0000f), 155 | new CommandParameter("connection_server2client_packetloss_keepalive", 1.0000f), 156 | new CommandParameter("connection_server2client_packetloss_control", 0.5000f), 157 | new CommandParameter("connection_server2client_packetloss_total", 0.0000f), 158 | new CommandParameter("connection_bandwidth_sent_last_second_speech", lastSecondOut[(int)PacketKind.Speech]), 159 | new CommandParameter("connection_bandwidth_sent_last_second_keepalive", lastSecondOut[(int)PacketKind.Keepalive]), 160 | new CommandParameter("connection_bandwidth_sent_last_second_control", lastSecondOut[(int)PacketKind.Control]), 161 | new CommandParameter("connection_bandwidth_sent_last_minute_speech", lastMinuteOut[(int)PacketKind.Speech]), 162 | new CommandParameter("connection_bandwidth_sent_last_minute_keepalive", lastMinuteOut[(int)PacketKind.Keepalive]), 163 | new CommandParameter("connection_bandwidth_sent_last_minute_control", lastMinuteOut[(int)PacketKind.Control]), 164 | new CommandParameter("connection_bandwidth_received_last_second_speech", lastSecondIn[(int)PacketKind.Speech]), 165 | new CommandParameter("connection_bandwidth_received_last_second_keepalive", lastSecondIn[(int)PacketKind.Keepalive]), 166 | new CommandParameter("connection_bandwidth_received_last_second_control", lastSecondIn[(int)PacketKind.Control]), 167 | new CommandParameter("connection_bandwidth_received_last_minute_speech", lastMinuteIn[(int)PacketKind.Speech]), 168 | new CommandParameter("connection_bandwidth_received_last_minute_keepalive", lastMinuteIn[(int)PacketKind.Keepalive]), 169 | new CommandParameter("connection_bandwidth_received_last_minute_control", lastMinuteIn[(int)PacketKind.Control]), 170 | }); 171 | } 172 | 173 | public void Reset() 174 | { 175 | Array.Clear(outPackets, 0, outPackets.Length); 176 | Array.Clear(inPackets, 0, inPackets.Length); 177 | Array.Clear(outBytes, 0, outBytes.Length); 178 | Array.Clear(inBytes, 0, inBytes.Length); 179 | outBytesTime.Clear(); 180 | inBytesTime.Clear(); 181 | } 182 | 183 | private enum PacketKind 184 | { 185 | Speech, 186 | Keepalive, 187 | Control, 188 | } 189 | 190 | private struct PacketData 191 | { 192 | public long Size { get; } 193 | public DateTime SendPoint { get; } 194 | public PacketKind Kind { get; } 195 | 196 | public PacketData(long size, DateTime sendPoint, PacketKind kind) { Size = size; SendPoint = sendPoint; Kind = kind; } 197 | } 198 | } 199 | } 200 | -------------------------------------------------------------------------------- /TS3Client/Full/OutgoingPacket.cs: -------------------------------------------------------------------------------- 1 | // TS3AudioBot - An advanced Musicbot for Teamspeak 3 2 | // Copyright (C) 2016 TS3AudioBot contributors 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU Affero General Public License as 6 | // published by the Free Software Foundation, either version 3 of the 7 | // License, or (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU Affero General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU Affero General Public License 15 | // along with this program. If not, see . 16 | 17 | namespace TS3Client.Full 18 | { 19 | using System; 20 | 21 | class OutgoingPacket : BasePacket 22 | { 23 | public ushort ClientId { get; set; } 24 | 25 | public DateTime LastSendTime { get; set; } = DateTime.MaxValue; 26 | public int ResendCount { get; set; } = 0; 27 | 28 | public OutgoingPacket(byte[] data, PacketType type) 29 | { 30 | Data = data; 31 | PacketType = type; 32 | Header = new byte[5]; 33 | } 34 | 35 | public void BuildHeader() 36 | { 37 | NetUtil.H2N(PacketId, Header, 0); 38 | NetUtil.H2N(ClientId, Header, 2); 39 | Header[4] = PacketTypeFlagged; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /TS3Client/Full/PacketType.cs: -------------------------------------------------------------------------------- 1 | // TS3AudioBot - An advanced Musicbot for Teamspeak 3 2 | // Copyright (C) 2016 TS3AudioBot contributors 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU Affero General Public License as 6 | // published by the Free Software Foundation, either version 3 of the 7 | // License, or (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU Affero General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU Affero General Public License 15 | // along with this program. If not, see . 16 | 17 | namespace TS3Client.Full 18 | { 19 | using System; 20 | 21 | internal enum PacketType : byte 22 | { 23 | Voice = 0x0, 24 | VoiceWhisper = 0x1, 25 | Command = 0x2, 26 | CommandLow = 0x3, 27 | Ping = 0x4, 28 | Pong = 0x5, 29 | Ack = 0x6, 30 | AckLow = 0x7, 31 | Init1 = 0x8, 32 | } 33 | 34 | [Flags] 35 | internal enum PacketFlags : byte 36 | { 37 | None = 0x0, 38 | Fragmented = 0x10, 39 | Newprotocol = 0x20, 40 | Compressed = 0x40, 41 | Unencrypted = 0x80, 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /TS3Client/Full/RingQueue.cs: -------------------------------------------------------------------------------- 1 | // TS3AudioBot - An advanced Musicbot for Teamspeak 3 2 | // Copyright (C) 2016 TS3AudioBot contributors 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU Affero General Public License as 6 | // published by the Free Software Foundation, either version 3 of the 7 | // License, or (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU Affero General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU Affero General Public License 15 | // along with this program. If not, see . 16 | 17 | namespace TS3Client.Full 18 | { 19 | using System; 20 | 21 | internal class RingQueue 22 | { 23 | private int currentStart; 24 | private T[] ringBuffer; 25 | private bool[] ringDoneState; 26 | 27 | public int StartIndex { get; private set; } 28 | public int EndIndex => StartIndex + Count; 29 | public int Count { get; private set; } 30 | 31 | public RingQueue(int bufferSize) 32 | { 33 | ringBuffer = new T[bufferSize]; 34 | ringDoneState = new bool[bufferSize]; 35 | Clear(); 36 | } 37 | 38 | public bool Fits(int index) => index < StartIndex + ringBuffer.Length; 39 | 40 | public void Set(T data, int index) 41 | { 42 | if (!Fits(index)) 43 | throw new ArgumentOutOfRangeException(nameof(index), "Buffer is not large enough for this object."); 44 | if (IsSet(index)) 45 | throw new ArgumentOutOfRangeException(nameof(index), "Object already set."); 46 | 47 | int localIndex = IndexToLocal(index); 48 | ringBuffer[localIndex] = data; 49 | ringDoneState[localIndex] = true; 50 | Count++; 51 | } 52 | 53 | public bool TryDequeue(out T obj) 54 | { 55 | if (!TryPeek(StartIndex, out obj)) return false; 56 | 57 | ringDoneState[currentStart] = false; 58 | 59 | StartIndex++; 60 | Count--; 61 | currentStart = (currentStart + 1) % ringBuffer.Length; 62 | return true; 63 | } 64 | 65 | public bool TryPeek(int index, out T obj) 66 | { 67 | int localIndex = IndexToLocal(index); 68 | if (ringDoneState[localIndex] != true) { obj = default(T); return false; } 69 | else { obj = ringBuffer[localIndex]; return true; } 70 | } 71 | 72 | public bool IsSet(int index) 73 | { 74 | if (index < StartIndex) return true; 75 | if (index >= EndIndex) return false; 76 | return ringDoneState[IndexToLocal(index)]; 77 | } 78 | 79 | private int IndexToLocal(int index) => (currentStart + index - StartIndex) % ringBuffer.Length; 80 | 81 | public void Clear() 82 | { 83 | currentStart = 0; 84 | StartIndex = 0; 85 | Count = 0; 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /TS3Client/Full/VersionSign.cs: -------------------------------------------------------------------------------- 1 | // TS3AudioBot - An advanced Musicbot for Teamspeak 3 2 | // Copyright (C) 2016 TS3AudioBot contributors 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU Affero General Public License as 6 | // published by the Free Software Foundation, either version 3 of the 7 | // License, or (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU Affero General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU Affero General Public License 15 | // along with this program. If not, see . 16 | 17 | namespace TS3Client.Full 18 | { 19 | public class VersionSign 20 | { 21 | private static readonly string[] plattforms = new[] { "Windows", "Linux", "OS X", "Android" }; 22 | 23 | public string Sign { get; } 24 | public string Name { get; } 25 | ClientPlattform Plattform { get; } 26 | public string PlattformName { get; } 27 | 28 | public VersionSign(string name, ClientPlattform plattform, string sign) 29 | { 30 | Name = name; 31 | Sign = sign; 32 | Plattform = plattform; 33 | PlattformName = plattforms[(int)plattform]; 34 | } 35 | 36 | // Many ids implemented from here: https://r4p3.net/threads/client-builds.499/ 37 | 38 | public static readonly VersionSign VER_WIN_3_0_19_3 39 | = new VersionSign("3.0.19.3 [Build: 1466672534]", ClientPlattform.Windows, "a1OYzvM18mrmfUQBUgxYBxYz2DUU6y5k3/mEL6FurzU0y97Bd1FL7+PRpcHyPkg4R+kKAFZ1nhyzbgkGphDWDg=="); 40 | public static readonly VersionSign VER_WIN_3_0_19_4 41 | = new VersionSign("3.0.19.4 [Build: 1468491418]", ClientPlattform.Windows, "ldWL49uDKC3N9uxdgWRMTOzUuiG1nBqUiOa+Nal5HvdxJiN4fsTnmmPo5tvglN7WqoVoFfuuKuYq1LzodtEtCg=="); 42 | public static readonly VersionSign VER_LIN_3_0_19_4 43 | = new VersionSign("3.0.19.4 [Build: 1468491418]", ClientPlattform.Linux, "jvhhk75EV3nCGeewx4Y5zZmiZSN07q5ByKZ9Wlmg85aAbnw7c1jKq5/Iq0zY6dfGwCEwuKod0I5lQcVLf2NTCg=="); 44 | public static readonly VersionSign VER_OSX_3_0_19_4 45 | = new VersionSign("3.0.19.4 [Build: 1468491418]", ClientPlattform.Osx, "Pvcizdk3HRQMzTLt7goUYBmmS5nbAS1g2E6HIypLU+9eXTqGTBLim0UUtKc0s867TFHbK91GroDrTtv0aMUGAw=="); 46 | public static readonly VersionSign VER_WIN_3_0_20 47 | = new VersionSign("3.0.20 [Build: 1465542546]", ClientPlattform.Windows, "vDK31sOwOvDpTXgqAJzmR1NzeUeSDG9dLMgIz5LCX+KpDSVD/qU60mzScz9tuc9AsLyrL8DxHpDDO3eQD+hYCA=="); 48 | public static readonly VersionSign VER_AND_3_0_23 49 | = new VersionSign("3.0.23 [Build: 1463662487]", ClientPlattform.Android, "RN+cwFI+jSHJEhggucIuUyEteWNVFy4iw0QDp3qn2UzfopypFVE9BPZqJjBUGeoCN7Q/SfYL4RNIRzJEQaZUCA=="); 50 | public static readonly VersionSign VER_WIN_3_1 51 | = new VersionSign("3.1 [Build: 1471417187]", ClientPlattform.Windows, "Vr9F7kbVorcrkV5b/Iw+feH9qmDGvfsW8tpa737zhc1fDpK5uaEo6M5l2DzgaGqqOr3GKl5A7PF9Sj6eTM26Aw=="); 52 | } 53 | 54 | public enum ClientPlattform 55 | { 56 | Windows = 0, 57 | Linux, 58 | Osx, 59 | Android, 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /TS3Client/LazyNotification.cs: -------------------------------------------------------------------------------- 1 | // TS3AudioBot - An advanced Musicbot for Teamspeak 3 2 | // Copyright (C) 2016 TS3AudioBot contributors 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU Affero General Public License as 6 | // published by the Free Software Foundation, either version 3 of the 7 | // License, or (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU Affero General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU Affero General Public License 15 | // along with this program. If not, see . 16 | 17 | namespace TS3Client 18 | { 19 | using Messages; 20 | using System.Collections.Generic; 21 | 22 | struct LazyNotification 23 | { 24 | public readonly IEnumerable Notifications; 25 | public readonly NotificationType NotifyType; 26 | 27 | public LazyNotification(IEnumerable notifications, NotificationType notifyType) 28 | { 29 | Notifications = notifications; 30 | NotifyType = notifyType; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /TS3Client/MessageProcessor.cs: -------------------------------------------------------------------------------- 1 | // TS3AudioBot - An advanced Musicbot for Teamspeak 3 2 | // Copyright (C) 2016 TS3AudioBot contributors 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU Affero General Public License as 6 | // published by the Free Software Foundation, either version 3 of the 7 | // License, or (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU Affero General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU Affero General Public License 15 | // along with this program. If not, see . 16 | 17 | namespace TS3Client 18 | { 19 | using Messages; 20 | using Commands; 21 | using System; 22 | using System.Linq; 23 | using System.Collections.Generic; 24 | 25 | internal class MessageProcessor 26 | { 27 | private readonly Dictionary requestDict; 28 | private readonly Queue requestQueue; 29 | private readonly bool synchronQueue; 30 | 31 | private string cmdLineBuffer; 32 | 33 | public MessageProcessor(bool synchronQueue) 34 | { 35 | this.synchronQueue = synchronQueue; 36 | if (synchronQueue) 37 | requestQueue = new Queue(); 38 | else 39 | requestDict = new Dictionary(); 40 | } 41 | 42 | public LazyNotification? PushMessage(string message) 43 | { 44 | string notifyname; 45 | int splitindex = message.IndexOf(' '); 46 | if (splitindex < 0) 47 | notifyname = message.TrimEnd(); 48 | else 49 | notifyname = message.Substring(0, splitindex); 50 | 51 | var ntfyType = MessageHelper.GetNotificationType(notifyname); 52 | if (ntfyType == NotificationType.Unknown) 53 | { 54 | cmdLineBuffer = message; 55 | return null; 56 | } 57 | 58 | var lineDataPart = splitindex < 0 ? "" : message.Substring(splitindex); 59 | 60 | // if it's not an error it is a notification 61 | if (ntfyType != NotificationType.Error) 62 | { 63 | var notification = CommandDeserializer.GenerateNotification(lineDataPart, ntfyType); 64 | var lazyNotification = new LazyNotification(notification, ntfyType); 65 | return lazyNotification; 66 | } 67 | 68 | var errorStatus = (CommandError)CommandDeserializer.GenerateSingleNotification(lineDataPart, NotificationType.Error); 69 | 70 | if (synchronQueue) 71 | { 72 | if (requestQueue.Any()) 73 | { 74 | var waitBlock = requestQueue.Dequeue(); 75 | waitBlock.SetAnswer(errorStatus, cmdLineBuffer); 76 | cmdLineBuffer = null; 77 | } 78 | else { /* ??? */ } 79 | } 80 | else 81 | { 82 | // now check if this error is an answer to a request we made 83 | // if there is no return code provided it means it is a error-notification 84 | if (string.IsNullOrEmpty(errorStatus.ReturnCode)) 85 | { 86 | return new LazyNotification(new[] { errorStatus }, ntfyType); 87 | } 88 | 89 | // otherwise it is the result status code to a request 90 | WaitBlock waitBlock; 91 | if (requestDict.TryGetValue(errorStatus.ReturnCode, out waitBlock)) 92 | { 93 | requestDict.Remove(errorStatus.ReturnCode); 94 | waitBlock.SetAnswer(errorStatus, cmdLineBuffer); 95 | cmdLineBuffer = null; 96 | } 97 | else { /* ??? */ } 98 | } 99 | 100 | return null; 101 | } 102 | 103 | public void EnqueueRequest(string returnCode, WaitBlock waitBlock) 104 | { 105 | if (synchronQueue) 106 | throw new InvalidOperationException(); 107 | requestDict.Add(returnCode, waitBlock); 108 | } 109 | 110 | public void EnqueueRequest(WaitBlock waitBlock) 111 | { 112 | if (!synchronQueue) 113 | throw new InvalidOperationException(); 114 | requestQueue.Enqueue(waitBlock); 115 | } 116 | 117 | public void DropQueue() 118 | { 119 | if (synchronQueue) 120 | { 121 | while (requestQueue.Any()) 122 | requestQueue.Dequeue().SetAnswer( 123 | new CommandError { Id = Ts3ErrorCode.custom_error, Message = "Connection Closed" }); 124 | } 125 | else 126 | { 127 | var arr = requestDict.ToArray(); 128 | requestDict.Clear(); 129 | foreach (var val in arr) 130 | val.Value.SetAnswer( 131 | new CommandError { Id = Ts3ErrorCode.custom_error, Message = "Connection Closed" }); 132 | } 133 | } 134 | } 135 | 136 | /*internal class AsyncMessageProcessor : MessageProcessor 137 | { 138 | 139 | }*/ 140 | } 141 | -------------------------------------------------------------------------------- /TS3Client/Messages/BaseTypes.cs: -------------------------------------------------------------------------------- 1 | // TS3AudioBot - An advanced Musicbot for Teamspeak 3 2 | // Copyright (C) 2016 TS3AudioBot contributors 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU Affero General Public License as 6 | // published by the Free Software Foundation, either version 3 of the 7 | // License, or (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU Affero General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU Affero General Public License 15 | // along with this program. If not, see . 16 | 17 | namespace TS3Client.Messages 18 | { 19 | public interface IQueryMessage 20 | { 21 | void SetField(string name, string value); 22 | } 23 | 24 | public interface INotification : IQueryMessage 25 | { 26 | NotificationType NotifyType { get; } 27 | } 28 | 29 | public interface IResponse : IQueryMessage 30 | { 31 | string ReturnCode { get; set; } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /TS3Client/Messages/MessageTemplates.tt: -------------------------------------------------------------------------------- 1 | // TS3AudioBot - An advanced Musicbot for Teamspeak 3 2 | // Copyright (C) 2016 TS3AudioBot contributors 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU Affero General Public License as 6 | // published by the Free Software Foundation, either version 3 of the 7 | // License, or (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU Affero General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU Affero General Public License 15 | // along with this program. If not, see . 16 | 17 | <#@ output extension=".cs" #> 18 | <#@ template debug="true" hostSpecific="true" #> 19 | <#@ import namespace="System.IO" #> 20 | <#@ import namespace="System.Text" #> 21 | <#@ import namespace="System.Collections.Generic" #> 22 | <#= "// *** DO NOT EDIT THIS FILE, IT HAS BEEN AUTO-GENERATED ***" #> 23 | 24 | namespace TS3Client.Messages 25 | { 26 | using System; 27 | using Commands; 28 | using ClientUidT = System.String; 29 | using ClientDbIdT = System.UInt64; 30 | using ClientIdT = System.UInt16; 31 | using ChannelIdT = System.UInt64; 32 | using ServerGroupIdT = System.UInt64; 33 | using ChannelGroupIdT = System.UInt64; 34 | using PermissionIdT = System.Int32; 35 | 36 | <# 37 | string declFilePath = Host.ResolvePath("MessageDeclarations.txt"); 38 | string[] declLines = File.ReadAllLines(declFilePath); 39 | 40 | var fldDict = new Dictionary(); 41 | var msgDict = new Dictionary(); 42 | var ntfyDict = new Dictionary(); 43 | var convDict = new Dictionary(); 44 | 45 | foreach(var line in declLines) 46 | { 47 | if(string.IsNullOrWhiteSpace(line)) 48 | continue; 49 | 50 | var parts = line.Split(new [] {':'}, 2); 51 | if(parts.Length < 2 || string.IsNullOrWhiteSpace(parts[0])) 52 | continue; 53 | 54 | parts[0] = parts[0].Trim().ToUpper(); 55 | if(parts[0] == "MSG") 56 | { 57 | var param = parts[1].Replace(" ", "").Split(','); 58 | if(param.Length < 2) { this.Write("#warning Invalid MSG: " + line); continue; } 59 | msgDict.Add(param[0], new GenMsg { className=param[0], ntfyName=param[1] } ); 60 | 61 | bool isNotify = !string.IsNullOrEmpty(param[1]); 62 | GenNotify genNotify = null; 63 | if(isNotify) 64 | { 65 | genNotify = ntfyDict[param[1]]; 66 | genNotify.assocMsg = msgDict[param[0]]; 67 | } 68 | #> 69 | public sealed class <#= param[0] #> : <#= isNotify ? "INotification" : "IResponse" #> 70 | { 71 | public <#= isNotify ? "NotificationType NotifyType { get; } = NotificationType." + genNotify.enumName + ";" : "string ReturnCode { get; set; }" #> 72 | <# 73 | for(int i = 2; i < param.Length; i++) 74 | { 75 | GenField genField; 76 | if(!fldDict.TryGetValue(param[i], out genField)) { this.Write(Environment.NewLine + "#warning Missing Field: " + param[i]); continue; } 77 | #> 78 | public <#= genField.fldType #> <#= genField.fldName #> { get; set; }<# 79 | } 80 | #> 81 | 82 | public void SetField(string name, string value) 83 | { 84 | <# 85 | if (param.Length > 2) {#> 86 | switch(name) 87 | { 88 | <# 89 | for(int i = 2; i < param.Length; i++) 90 | { 91 | GenField genField; 92 | if(!fldDict.TryGetValue(param[i], out genField)) { this.Write(Environment.NewLine + "#warning Missing Field: " + param[i]); continue; } 93 | #> 94 | case "<#= genField.tsName #>": <#= genField.fldName #> = <#= convDict[genField.fldType] #> break;<# 95 | } 96 | #> 97 | <#= isNotify ? "" : ("case \"return_code\": ReturnCode = " + convDict["string"] + " break;") #> 98 | } 99 | <# 100 | }#> 101 | } 102 | } 103 | <# 104 | } 105 | else if(parts[0] == "FIELD") 106 | { 107 | var param = parts[1].Replace(" ", "").Split(','); 108 | if(param.Length < 4) { this.Write("#warning Invalid FIELD: " + line); continue; } 109 | fldDict.Add(param[0], new GenField { tsName=param[1], fldName=param[2], fldType=param[3] } ); 110 | } 111 | else if(parts[0] == "NOTIFY") 112 | { 113 | var param = parts[1].Replace(" ", "").Split(','); 114 | if(param.Length < 2) { this.Write("#warning Invalid NOTIFY: " + line); continue; } 115 | ntfyDict.Add(param[0], new GenNotify { enumName=param[1] } ); 116 | } 117 | else if(parts[0] == "CONV") 118 | { 119 | var param = parts[1].Replace(" ", "").Split(new[] { ',' }, 2); 120 | if(param.Length < 2) { this.Write("#warning Invalid CONV: " + line); continue; } 121 | convDict.Add(param[0], param[1] ); 122 | } 123 | else if(parts[0] == "BREAK") 124 | { 125 | break; 126 | } 127 | } 128 | #> 129 | public static class MessageHelper 130 | { 131 | public static NotificationType GetNotificationType(string name) 132 | { 133 | switch(name) 134 | { 135 | <# 136 | foreach(var kvp in ntfyDict) 137 | { 138 | #> 139 | case "<#= kvp.Key #>": return NotificationType.<#= kvp.Value.enumName #>;<# 140 | } 141 | #> 142 | default: return NotificationType.Unknown; 143 | } 144 | } 145 | 146 | public static INotification GenerateNotificationType(NotificationType name) 147 | { 148 | switch(name) 149 | { 150 | <# 151 | foreach(var kvp in ntfyDict) 152 | { 153 | #> 154 | <#= kvp.Value.assocMsg == null ? "#warning " : "" #>case NotificationType.<#= kvp.Value.enumName #>: return new <#= kvp.Value.assocMsg?.className ?? "" #>();<# 155 | } 156 | #> 157 | case NotificationType.Unknown: 158 | default: throw new ArgumentOutOfRangeException(nameof(name)); 159 | } 160 | } 161 | } 162 | } 163 | 164 | <#+ class GenField 165 | { 166 | public string tsName; 167 | public string fldName; 168 | public string fldType; 169 | } 170 | class GenMsg 171 | { 172 | public string className; 173 | public string ntfyName; 174 | } 175 | class GenNotify 176 | { 177 | public string enumName; 178 | public GenMsg assocMsg; 179 | } 180 | #> -------------------------------------------------------------------------------- /TS3Client/Messages/ResponseDictionary.cs: -------------------------------------------------------------------------------- 1 | // TS3AudioBot - An advanced Musicbot for Teamspeak 3 2 | // Copyright (C) 2016 TS3AudioBot contributors 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU Affero General Public License as 6 | // published by the Free Software Foundation, either version 3 of the 7 | // License, or (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU Affero General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU Affero General Public License 15 | // along with this program. If not, see . 16 | 17 | namespace TS3Client.Messages 18 | { 19 | using System; 20 | using System.Collections; 21 | using System.Collections.Generic; 22 | using KeyType = System.String; 23 | using ValueType = System.String; 24 | 25 | public class ResponseDictionary : IDictionary, IResponse 26 | { 27 | private readonly IDictionary data; 28 | 29 | public ResponseDictionary() { data = new Dictionary(); } 30 | public ResponseDictionary(IDictionary dataDict) { data = dataDict; } 31 | 32 | public ValueType this[KeyType key] { get { return data[key]; } set { throw new NotSupportedException(); } } 33 | public int Count => data.Count; 34 | public bool IsReadOnly => true; 35 | public ICollection Keys => data.Keys; 36 | public ICollection Values => data.Values; 37 | public void Add(KeyValuePair item) { throw new NotSupportedException(); } 38 | public void Add(KeyType key, ValueType value) { throw new NotSupportedException(); } 39 | public void Clear() { throw new NotSupportedException(); } 40 | public bool Contains(KeyValuePair item) => data.Contains(item); 41 | public bool ContainsKey(string key) => data.ContainsKey(key); 42 | public void CopyTo(KeyValuePair[] array, int arrayIndex) => data.CopyTo(array, arrayIndex); 43 | public IEnumerator> GetEnumerator() => data.GetEnumerator(); 44 | public bool Remove(KeyValuePair item) { throw new NotSupportedException(); } 45 | public bool Remove(KeyType key) { throw new NotSupportedException(); } 46 | public bool TryGetValue(KeyType key, out ValueType value) => data.TryGetValue(key, out value); 47 | IEnumerator IEnumerable.GetEnumerator() => data.GetEnumerator(); 48 | 49 | public void SetField(string name, string value) => data[name] = value; 50 | public string ReturnCode 51 | { 52 | get { return data.ContainsKey("return_code") ? data["return_code"] : string.Empty; } 53 | set { data["return_code"] = value; } 54 | } 55 | } 56 | 57 | public sealed class ResponseVoid : IResponse 58 | { 59 | public string ReturnCode { get; set; } 60 | public void SetField(string name, string value) { } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /TS3Client/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Teamspeak 3 Client")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Teamspeak Systems GmbH")] 12 | [assembly: AssemblyProduct("Teamspeak 3 Client")] 13 | [assembly: AssemblyCopyright("Copyright Teamspeak Systems GmbH © 2000")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | //[assembly: Guid("0eb99e9d-87e5-4534-a100-55d231c2b6a6")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("3.1.4")] 36 | [assembly: AssemblyFileVersion("3.1.4")] 37 | -------------------------------------------------------------------------------- /TS3Client/Query/Ts3QueryClient.cs: -------------------------------------------------------------------------------- 1 | // TS3AudioBot - An advanced Musicbot for Teamspeak 3 2 | // Copyright (C) 2016 TS3AudioBot contributors 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU Affero General Public License as 6 | // published by the Free Software Foundation, either version 3 of the 7 | // License, or (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU Affero General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU Affero General Public License 15 | // along with this program. If not, see . 16 | 17 | namespace TS3Client.Query 18 | { 19 | using Commands; 20 | using Messages; 21 | using System; 22 | using System.Linq; 23 | using System.Collections.Generic; 24 | using System.IO; 25 | using System.Net.Sockets; 26 | 27 | public sealed class Ts3QueryClient : Ts3BaseFunctions 28 | { 29 | private readonly object SendQueueLock = new object(); 30 | private readonly TcpClient tcpClient; 31 | private NetworkStream tcpStream; 32 | private StreamReader tcpReader; 33 | private StreamWriter tcpWriter; 34 | private readonly MessageProcessor msgProc; 35 | private readonly IEventDispatcher dispatcher; 36 | 37 | public override ClientType ClientType => ClientType.Query; 38 | public override bool Connected => tcpClient.Connected; 39 | 40 | public override event NotifyEventHandler OnTextMessageReceived; 41 | public override event NotifyEventHandler OnClientEnterView; 42 | public override event NotifyEventHandler OnClientLeftView; 43 | public override event EventHandler OnConnected; 44 | public override event EventHandler OnDisconnected; 45 | 46 | public Ts3QueryClient(EventDispatchType dispatcherType) 47 | { 48 | tcpClient = new TcpClient(); 49 | msgProc = new MessageProcessor(true); 50 | dispatcher = EventDispatcherHelper.Create(dispatcherType); 51 | } 52 | 53 | public override void Connect(ConnectionData conData) 54 | { 55 | try { tcpClient.Connect(conData.Hostname, conData.Port); } 56 | catch (SocketException ex) { throw new Ts3Exception("Could not connect.", ex); } 57 | 58 | tcpStream = tcpClient.GetStream(); 59 | tcpReader = new StreamReader(tcpStream, Util.Encoder); 60 | tcpWriter = new StreamWriter(tcpStream, Util.Encoder) { NewLine = "\n" }; 61 | 62 | for (int i = 0; i < 3; i++) 63 | tcpReader.ReadLine(); 64 | 65 | dispatcher.Init(NetworkLoop, InvokeEvent); 66 | OnConnected?.Invoke(this, new EventArgs()); 67 | } 68 | 69 | public override void Disconnect() 70 | { 71 | lock (SendQueueLock) 72 | { 73 | SendRaw("quit"); 74 | if (tcpClient.Connected) 75 | ((IDisposable)tcpClient)?.Dispose(); 76 | } 77 | } 78 | 79 | private void NetworkLoop() 80 | { 81 | while (true) 82 | { 83 | string line; 84 | try { line = tcpReader.ReadLine(); } 85 | catch (IOException) { line = null; } 86 | if (line == null) break; 87 | if (string.IsNullOrWhiteSpace(line)) continue; 88 | 89 | var message = line.Trim(); 90 | msgProc.PushMessage(message); 91 | } 92 | OnDisconnected?.Invoke(this, new DisconnectEventArgs(MoveReason.LeftServer)); // TODO ?? 93 | } 94 | 95 | private void InvokeEvent(LazyNotification lazyNotification) 96 | { 97 | var notification = lazyNotification.Notifications; 98 | switch (lazyNotification.NotifyType) 99 | { 100 | case NotificationType.ChannelCreated: break; 101 | case NotificationType.ChannelDeleted: break; 102 | case NotificationType.ChannelChanged: break; 103 | case NotificationType.ChannelEdited: break; 104 | case NotificationType.ChannelMoved: break; 105 | case NotificationType.ChannelPasswordChanged: break; 106 | case NotificationType.ClientEnterView: OnClientEnterView?.Invoke(this, notification.Cast()); break; 107 | case NotificationType.ClientLeftView: OnClientLeftView?.Invoke(this, notification.Cast()); break; 108 | case NotificationType.ClientMoved: break; 109 | case NotificationType.ServerEdited: break; 110 | case NotificationType.TextMessage: OnTextMessageReceived?.Invoke(this, notification.Cast()); break; 111 | case NotificationType.TokenUsed: break; 112 | // special 113 | case NotificationType.Error: break; 114 | case NotificationType.Unknown: 115 | default: throw new InvalidOperationException(); 116 | } 117 | } 118 | 119 | protected override IEnumerable SendCommand(Ts3Command com) // Synchronous 120 | { 121 | using (var wb = new WaitBlock()) 122 | { 123 | lock (SendQueueLock) 124 | { 125 | msgProc.EnqueueRequest(wb); 126 | SendRaw(com.ToString()); 127 | } 128 | 129 | return wb.WaitForMessage(); 130 | } 131 | } 132 | 133 | private void SendRaw(string data) 134 | { 135 | if (!tcpClient.Connected) 136 | return; 137 | tcpWriter.WriteLine(data); 138 | tcpWriter.Flush(); 139 | } 140 | 141 | #region QUERY SPECIFIC COMMANDS 142 | 143 | private static readonly string[] targetTypeString = new[] { "textprivate", "textchannel", "textserver", "channel", "server" }; 144 | 145 | public void RegisterNotification(MessageTarget target, int channel) => RegisterNotification(targetTypeString[(int)target], channel); 146 | public void RegisterNotification(RequestTarget target, int channel) => RegisterNotification(targetTypeString[(int)target], channel); 147 | private void RegisterNotification(string target, int channel) 148 | { 149 | var ev = new CommandParameter("event", target.ToLowerInvariant()); 150 | if (target == "channel") 151 | Send("servernotifyregister", ev, new CommandParameter("id", channel)); 152 | else 153 | Send("servernotifyregister", ev); 154 | } 155 | 156 | public void Login(string username, string password) 157 | => Send("login", 158 | new CommandParameter("client_login_name", username), 159 | new CommandParameter("client_login_password", password)); 160 | public void UseServer(int svrId) 161 | => Send("use", 162 | new CommandParameter("sid", svrId)); 163 | 164 | #endregion 165 | 166 | public override void Dispose() 167 | { 168 | lock (SendQueueLock) 169 | { 170 | tcpWriter?.Dispose(); 171 | tcpWriter = null; 172 | 173 | tcpReader?.Dispose(); 174 | tcpReader = null; 175 | 176 | msgProc.DropQueue(); 177 | dispatcher.Dispose(); 178 | } 179 | } 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /TS3Client/TS3Client.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {0EB99E9D-87E5-4534-A100-55D231C2B6A6} 8 | Library 9 | Properties 10 | TS3Client 11 | TS3Client 12 | v4.5 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | false 25 | 6 26 | false 27 | Auto 28 | 29 | 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | 6 37 | 38 | 39 | 40 | 41 | 42 | 43 | ..\packages\BouncyCastle.1.8.1\lib\BouncyCastle.Crypto.dll 44 | True 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | True 71 | True 72 | MessageTemplates.tt 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | TextTemplatingFileGenerator 97 | MessageTemplates.cs 98 | 99 | 100 | 101 | 102 | 103 | 104 | 111 | -------------------------------------------------------------------------------- /TS3Client/Ts3BaseClient.cs: -------------------------------------------------------------------------------- 1 | namespace TS3Client 2 | { 3 | using Commands; 4 | using Messages; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Diagnostics; 8 | using System.Linq; 9 | 10 | public delegate void NotifyEventHandler(object sender, IEnumerable e) where TEventArgs : INotification; 11 | 12 | public abstract class Ts3BaseFunctions : IDisposable 13 | { 14 | public abstract event NotifyEventHandler OnTextMessageReceived; 15 | public abstract event NotifyEventHandler OnClientEnterView; 16 | public abstract event NotifyEventHandler OnClientLeftView; 17 | public abstract event EventHandler OnConnected; 18 | public abstract event EventHandler OnDisconnected; 19 | 20 | public abstract bool Connected { get; } 21 | public abstract ClientType ClientType { get; } 22 | 23 | public abstract void Connect(ConnectionData conData); 24 | public abstract void Disconnect(); 25 | public abstract void Dispose(); 26 | 27 | #region NETWORK SEND 28 | 29 | [DebuggerStepThrough] 30 | public IEnumerable Send(string command) 31 | => SendCommand(new Ts3Command(command)); 32 | 33 | [DebuggerStepThrough] 34 | public IEnumerable Send(string command, params CommandParameter[] parameter) 35 | => SendCommand(new Ts3Command(command, parameter.ToList())); 36 | 37 | [DebuggerStepThrough] 38 | public IEnumerable Send(string command, CommandParameter[] parameter, params CommandOption[] options) 39 | => SendCommand(new Ts3Command(command, parameter.ToList(), options.ToList())); 40 | 41 | [DebuggerStepThrough] 42 | public IEnumerable Send(string command) where T : IResponse, new() 43 | => SendCommand(new Ts3Command(command)); 44 | 45 | [DebuggerStepThrough] 46 | public IEnumerable Send(string command, params CommandParameter[] parameter) where T : IResponse, new() 47 | => Send(command, parameter.ToList()); 48 | 49 | [DebuggerStepThrough] 50 | public IEnumerable Send(string command, List parameter) where T : IResponse, new() 51 | => SendCommand(new Ts3Command(command, parameter)); 52 | 53 | [DebuggerStepThrough] 54 | public IEnumerable Send(string command, CommandParameter[] parameter, params CommandOption[] options) where T : IResponse, new() 55 | => SendCommand(new Ts3Command(command, parameter.ToList(), options.ToList())); 56 | 57 | [DebuggerStepThrough] 58 | public IEnumerable Send(string command, List parameter, params CommandOption[] options) where T : IResponse, new() 59 | => SendCommand(new Ts3Command(command, parameter.ToList(), options.ToList())); 60 | 61 | [DebuggerStepThrough] 62 | protected void SendNoResponsed(Ts3Command command) 63 | { 64 | command.ExpectResponse = false; 65 | SendCommand(command); 66 | } 67 | 68 | protected abstract IEnumerable SendCommand(Ts3Command com) where T : IResponse, new(); 69 | 70 | #endregion 71 | 72 | #region UNIVERSAL COMMANDS 73 | 74 | public void ChangeName(string newName) 75 | => Send("clientupdate", 76 | new CommandParameter("client_nickname", newName)); 77 | public void ChangeDescription(string newDescription, ClientData client) 78 | => Send("clientdbedit", 79 | new CommandParameter("cldbid", client.DatabaseId), 80 | new CommandParameter("client_description", newDescription)); 81 | public WhoAmI WhoAmI() // Q ? 82 | => Send("whoami").FirstOrDefault(); 83 | public void SendMessage(string message, ClientData client) 84 | => SendMessage(MessageTarget.Private, client.ClientId, message); 85 | public void SendMessage(string message, ChannelData channel) 86 | => SendMessage(MessageTarget.Channel, (ulong)channel.Id, message); 87 | public void SendMessage(string message, ServerData server) 88 | => SendMessage(MessageTarget.Server, server.VirtualServerId, message); 89 | public void SendMessage(MessageTarget target, ulong id, string message) 90 | => Send("sendtextmessage", 91 | new CommandParameter("targetmode", (ulong)target), 92 | new CommandParameter("target", id), 93 | new CommandParameter("msg", message)); 94 | public void SendGlobalMessage(string message) 95 | => Send("gm", 96 | new CommandParameter("msg", message)); 97 | public void KickClientFromServer(ushort[] clientIds) 98 | => KickClient(clientIds, RequestTarget.Server); 99 | public void KickClientFromChannel(ushort[] clientIds) 100 | => KickClient(clientIds, RequestTarget.Channel); 101 | public void KickClient(ushort[] clientIds, RequestTarget target) 102 | => Send("clientkick", 103 | new CommandParameter("reasonid", (int)target), 104 | CommandBinder.NewBind("clid", clientIds)); 105 | public IEnumerable ClientList() 106 | => ClientList(0); 107 | public IEnumerable ClientList(ClientListOptions options) => Send("clientlist", 108 | Ts3Command.NoParameter, options); 109 | public IEnumerable ServerGroupsOfClientDbId(ClientData client) 110 | => ServerGroupsOfClientDbId(client.DatabaseId); 111 | public IEnumerable ServerGroupsOfClientDbId(ulong clDbId) 112 | => Send("servergroupsbyclientid", new CommandParameter("cldbid", clDbId)); 113 | public ClientDbData ClientDbInfo(ClientData client) 114 | => ClientDbInfo(client.DatabaseId); 115 | public ClientDbData ClientDbInfo(ulong clDbId) 116 | => Send("clientdbinfo", new CommandParameter("cldbid", clDbId)).FirstOrDefault(); 117 | public ClientInfo ClientInfo(ushort clientId) 118 | => Send("clientinfo", new CommandParameter("clid", clientId)).FirstOrDefault(); 119 | 120 | #endregion 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /TS3Client/Ts3Exceptions.cs: -------------------------------------------------------------------------------- 1 | // TS3AudioBot - An advanced Musicbot for Teamspeak 3 2 | // Copyright (C) 2016 TS3AudioBot contributors 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU Affero General Public License as 6 | // published by the Free Software Foundation, either version 3 of the 7 | // License, or (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU Affero General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU Affero General Public License 15 | // along with this program. If not, see . 16 | 17 | namespace TS3Client 18 | { 19 | using Messages; 20 | using System; 21 | 22 | public class Ts3Exception : Exception 23 | { 24 | public Ts3Exception(string message) : base(message) { } 25 | public Ts3Exception(string message, Exception innerException) : base(message, innerException) { } 26 | } 27 | 28 | public class Ts3CommandException : Ts3Exception 29 | { 30 | public CommandError ErrorStatus { get; private set; } 31 | 32 | internal Ts3CommandException(CommandError message) : base(message.ErrorFormat()) { ErrorStatus = message; } 33 | internal Ts3CommandException(CommandError message, Exception inner) : base(message.ErrorFormat(), inner) { ErrorStatus = message; } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /TS3Client/Util.cs: -------------------------------------------------------------------------------- 1 | // TS3AudioBot - An advanced Musicbot for Teamspeak 3 2 | // Copyright (C) 2016 TS3AudioBot contributors 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU Affero General Public License as 6 | // published by the Free Software Foundation, either version 3 of the 7 | // License, or (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU Affero General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU Affero General Public License 15 | // along with this program. If not, see . 16 | 17 | namespace TS3Client 18 | { 19 | using System.Collections.Generic; 20 | using System.Linq; 21 | using System.Text; 22 | using System; 23 | using Messages; 24 | 25 | internal static class Util 26 | { 27 | public static IEnumerable Slice(this IList arr, int from) => Slice(arr, from, arr.Count - from); 28 | public static IEnumerable Slice(this IEnumerable arr, int from, int len) => arr.Skip(from).Take(len); 29 | 30 | public static IEnumerable GetFlags(this Enum input) => Enum.GetValues(input.GetType()).Cast().Where(enu => input.HasFlag(enu)); 31 | 32 | public static void Init(ref T fld) where T : new() => fld = new T(); 33 | 34 | public static Encoding Encoder { get; } = new UTF8Encoding(false); 35 | 36 | public static readonly DateTime UnixTimeStart = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); 37 | 38 | public static uint UnixNow => (uint)(DateTime.UtcNow - UnixTimeStart).TotalSeconds; 39 | 40 | public static Random Random { get; } = new Random(); 41 | 42 | public static DateTime Now => DateTime.UtcNow; 43 | 44 | public static TimeSpan Min(TimeSpan a, TimeSpan b) => a < b ? a : b; 45 | } 46 | 47 | public static class Extensions 48 | { 49 | public static string ErrorFormat(this CommandError error) 50 | { 51 | if (error.MissingPermissionId > PermissionId.unknown) 52 | return $"{error.Id}: the command failed to execute: {error.Message} (missing permission:{error.MissingPermissionId})"; 53 | else 54 | return $"{error.Id}: the command failed to execute: {error.Message}"; 55 | } 56 | } 57 | 58 | internal static class DebugUtil 59 | { 60 | public static string DebugToHex(byte[] data) => string.Join(" ", data.Select(x => x.ToString("X2"))); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /TS3Client/WaitBlock.cs: -------------------------------------------------------------------------------- 1 | // TS3AudioBot - An advanced Musicbot for Teamspeak 3 2 | // Copyright (C) 2016 TS3AudioBot contributors 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU Affero General Public License as 6 | // published by the Free Software Foundation, either version 3 of the 7 | // License, or (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU Affero General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU Affero General Public License 15 | // along with this program. If not, see . 16 | 17 | namespace TS3Client 18 | { 19 | using Commands; 20 | using Messages; 21 | using System; 22 | using System.Collections.Generic; 23 | using System.Threading; 24 | 25 | internal class WaitBlock : IDisposable 26 | { 27 | private AutoResetEvent waiter = new AutoResetEvent(false); 28 | private CommandError commandError = null; 29 | private string commandLine = null; 30 | 31 | public WaitBlock() { } 32 | 33 | public IEnumerable WaitForMessage() where T : IResponse, new() 34 | { 35 | waiter.WaitOne(); 36 | if (commandError.Id != Ts3ErrorCode.ok) 37 | throw new Ts3CommandException(commandError); 38 | 39 | return CommandDeserializer.GenerateResponse(commandLine); 40 | } 41 | 42 | public void SetAnswer(CommandError commandError, string commandLine = null) 43 | { 44 | if (commandError == null) 45 | throw new ArgumentNullException(nameof(commandError)); 46 | this.commandError = commandError; 47 | this.commandLine = commandLine; 48 | waiter.Set(); 49 | } 50 | 51 | public void Dispose() 52 | { 53 | if (waiter != null) 54 | { 55 | waiter.Set(); 56 | waiter.Dispose(); 57 | waiter = null; 58 | } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /TS3Client/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /TS3Client/ts3protocol.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | [==============================================================================] 4 | TS3 PROTOCOL PAPER 5 | [==============================================================================] 6 | 7 | 1. The (Low-Level) Initiation/Handshake 8 | 9 | A connection is started from the client by sending the first handshake 10 | packet. The handshake process consists of 5 different init packets. This 11 | includes the so called RSA puzzle to prevent DOS attacks. 12 | 13 | Packet 0 (Client -> Server) 14 | 04 bytes : Version of the Teamspeak client as timestamp 15 | Example: { 0x06, 0x3b, 0xec, 0xe9 } 16 | 01 bytes : Init-packet step number 17 | Fixed: 0x00 18 | 08 bytes : Zeros, reserverd. 19 | 04 bytes : Current timespamp in unix format 20 | 04 bytes : Random bytes := [A0] 21 | 22 | Packet 1 (Client <- Server) 23 | 01 bytes : Init-packet step number 24 | Fixed: 0x01 25 | 16 bytes : Server stuff := [A1] 26 | 04 bytes : The bytes from [A0] in reversed order 27 | 28 | Packet 2 (Client -> Server) 29 | 04 bytes : Version of the Teamspeak client as timestamp 30 | 01 bytes : Init-packet step number 31 | Fixed: 0x02 32 | 16 bytes : The bytes from [A1] 33 | 04 bytes : The bytes from [A0] in reversed order 34 | 35 | Packet 3 (Client <- Server) 36 | 01 bytes : Init-packet step number 37 | Fixed: 0x03 38 | 64 bytes : 'x', an unsigned biginteger 39 | 64 bytes : 'n', an unsigned biginteger 40 | 04 bytes : 'level' an int4 parsed with network to host endianness 41 | 100 bytes : Server stuff := [A2] 42 | 43 | Packet 4 (Client -> Server) 44 | 01 bytes : Init-packet step number 45 | Fixed: 0x03 46 | 64 bytes : the received 'x' 47 | 64 bytes : the received 'n' 48 | 04 bytes : the recoived 'level' 49 | 100 bytes : The bytes from [A2] 50 | 64 bytes : 'y' which is the result of x ^ (2 ^ level) % n as an unsigned 51 | biginteger. Padded from the lower side with '0x00' when shorter 52 | than 64 bytes. 53 | Example: { 0x00, 0x00, data ... data} 54 | var bytes : The clientinitiv command as explained in (* TODO *) 55 | 56 | 2. The (High-Level) Initiation/Handshake 57 | 58 | In this phase the client and server exchange basic information and 59 | agree/calculate the symmetric AES encryption key with the ECDH 60 | public/private key exchange technique. 61 | 62 | Both the client and the server will need a EC public/private key. This key 63 | is also the identity which the server uses to recognize a user again. 64 | The curve used is 'prime256v1'. 65 | 66 | 3. Low-Level Commands 67 | 68 | 4. High-Level Commands -------------------------------------------------------------------------------- /TS3ClientGUI/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 127.0.0.1 15 | 16 | 17 | 9987 18 | 19 | 20 | SlimTeamspeakUser 21 | 22 | 23 | 123 24 | 25 | 26 | False 27 | 28 | 29 | False 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /TS3ClientGUI/Client.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using TS3Client; 7 | using TS3Client.Commands; 8 | using TS3Client.Full; 9 | using TS3Client.Messages; 10 | using TS3Client.Query; 11 | using System.Windows.Forms; 12 | 13 | namespace TS3ClientGUI 14 | { 15 | class Client 16 | { 17 | public static Client TS3Client = new Client(); 18 | 19 | ConnectionDataFull con; 20 | public Ts3FullClient client; 21 | MainWindow mainwindow; 22 | 23 | public Client() 24 | { 25 | client = new Ts3FullClient(EventDispatchType.AutoThreadPooled); 26 | client.QuitMessage = "Teamspeak 3 Slim"; 27 | client.OnConnected += Client_OnConnected; 28 | client.OnDisconnected += Client_OnDisconnected; 29 | client.OnErrorEvent += Client_OnErrorEvent; 30 | client.OnTextMessageReceived += Client_OnTextMessageReceived; 31 | client.OnClientEnterView += Client_OnClientEnterView; 32 | client.OnClientLeftView += Client_OnClientLeftView; 33 | } 34 | 35 | public event EventHandler OnClientConnect; 36 | 37 | public void Connect(MainWindow sender) 38 | { 39 | mainwindow = sender; 40 | con = new ConnectionDataFull() { 41 | Hostname = Properties.Settings.Default.ip, 42 | Port = Properties.Settings.Default.port, 43 | Username = Properties.Settings.Default.nickname, 44 | Identity = Ts3Crypt.GenerateNewIdentity(8), 45 | Password = Properties.Settings.Default.password 46 | }; 47 | client.Connect(con); 48 | } 49 | 50 | delegate void SetTextCallback(string text, int index, string author = null); 51 | delegate void AddTabCallback(string title); 52 | 53 | private void addChatTab(string title) 54 | { 55 | if (title == "") return; 56 | if (mainwindow.chatTabWidget.InvokeRequired) 57 | { 58 | AddTabCallback d = new AddTabCallback(addChatTab); 59 | mainwindow.chatTabWidget.Invoke(d, new object[] { title }); 60 | } 61 | else 62 | { 63 | TabControl.TabPageCollection pages = mainwindow.chatTabWidget.TabPages; 64 | foreach (TabPage page in pages) 65 | if (page.Text == title) return; 66 | mainwindow.chatTabWidget.TabPages.Add(title); 67 | } 68 | } 69 | 70 | private void ChatAppend(string text, int index, string author = null) 71 | { 72 | // InvokeRequired required compares the thread ID of the 73 | // calling thread to the thread ID of the creating thread. 74 | // If these threads are different, it returns true. 75 | RichTextBox tab; 76 | switch (index) 77 | { 78 | case 1: 79 | tab = mainwindow.chatServerTab; 80 | break; 81 | case 2: 82 | tab = mainwindow.chatChannelTab; 83 | break; 84 | case 0: 85 | addChatTab(author); 86 | for (int a = 0; a <= mainwindow.chatTabWidget.TabCount; a = a + 1) 87 | { 88 | // mainwindow.chatTabWidget. 89 | } 90 | tab = mainwindow.chatServerTab; 91 | break; 92 | } 93 | if (mainwindow.chatServerTab.InvokeRequired) 94 | { 95 | SetTextCallback d = new SetTextCallback(ChatAppend); 96 | mainwindow.chatServerTab.Invoke(d, new object[] { text, index, author }); 97 | } 98 | else 99 | { 100 | string str = "[" + DateTime.Now.ToString() + "] " + text + "\n"; 101 | mainwindow.chatServerTab.AppendText(str); 102 | if (Properties.Settings.Default.debug) 103 | Console.WriteLine(str); 104 | } 105 | } 106 | 107 | public void SendMessage(string message) 108 | { 109 | MessageTarget target; 110 | switch (mainwindow.chatTabWidget.SelectedIndex) 111 | { 112 | case 1: 113 | target = MessageTarget.Server; break; 114 | case 2: 115 | target = MessageTarget.Channel; break; 116 | default: 117 | target = MessageTarget.Private; break; 118 | } 119 | } 120 | 121 | private void Client_OnConnected(object sender, EventArgs e) 122 | { 123 | //var client = (Ts3FullClient)sender; 124 | //var data = client.ClientInfo(client.ClientId); 125 | ChatAppend("Connected to "+Properties.Settings.Default.ip+":"+Properties.Settings.Default.port, 0); 126 | } 127 | 128 | private void Client_OnDisconnected(object sender, DisconnectEventArgs e) 129 | { 130 | ChatAppend("Disconnected from " + Properties.Settings.Default.ip + ":" + Properties.Settings.Default.port, 0); 131 | } 132 | 133 | private void Client_OnClientEnterView(object sender, IEnumerable eventArgs) 134 | { 135 | foreach (var user in eventArgs) 136 | { 137 | if (user.CountryCode != "") 138 | { 139 | ChatAppend("\"" + user.NickName + "\" #"+user.ClientId+" connected from " + user.CountryCode + ".", 1); 140 | } 141 | else 142 | { 143 | ChatAppend("\"" + user.NickName + "\" #" + user.ClientId + " connected.", 1); 144 | } 145 | } 146 | } 147 | 148 | private void Client_OnClientLeftView(object sender, IEnumerable eventArgs) 149 | { 150 | foreach (var user in eventArgs) 151 | { 152 | ChatAppend("#" + user.ClientId + " disconnected.", 1); 153 | } 154 | } 155 | 156 | private void Client_OnTextMessageReceived(object sender, IEnumerable e) 157 | { 158 | foreach (var msg in e) 159 | { 160 | var source = (Ts3FullClient)sender; 161 | ChatAppend(msg.InvokerName + ": " + msg.Message, 0, msg.InvokerName); 162 | if (msg.Message.StartsWith("!nick ")) 163 | client.ChangeName(msg.Message.Replace("!nick ", "")); 164 | } 165 | } 166 | 167 | private void Client_OnErrorEvent(object sender, CommandError e) 168 | { 169 | var client = (Ts3FullClient)sender; 170 | Console.WriteLine(e.ErrorFormat()); 171 | if (!client.Connected) 172 | { 173 | client.Connect(con); 174 | } 175 | } 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /TS3ClientGUI/MainWindow.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace TS3ClientGUI 2 | { 3 | partial class MainWindow 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(MainWindow)); 32 | this.lbl_ip = new System.Windows.Forms.Label(); 33 | this.ip = new System.Windows.Forms.TextBox(); 34 | this.lbl_port = new System.Windows.Forms.Label(); 35 | this.port = new System.Windows.Forms.TextBox(); 36 | this.lbl_nickname = new System.Windows.Forms.Label(); 37 | this.nickname = new System.Windows.Forms.TextBox(); 38 | this.lbl_password = new System.Windows.Forms.Label(); 39 | this.password = new System.Windows.Forms.TextBox(); 40 | this.btn_connect = new System.Windows.Forms.Button(); 41 | this.chk_autoconnect = new System.Windows.Forms.CheckBox(); 42 | this.TreeView = new System.Windows.Forms.ListBox(); 43 | this.chatServerTab = new System.Windows.Forms.RichTextBox(); 44 | this.infoData = new System.Windows.Forms.RichTextBox(); 45 | this.btn_send = new System.Windows.Forms.Button(); 46 | this.txt_message = new System.Windows.Forms.TextBox(); 47 | this.btn_disconnect = new System.Windows.Forms.Button(); 48 | this.chatTabWidget = new System.Windows.Forms.TabControl(); 49 | this.tabPage1 = new System.Windows.Forms.TabPage(); 50 | this.tabPage2 = new System.Windows.Forms.TabPage(); 51 | this.chatChannelTab = new System.Windows.Forms.RichTextBox(); 52 | this.chatTabWidget.SuspendLayout(); 53 | this.tabPage1.SuspendLayout(); 54 | this.tabPage2.SuspendLayout(); 55 | this.SuspendLayout(); 56 | // 57 | // lbl_ip 58 | // 59 | this.lbl_ip.AutoSize = true; 60 | this.lbl_ip.Location = new System.Drawing.Point(13, 13); 61 | this.lbl_ip.Name = "lbl_ip"; 62 | this.lbl_ip.Size = new System.Drawing.Size(20, 13); 63 | this.lbl_ip.TabIndex = 0; 64 | this.lbl_ip.Text = "IP:"; 65 | // 66 | // ip 67 | // 68 | this.ip.Location = new System.Drawing.Point(54, 10); 69 | this.ip.Name = "ip"; 70 | this.ip.Size = new System.Drawing.Size(100, 20); 71 | this.ip.TabIndex = 1; 72 | this.ip.Text = "127.0.0.1"; 73 | // 74 | // lbl_port 75 | // 76 | this.lbl_port.AutoSize = true; 77 | this.lbl_port.Location = new System.Drawing.Point(161, 13); 78 | this.lbl_port.Name = "lbl_port"; 79 | this.lbl_port.Size = new System.Drawing.Size(29, 13); 80 | this.lbl_port.TabIndex = 2; 81 | this.lbl_port.Text = "Port:"; 82 | // 83 | // port 84 | // 85 | this.port.Location = new System.Drawing.Point(202, 10); 86 | this.port.Name = "port"; 87 | this.port.Size = new System.Drawing.Size(41, 20); 88 | this.port.TabIndex = 3; 89 | this.port.Text = "9987"; 90 | // 91 | // lbl_nickname 92 | // 93 | this.lbl_nickname.AutoSize = true; 94 | this.lbl_nickname.Location = new System.Drawing.Point(249, 13); 95 | this.lbl_nickname.Name = "lbl_nickname"; 96 | this.lbl_nickname.Size = new System.Drawing.Size(58, 13); 97 | this.lbl_nickname.TabIndex = 4; 98 | this.lbl_nickname.Text = "Nickname:"; 99 | // 100 | // nickname 101 | // 102 | this.nickname.Location = new System.Drawing.Point(310, 10); 103 | this.nickname.Name = "nickname"; 104 | this.nickname.Size = new System.Drawing.Size(100, 20); 105 | this.nickname.TabIndex = 5; 106 | this.nickname.Text = "SlimTeamspeakUser"; 107 | // 108 | // lbl_password 109 | // 110 | this.lbl_password.AutoSize = true; 111 | this.lbl_password.Location = new System.Drawing.Point(416, 13); 112 | this.lbl_password.Name = "lbl_password"; 113 | this.lbl_password.Size = new System.Drawing.Size(56, 13); 114 | this.lbl_password.TabIndex = 6; 115 | this.lbl_password.Text = "Password:"; 116 | // 117 | // password 118 | // 119 | this.password.Location = new System.Drawing.Point(478, 10); 120 | this.password.Name = "password"; 121 | this.password.Size = new System.Drawing.Size(100, 20); 122 | this.password.TabIndex = 7; 123 | this.password.Text = "123"; 124 | // 125 | // btn_connect 126 | // 127 | this.btn_connect.Location = new System.Drawing.Point(706, 8); 128 | this.btn_connect.Name = "btn_connect"; 129 | this.btn_connect.Size = new System.Drawing.Size(75, 23); 130 | this.btn_connect.TabIndex = 8; 131 | this.btn_connect.Text = "Connect"; 132 | this.btn_connect.UseVisualStyleBackColor = true; 133 | this.btn_connect.Click += new System.EventHandler(this.btn_connect_Click); 134 | // 135 | // chk_autoconnect 136 | // 137 | this.chk_autoconnect.AutoSize = true; 138 | this.chk_autoconnect.Location = new System.Drawing.Point(609, 12); 139 | this.chk_autoconnect.Name = "chk_autoconnect"; 140 | this.chk_autoconnect.Size = new System.Drawing.Size(91, 17); 141 | this.chk_autoconnect.TabIndex = 9; 142 | this.chk_autoconnect.Text = "Auto Connect"; 143 | this.chk_autoconnect.UseVisualStyleBackColor = true; 144 | this.chk_autoconnect.Visible = false; 145 | // 146 | // TreeView 147 | // 148 | this.TreeView.FormattingEnabled = true; 149 | this.TreeView.Location = new System.Drawing.Point(12, 37); 150 | this.TreeView.Name = "TreeView"; 151 | this.TreeView.Size = new System.Drawing.Size(361, 446); 152 | this.TreeView.TabIndex = 10; 153 | this.TreeView.SelectedIndexChanged += new System.EventHandler(this.listBox1_SelectedIndexChanged); 154 | // 155 | // chatServerTab 156 | // 157 | this.chatServerTab.Location = new System.Drawing.Point(3, 6); 158 | this.chatServerTab.Name = "chatServerTab"; 159 | this.chatServerTab.ReadOnly = true; 160 | this.chatServerTab.Size = new System.Drawing.Size(755, 106); 161 | this.chatServerTab.TabIndex = 11; 162 | this.chatServerTab.Text = ""; 163 | // 164 | // infoData 165 | // 166 | this.infoData.Location = new System.Drawing.Point(379, 37); 167 | this.infoData.Name = "infoData"; 168 | this.infoData.ReadOnly = true; 169 | this.infoData.Size = new System.Drawing.Size(402, 450); 170 | this.infoData.TabIndex = 12; 171 | this.infoData.Text = ""; 172 | // 173 | // btn_send 174 | // 175 | this.btn_send.Enabled = false; 176 | this.btn_send.Location = new System.Drawing.Point(706, 633); 177 | this.btn_send.Name = "btn_send"; 178 | this.btn_send.Size = new System.Drawing.Size(75, 23); 179 | this.btn_send.TabIndex = 13; 180 | this.btn_send.Text = "Send"; 181 | this.btn_send.UseVisualStyleBackColor = true; 182 | this.btn_send.Click += new System.EventHandler(this.btn_send_Click); 183 | // 184 | // txt_message 185 | // 186 | this.txt_message.Location = new System.Drawing.Point(12, 635); 187 | this.txt_message.Name = "txt_message"; 188 | this.txt_message.ReadOnly = true; 189 | this.txt_message.Size = new System.Drawing.Size(688, 20); 190 | this.txt_message.TabIndex = 14; 191 | this.txt_message.TextChanged += new System.EventHandler(this.txt_message_TextChanged); 192 | // 193 | // btn_disconnect 194 | // 195 | this.btn_disconnect.Location = new System.Drawing.Point(706, 8); 196 | this.btn_disconnect.Name = "btn_disconnect"; 197 | this.btn_disconnect.Size = new System.Drawing.Size(75, 23); 198 | this.btn_disconnect.TabIndex = 15; 199 | this.btn_disconnect.Text = "Disconnect"; 200 | this.btn_disconnect.UseVisualStyleBackColor = true; 201 | this.btn_disconnect.Visible = false; 202 | this.btn_disconnect.Click += new System.EventHandler(this.btn_disconnect_Click); 203 | // 204 | // chatTabWidget 205 | // 206 | this.chatTabWidget.Controls.Add(this.tabPage1); 207 | this.chatTabWidget.Controls.Add(this.tabPage2); 208 | this.chatTabWidget.Location = new System.Drawing.Point(12, 489); 209 | this.chatTabWidget.Name = "chatTabWidget"; 210 | this.chatTabWidget.SelectedIndex = 0; 211 | this.chatTabWidget.Size = new System.Drawing.Size(769, 140); 212 | this.chatTabWidget.TabIndex = 16; 213 | // 214 | // tabPage1 215 | // 216 | this.tabPage1.Controls.Add(this.chatServerTab); 217 | this.tabPage1.Location = new System.Drawing.Point(4, 22); 218 | this.tabPage1.Name = "tabPage1"; 219 | this.tabPage1.Padding = new System.Windows.Forms.Padding(3); 220 | this.tabPage1.Size = new System.Drawing.Size(761, 114); 221 | this.tabPage1.TabIndex = 0; 222 | this.tabPage1.Text = "Server"; 223 | this.tabPage1.UseVisualStyleBackColor = true; 224 | // 225 | // tabPage2 226 | // 227 | this.tabPage2.Controls.Add(this.chatChannelTab); 228 | this.tabPage2.Location = new System.Drawing.Point(4, 22); 229 | this.tabPage2.Name = "tabPage2"; 230 | this.tabPage2.Padding = new System.Windows.Forms.Padding(3); 231 | this.tabPage2.Size = new System.Drawing.Size(761, 114); 232 | this.tabPage2.TabIndex = 1; 233 | this.tabPage2.Text = "Channel"; 234 | this.tabPage2.UseVisualStyleBackColor = true; 235 | // 236 | // chatChannelTab 237 | // 238 | this.chatChannelTab.Location = new System.Drawing.Point(3, 4); 239 | this.chatChannelTab.Name = "chatChannelTab"; 240 | this.chatChannelTab.ReadOnly = true; 241 | this.chatChannelTab.Size = new System.Drawing.Size(755, 106); 242 | this.chatChannelTab.TabIndex = 12; 243 | this.chatChannelTab.Text = ""; 244 | // 245 | // MainWindow 246 | // 247 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 248 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 249 | this.ClientSize = new System.Drawing.Size(793, 658); 250 | this.Controls.Add(this.chatTabWidget); 251 | this.Controls.Add(this.btn_disconnect); 252 | this.Controls.Add(this.txt_message); 253 | this.Controls.Add(this.btn_send); 254 | this.Controls.Add(this.infoData); 255 | this.Controls.Add(this.TreeView); 256 | this.Controls.Add(this.chk_autoconnect); 257 | this.Controls.Add(this.btn_connect); 258 | this.Controls.Add(this.password); 259 | this.Controls.Add(this.lbl_password); 260 | this.Controls.Add(this.nickname); 261 | this.Controls.Add(this.lbl_nickname); 262 | this.Controls.Add(this.port); 263 | this.Controls.Add(this.lbl_port); 264 | this.Controls.Add(this.ip); 265 | this.Controls.Add(this.lbl_ip); 266 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 267 | this.Name = "MainWindow"; 268 | this.Text = "Teamspeak 3 Client"; 269 | this.chatTabWidget.ResumeLayout(false); 270 | this.tabPage1.ResumeLayout(false); 271 | this.tabPage2.ResumeLayout(false); 272 | this.ResumeLayout(false); 273 | this.PerformLayout(); 274 | 275 | } 276 | 277 | #endregion 278 | 279 | private System.Windows.Forms.Label lbl_ip; 280 | private System.Windows.Forms.TextBox ip; 281 | private System.Windows.Forms.Label lbl_port; 282 | private System.Windows.Forms.TextBox port; 283 | private System.Windows.Forms.Label lbl_nickname; 284 | private System.Windows.Forms.TextBox nickname; 285 | private System.Windows.Forms.Label lbl_password; 286 | private System.Windows.Forms.TextBox password; 287 | private System.Windows.Forms.Button btn_connect; 288 | private System.Windows.Forms.CheckBox chk_autoconnect; 289 | public System.Windows.Forms.ListBox TreeView; 290 | public System.Windows.Forms.RichTextBox chatServerTab; 291 | public System.Windows.Forms.RichTextBox infoData; 292 | public System.Windows.Forms.Button btn_send; 293 | public System.Windows.Forms.TextBox txt_message; 294 | public System.Windows.Forms.Button btn_disconnect; 295 | public System.Windows.Forms.TabControl chatTabWidget; 296 | public System.Windows.Forms.TabPage tabPage1; 297 | public System.Windows.Forms.TabPage tabPage2; 298 | public System.Windows.Forms.RichTextBox chatChannelTab; 299 | } 300 | } 301 | 302 | -------------------------------------------------------------------------------- /TS3ClientGUI/MainWindow.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 | using TS3Client; 11 | using TS3Client.Messages; 12 | using TS3Client.Full; 13 | 14 | namespace TS3ClientGUI 15 | { 16 | public partial class MainWindow : Form 17 | { 18 | public MainWindow() 19 | { 20 | InitializeComponent(); 21 | LoadSettings(); 22 | if (Properties.Settings.Default.autoconnect) 23 | Connect(); 24 | } 25 | 26 | public void LoadSettings() 27 | { 28 | var settings = Properties.Settings.Default; 29 | this.ip.Text = settings.ip; 30 | this.port.Text = settings.port.ToString(); 31 | this.nickname.Text = settings.nickname; 32 | this.password.Text = settings.password; 33 | this.chk_autoconnect.Checked = settings.autoconnect; 34 | } 35 | 36 | public void SaveSettings() 37 | { 38 | var settings = Properties.Settings.Default; 39 | settings.ip = this.ip.Text; 40 | settings.port = Convert.ToUInt16(this.port.Text); 41 | settings.nickname = this.nickname.Text; 42 | settings.password = this.password.Text; 43 | settings.autoconnect = this.chk_autoconnect.Checked; 44 | Properties.Settings.Default.Save(); 45 | } 46 | 47 | public void Connect() 48 | { 49 | SaveSettings(); 50 | this.btn_connect.Visible = false; 51 | this.btn_disconnect.Visible = true; 52 | this.txt_message.ReadOnly = false; 53 | this.btn_send.Enabled = true; 54 | Client.TS3Client.Connect(this); 55 | } 56 | 57 | private void listBox1_SelectedIndexChanged(object sender, EventArgs e) 58 | { 59 | 60 | } 61 | 62 | private void btn_connect_Click(object sender, EventArgs e) 63 | { 64 | Connect(); 65 | } 66 | 67 | private void txt_message_TextChanged(object sender, EventArgs e) 68 | { 69 | this.btn_send.Enabled = true; 70 | } 71 | 72 | private void btn_disconnect_Click(object sender, EventArgs e) 73 | { 74 | this.btn_disconnect.Visible = false; 75 | this.btn_connect.Visible = true; 76 | this.btn_send.Enabled = false; 77 | this.txt_message.ReadOnly = true; 78 | Client.TS3Client.client.Disconnect(); 79 | } 80 | 81 | private void btn_send_Click(object sender, EventArgs e) 82 | { 83 | Client.TS3Client.SendMessage(this.txt_message.Text); 84 | this.txt_message.Clear(); 85 | } 86 | 87 | protected override bool ProcessCmdKey(ref Message msg, Keys keyData) 88 | { 89 | if (keyData == (Keys.Up)) 90 | { 91 | this.txt_message.ClearUndo(); 92 | return true; 93 | } 94 | return base.ProcessCmdKey(ref msg, keyData); 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /TS3ClientGUI/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.Windows.Forms; 6 | 7 | namespace TS3ClientGUI 8 | { 9 | static class Program 10 | { 11 | /// 12 | /// The main entry point for the application. 13 | /// 14 | [STAThread] 15 | static void Main() 16 | { 17 | Application.EnableVisualStyles(); 18 | Application.SetCompatibleTextRenderingDefault(false); 19 | Application.Run(new MainWindow()); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /TS3ClientGUI/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("TS3ClientGUI")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("TS3ClientGUI")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("79ac094f-59fe-4198-9088-982265ab12f0")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /TS3ClientGUI/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 TS3ClientGUI.Properties 12 | { 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 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// Returns the cached ResourceManager instance used by this class. 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("TS3ClientGUI.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// Overrides the current thread's CurrentUICulture property for all 56 | /// resource lookups using this strongly typed resource class. 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /TS3ClientGUI/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 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /TS3ClientGUI/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 TS3ClientGUI.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 | [global::System.Configuration.UserScopedSettingAttribute()] 27 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 28 | [global::System.Configuration.DefaultSettingValueAttribute("127.0.0.1")] 29 | public string ip { 30 | get { 31 | return ((string)(this["ip"])); 32 | } 33 | set { 34 | this["ip"] = value; 35 | } 36 | } 37 | 38 | [global::System.Configuration.UserScopedSettingAttribute()] 39 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 40 | [global::System.Configuration.DefaultSettingValueAttribute("9987")] 41 | public ushort port { 42 | get { 43 | return ((ushort)(this["port"])); 44 | } 45 | set { 46 | this["port"] = value; 47 | } 48 | } 49 | 50 | [global::System.Configuration.UserScopedSettingAttribute()] 51 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 52 | [global::System.Configuration.DefaultSettingValueAttribute("SlimTeamspeakUser")] 53 | public string nickname { 54 | get { 55 | return ((string)(this["nickname"])); 56 | } 57 | set { 58 | this["nickname"] = value; 59 | } 60 | } 61 | 62 | [global::System.Configuration.UserScopedSettingAttribute()] 63 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 64 | [global::System.Configuration.DefaultSettingValueAttribute("123")] 65 | public string password { 66 | get { 67 | return ((string)(this["password"])); 68 | } 69 | set { 70 | this["password"] = value; 71 | } 72 | } 73 | 74 | [global::System.Configuration.UserScopedSettingAttribute()] 75 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 76 | [global::System.Configuration.DefaultSettingValueAttribute("False")] 77 | public bool autoconnect { 78 | get { 79 | return ((bool)(this["autoconnect"])); 80 | } 81 | set { 82 | this["autoconnect"] = value; 83 | } 84 | } 85 | 86 | [global::System.Configuration.UserScopedSettingAttribute()] 87 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 88 | [global::System.Configuration.DefaultSettingValueAttribute("False")] 89 | public bool debug { 90 | get { 91 | return ((bool)(this["debug"])); 92 | } 93 | set { 94 | this["debug"] = value; 95 | } 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /TS3ClientGUI/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 127.0.0.1 7 | 8 | 9 | 9987 10 | 11 | 12 | SlimTeamspeakUser 13 | 14 | 15 | 123 16 | 17 | 18 | False 19 | 20 | 21 | False 22 | 23 | 24 | -------------------------------------------------------------------------------- /TS3ClientGUI/TS3ClientGUI.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {79AC094F-59FE-4198-9088-982265AB12F0} 8 | WinExe 9 | Properties 10 | TS3ClientGUI 11 | TS3ClientGUI 12 | v4.5 13 | 512 14 | publish\ 15 | true 16 | Disk 17 | false 18 | Foreground 19 | 7 20 | Days 21 | false 22 | false 23 | true 24 | 0 25 | 1.0.0.%2a 26 | false 27 | false 28 | true 29 | 30 | 31 | AnyCPU 32 | true 33 | full 34 | false 35 | bin\Debug\ 36 | DEBUG;TRACE 37 | prompt 38 | 4 39 | 40 | 41 | AnyCPU 42 | pdbonly 43 | true 44 | bin\Release\ 45 | TRACE 46 | prompt 47 | 4 48 | 49 | 50 | ts3client.ico 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | Form 69 | 70 | 71 | MainWindow.cs 72 | 73 | 74 | 75 | 76 | MainWindow.cs 77 | 78 | 79 | ResXFileCodeGenerator 80 | Resources.Designer.cs 81 | Designer 82 | 83 | 84 | True 85 | Resources.resx 86 | 87 | 88 | SettingsSingleFileGenerator 89 | Settings.Designer.cs 90 | 91 | 92 | True 93 | Settings.settings 94 | True 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | False 106 | Microsoft .NET Framework 4.5 %28x86 and x64%29 107 | true 108 | 109 | 110 | False 111 | .NET Framework 3.5 SP1 112 | false 113 | 114 | 115 | 116 | 117 | {0eb99e9d-87e5-4534-a100-55d231c2b6a6} 118 | TS3Client 119 | 120 | 121 | 122 | 129 | -------------------------------------------------------------------------------- /TS3ClientGUI/TS3ClientGUI.csproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | publish\ 5 | 6 | 7 | 8 | 9 | 10 | en-US 11 | false 12 | 13 | -------------------------------------------------------------------------------- /TS3ClientGUI/ts3client.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/TS3ClientGUI/ts3client.ico -------------------------------------------------------------------------------- /packages/BouncyCastle.1.8.1/BouncyCastle.1.8.1.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/BouncyCastle.1.8.1/BouncyCastle.1.8.1.nupkg -------------------------------------------------------------------------------- /packages/BouncyCastle.1.8.1/Readme.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/BouncyCastle.1.8.1/Readme.txt -------------------------------------------------------------------------------- /packages/BouncyCastle.1.8.1/lib/BouncyCastle.Crypto.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/BouncyCastle.1.8.1/lib/BouncyCastle.Crypto.dll -------------------------------------------------------------------------------- /packages/Fody.1.29.4/Content/FodyWeavers.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/Fody.1.29.4/Fody.1.29.4.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/Fody.1.29.4/Fody.1.29.4.nupkg -------------------------------------------------------------------------------- /packages/Fody.1.29.4/Fody.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/Fody.1.29.4/Fody.dll -------------------------------------------------------------------------------- /packages/Fody.1.29.4/Fody.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/Fody.1.29.4/Fody.pdb -------------------------------------------------------------------------------- /packages/Fody.1.29.4/FodyCommon.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/Fody.1.29.4/FodyCommon.dll -------------------------------------------------------------------------------- /packages/Fody.1.29.4/FodyCommon.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/Fody.1.29.4/FodyCommon.pdb -------------------------------------------------------------------------------- /packages/Fody.1.29.4/FodyIsolated.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/Fody.1.29.4/FodyIsolated.dll -------------------------------------------------------------------------------- /packages/Fody.1.29.4/FodyIsolated.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/Fody.1.29.4/FodyIsolated.pdb -------------------------------------------------------------------------------- /packages/Fody.1.29.4/Mono.Cecil.Mdb.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/Fody.1.29.4/Mono.Cecil.Mdb.dll -------------------------------------------------------------------------------- /packages/Fody.1.29.4/Mono.Cecil.Pdb.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/Fody.1.29.4/Mono.Cecil.Pdb.dll -------------------------------------------------------------------------------- /packages/Fody.1.29.4/Mono.Cecil.Rocks.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/Fody.1.29.4/Mono.Cecil.Rocks.dll -------------------------------------------------------------------------------- /packages/Fody.1.29.4/Mono.Cecil.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/Fody.1.29.4/Mono.Cecil.dll -------------------------------------------------------------------------------- /packages/Fody.1.29.4/build/dotnet/Fody.targets: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | $(NCrunchOriginalSolutionDir) 7 | 8 | 9 | 10 | 11 | $(SolutionDir) 12 | 13 | 14 | 15 | 16 | $(MSBuildProjectDirectory)..\..\..\ 17 | 18 | 19 | 20 | 21 | 22 | 23 | $(KeyOriginatorFile) 24 | 25 | 26 | 27 | 28 | $(AssemblyOriginatorKeyFile) 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | $(ProjectDir)$(IntermediateOutputPath) 39 | $(SignAssembly) 40 | $(MSBuildThisFileDirectory)..\..\ 41 | 42 | 45 | 49 | 50 | 62 | 63 | 66 | 67 | 68 | 69 | 70 | 73 | 77 | 78 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /packages/Fody.1.29.4/build/portable-net+sl+win+wpa+wp/Fody.targets: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | $(NCrunchOriginalSolutionDir) 7 | 8 | 9 | 10 | 11 | $(SolutionDir) 12 | 13 | 14 | 15 | 16 | $(MSBuildProjectDirectory)..\..\..\ 17 | 18 | 19 | 20 | 21 | 22 | 23 | $(KeyOriginatorFile) 24 | 25 | 26 | 27 | 28 | $(AssemblyOriginatorKeyFile) 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | $(ProjectDir)$(IntermediateOutputPath) 39 | $(SignAssembly) 40 | $(MSBuildThisFileDirectory)..\..\ 41 | 42 | 45 | 49 | 50 | 62 | 63 | 66 | 67 | 68 | 69 | 70 | 73 | 77 | 78 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /packages/HtmlAgilityPack.1.4.9.5/HAPIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/HtmlAgilityPack.1.4.9.5/HAPIcon.png -------------------------------------------------------------------------------- /packages/HtmlAgilityPack.1.4.9.5/HtmlAgilityPack.1.4.9.5.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/HtmlAgilityPack.1.4.9.5/HtmlAgilityPack.1.4.9.5.nupkg -------------------------------------------------------------------------------- /packages/HtmlAgilityPack.1.4.9.5/lib/Net20/HtmlAgilityPack.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/HtmlAgilityPack.1.4.9.5/lib/Net20/HtmlAgilityPack.dll -------------------------------------------------------------------------------- /packages/HtmlAgilityPack.1.4.9.5/lib/Net20/HtmlAgilityPack.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/HtmlAgilityPack.1.4.9.5/lib/Net20/HtmlAgilityPack.pdb -------------------------------------------------------------------------------- /packages/HtmlAgilityPack.1.4.9.5/lib/Net40-client/HtmlAgilityPack.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/HtmlAgilityPack.1.4.9.5/lib/Net40-client/HtmlAgilityPack.dll -------------------------------------------------------------------------------- /packages/HtmlAgilityPack.1.4.9.5/lib/Net40-client/HtmlAgilityPack.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/HtmlAgilityPack.1.4.9.5/lib/Net40-client/HtmlAgilityPack.pdb -------------------------------------------------------------------------------- /packages/HtmlAgilityPack.1.4.9.5/lib/Net40/HtmlAgilityPack.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/HtmlAgilityPack.1.4.9.5/lib/Net40/HtmlAgilityPack.dll -------------------------------------------------------------------------------- /packages/HtmlAgilityPack.1.4.9.5/lib/Net40/HtmlAgilityPack.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/HtmlAgilityPack.1.4.9.5/lib/Net40/HtmlAgilityPack.pdb -------------------------------------------------------------------------------- /packages/HtmlAgilityPack.1.4.9.5/lib/Net45/HtmlAgilityPack.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/HtmlAgilityPack.1.4.9.5/lib/Net45/HtmlAgilityPack.dll -------------------------------------------------------------------------------- /packages/HtmlAgilityPack.1.4.9.5/lib/Net45/HtmlAgilityPack.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/HtmlAgilityPack.1.4.9.5/lib/Net45/HtmlAgilityPack.pdb -------------------------------------------------------------------------------- /packages/HtmlAgilityPack.1.4.9.5/lib/NetCore45/HtmlAgilityPack.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/HtmlAgilityPack.1.4.9.5/lib/NetCore45/HtmlAgilityPack.dll -------------------------------------------------------------------------------- /packages/HtmlAgilityPack.1.4.9.5/lib/NetCore45/HtmlAgilityPack.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/HtmlAgilityPack.1.4.9.5/lib/NetCore45/HtmlAgilityPack.pdb -------------------------------------------------------------------------------- /packages/HtmlAgilityPack.1.4.9.5/lib/NetCore45/HtmlAgilityPack.pri: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/HtmlAgilityPack.1.4.9.5/lib/NetCore45/HtmlAgilityPack.pri -------------------------------------------------------------------------------- /packages/HtmlAgilityPack.1.4.9.5/lib/portable-net45+netcore45+wp8+MonoAndroid+MonoTouch/HtmlAgilityPack.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/HtmlAgilityPack.1.4.9.5/lib/portable-net45+netcore45+wp8+MonoAndroid+MonoTouch/HtmlAgilityPack.dll -------------------------------------------------------------------------------- /packages/HtmlAgilityPack.1.4.9.5/lib/portable-net45+netcore45+wp8+MonoAndroid+MonoTouch/HtmlAgilityPack.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/HtmlAgilityPack.1.4.9.5/lib/portable-net45+netcore45+wp8+MonoAndroid+MonoTouch/HtmlAgilityPack.pdb -------------------------------------------------------------------------------- /packages/HtmlAgilityPack.1.4.9.5/lib/portable-net45+netcore45+wpa81+wp8+MonoAndroid+MonoTouch/HtmlAgilityPack.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/HtmlAgilityPack.1.4.9.5/lib/portable-net45+netcore45+wpa81+wp8+MonoAndroid+MonoTouch/HtmlAgilityPack.dll -------------------------------------------------------------------------------- /packages/HtmlAgilityPack.1.4.9.5/lib/portable-net45+netcore45+wpa81+wp8+MonoAndroid+MonoTouch/HtmlAgilityPack.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/HtmlAgilityPack.1.4.9.5/lib/portable-net45+netcore45+wpa81+wp8+MonoAndroid+MonoTouch/HtmlAgilityPack.pdb -------------------------------------------------------------------------------- /packages/HtmlAgilityPack.1.4.9.5/lib/sl5/HtmlAgilityPack.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/HtmlAgilityPack.1.4.9.5/lib/sl5/HtmlAgilityPack.dll -------------------------------------------------------------------------------- /packages/HtmlAgilityPack.1.4.9.5/lib/sl5/HtmlAgilityPack.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/HtmlAgilityPack.1.4.9.5/lib/sl5/HtmlAgilityPack.pdb -------------------------------------------------------------------------------- /packages/HtmlAgilityPack.1.4.9.5/readme.txt: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------- 2 | ---------- Html Agility Pack Nuget Readme ---------- 3 | ---------------------------------------------------- 4 | 5 | ----Silverlight 4 and Windows Phone 7.1+ projects----- 6 | To use XPATH features: System.Xml.Xpath.dll from the Silverlight 4 SDK must be referenced. 7 | This is normally found at 8 | %ProgramFiles(x86)%\Microsoft SDKs\Microsoft SDKs\Silverlight\v4.0\Libraries\Client 9 | or 10 | %ProgramFiles%\Microsoft SDKs\Microsoft SDKs\Silverlight\v4.0\Libraries\Client 11 | 12 | ----Silverlight 5 projects----- 13 | To use XPATH features: System.Xml.Xpath.dll from the Silverlight 5 SDK must be referenced. 14 | This is normally found at 15 | %ProgramFiles(x86)%\Microsoft SDKs\Microsoft SDKs\Silverlight\v5.0\Libraries\Client 16 | or 17 | %ProgramFiles%\Microsoft SDKs\Microsoft SDKs\Silverlight\v5.0\Libraries\Client 18 | -------------------------------------------------------------------------------- /packages/LiteDB.3.0.0/LiteDB.3.0.0.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/LiteDB.3.0.0/LiteDB.3.0.0.nupkg -------------------------------------------------------------------------------- /packages/LiteDB.3.0.0/lib/net35/LiteDB.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/LiteDB.3.0.0/lib/net35/LiteDB.dll -------------------------------------------------------------------------------- /packages/LiteDB.3.0.0/lib/netstandard1.4/LiteDB.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/LiteDB.3.0.0/lib/netstandard1.4/LiteDB.dll -------------------------------------------------------------------------------- /packages/Mono.Cecil.0.9.6.4/Mono.Cecil.0.9.6.4.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/Mono.Cecil.0.9.6.4/Mono.Cecil.0.9.6.4.nupkg -------------------------------------------------------------------------------- /packages/Mono.Cecil.0.9.6.4/lib/net20/Mono.Cecil.Mdb.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/Mono.Cecil.0.9.6.4/lib/net20/Mono.Cecil.Mdb.dll -------------------------------------------------------------------------------- /packages/Mono.Cecil.0.9.6.4/lib/net20/Mono.Cecil.Pdb.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/Mono.Cecil.0.9.6.4/lib/net20/Mono.Cecil.Pdb.dll -------------------------------------------------------------------------------- /packages/Mono.Cecil.0.9.6.4/lib/net20/Mono.Cecil.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/Mono.Cecil.0.9.6.4/lib/net20/Mono.Cecil.dll -------------------------------------------------------------------------------- /packages/Mono.Cecil.0.9.6.4/lib/net35/Mono.Cecil.Mdb.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/Mono.Cecil.0.9.6.4/lib/net35/Mono.Cecil.Mdb.dll -------------------------------------------------------------------------------- /packages/Mono.Cecil.0.9.6.4/lib/net35/Mono.Cecil.Pdb.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/Mono.Cecil.0.9.6.4/lib/net35/Mono.Cecil.Pdb.dll -------------------------------------------------------------------------------- /packages/Mono.Cecil.0.9.6.4/lib/net35/Mono.Cecil.Rocks.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/Mono.Cecil.0.9.6.4/lib/net35/Mono.Cecil.Rocks.dll -------------------------------------------------------------------------------- /packages/Mono.Cecil.0.9.6.4/lib/net35/Mono.Cecil.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/Mono.Cecil.0.9.6.4/lib/net35/Mono.Cecil.dll -------------------------------------------------------------------------------- /packages/Mono.Cecil.0.9.6.4/lib/net40/Mono.Cecil.Mdb.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/Mono.Cecil.0.9.6.4/lib/net40/Mono.Cecil.Mdb.dll -------------------------------------------------------------------------------- /packages/Mono.Cecil.0.9.6.4/lib/net40/Mono.Cecil.Pdb.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/Mono.Cecil.0.9.6.4/lib/net40/Mono.Cecil.Pdb.dll -------------------------------------------------------------------------------- /packages/Mono.Cecil.0.9.6.4/lib/net40/Mono.Cecil.Rocks.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/Mono.Cecil.0.9.6.4/lib/net40/Mono.Cecil.Rocks.dll -------------------------------------------------------------------------------- /packages/Mono.Cecil.0.9.6.4/lib/net40/Mono.Cecil.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/Mono.Cecil.0.9.6.4/lib/net40/Mono.Cecil.dll -------------------------------------------------------------------------------- /packages/Mono.Cecil.0.9.6.4/lib/net45/Mono.Cecil.Mdb.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/Mono.Cecil.0.9.6.4/lib/net45/Mono.Cecil.Mdb.dll -------------------------------------------------------------------------------- /packages/Mono.Cecil.0.9.6.4/lib/net45/Mono.Cecil.Pdb.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/Mono.Cecil.0.9.6.4/lib/net45/Mono.Cecil.Pdb.dll -------------------------------------------------------------------------------- /packages/Mono.Cecil.0.9.6.4/lib/net45/Mono.Cecil.Rocks.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/Mono.Cecil.0.9.6.4/lib/net45/Mono.Cecil.Rocks.dll -------------------------------------------------------------------------------- /packages/Mono.Cecil.0.9.6.4/lib/net45/Mono.Cecil.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/Mono.Cecil.0.9.6.4/lib/net45/Mono.Cecil.dll -------------------------------------------------------------------------------- /packages/Mono.Cecil.0.9.6.4/lib/sl5/Mono.Cecil.Rocks.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/Mono.Cecil.0.9.6.4/lib/sl5/Mono.Cecil.Rocks.dll -------------------------------------------------------------------------------- /packages/Mono.Cecil.0.9.6.4/lib/sl5/Mono.Cecil.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/Mono.Cecil.0.9.6.4/lib/sl5/Mono.Cecil.dll -------------------------------------------------------------------------------- /packages/NUnit.3.6.0/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 Charlie Poole 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | 21 | -------------------------------------------------------------------------------- /packages/NUnit.3.6.0/NOTICES.txt: -------------------------------------------------------------------------------- 1 | NUnit 3.0 is based on earlier versions of NUnit, with Portions 2 | 3 | Copyright (c) 2002-2014 Charlie Poole or 4 | Copyright (c) 2002-2004 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov or 5 | Copyright (c) 2000-2002 Philip A. Craig 6 | -------------------------------------------------------------------------------- /packages/NUnit.3.6.0/NUnit.3.6.0.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/NUnit.3.6.0/NUnit.3.6.0.nupkg -------------------------------------------------------------------------------- /packages/NUnit.3.6.0/lib/MonoAndroid/nunit.framework.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/NUnit.3.6.0/lib/MonoAndroid/nunit.framework.dll -------------------------------------------------------------------------------- /packages/NUnit.3.6.0/lib/Xamarin.iOS10/nunit.framework.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/NUnit.3.6.0/lib/Xamarin.iOS10/nunit.framework.dll -------------------------------------------------------------------------------- /packages/NUnit.3.6.0/lib/net20/NUnit.System.Linq.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/NUnit.3.6.0/lib/net20/NUnit.System.Linq.dll -------------------------------------------------------------------------------- /packages/NUnit.3.6.0/lib/net20/nunit.framework.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/NUnit.3.6.0/lib/net20/nunit.framework.dll -------------------------------------------------------------------------------- /packages/NUnit.3.6.0/lib/net35/nunit.framework.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/NUnit.3.6.0/lib/net35/nunit.framework.dll -------------------------------------------------------------------------------- /packages/NUnit.3.6.0/lib/net40/nunit.framework.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/NUnit.3.6.0/lib/net40/nunit.framework.dll -------------------------------------------------------------------------------- /packages/NUnit.3.6.0/lib/net45/nunit.framework.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/NUnit.3.6.0/lib/net45/nunit.framework.dll -------------------------------------------------------------------------------- /packages/NUnit.3.6.0/lib/netstandard1.6/nunit.framework.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/NUnit.3.6.0/lib/netstandard1.6/nunit.framework.dll -------------------------------------------------------------------------------- /packages/NUnit.3.6.0/lib/portable-net45+win8+wp8+wpa81/nunit.framework.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/NUnit.3.6.0/lib/portable-net45+win8+wp8+wpa81/nunit.framework.dll -------------------------------------------------------------------------------- /packages/PropertyChanged.Fody.1.52.1/Lib/dotnet/PropertyChanged.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/PropertyChanged.Fody.1.52.1/Lib/dotnet/PropertyChanged.dll -------------------------------------------------------------------------------- /packages/PropertyChanged.Fody.1.52.1/Lib/dotnet/PropertyChanged.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | PropertyChanged 5 | 6 | 7 | 8 | 9 | Injects this property to be notified when a dependent property is set. 10 | 11 | 12 | 13 | 14 | Initializes a new instance of . 15 | 16 | A property that will be notified for. 17 | 18 | 19 | 20 | Initializes a new instance of . 21 | 22 | A property that will be notified for. 23 | The properties that will be notified for. 24 | 25 | 26 | 27 | Defines filters on which types to include in the 28 | weaving process. These filters are Regex based and 29 | are matched against the Type.FullName 30 | 31 | 32 | 33 | 34 | Initializes a new instance of . 35 | 36 | The filter to apply to the types in this 37 | assembly. Matching is done by the Regex.IsMatch method using 38 | the Type.FullName as input for the Matching method. 39 | 40 | 41 | 42 | 43 | Injects this property to be notified when a dependent property is set. 44 | 45 | 46 | 47 | 48 | Initializes a new instance of . 49 | 50 | A property that the assigned property depends on. 51 | 52 | 53 | 54 | Initializes a new instance of . 55 | 56 | A property that the assigned property depends on. 57 | The properties that the assigned property depends on. 58 | 59 | 60 | 61 | Exclude a or property from notification. 62 | 63 | 64 | 65 | 66 | Skip equality check before change notification 67 | 68 | 69 | 70 | 71 | Exclude a or property from IsChanged flagging. 72 | 73 | 74 | 75 | 76 | Specifies that PropertyChanged Notification will be added to a class. 77 | 78 | PropertyChanged.Fody will weave the interface and implementation into the class. 79 | When the value of a property changes, the PropertyChanged notification will be raised automatically 80 | 81 | 82 | see https://github.com/Fody/PropertyChanged (link) for more information. 83 | 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /packages/PropertyChanged.Fody.1.52.1/Lib/netstandard10/PropertyChanged.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/PropertyChanged.Fody.1.52.1/Lib/netstandard10/PropertyChanged.dll -------------------------------------------------------------------------------- /packages/PropertyChanged.Fody.1.52.1/Lib/netstandard10/PropertyChanged.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | PropertyChanged 5 | 6 | 7 | 8 | 9 | Injects this property to be notified when a dependent property is set. 10 | 11 | 12 | 13 | 14 | Initializes a new instance of . 15 | 16 | A property that will be notified for. 17 | 18 | 19 | 20 | Initializes a new instance of . 21 | 22 | A property that will be notified for. 23 | The properties that will be notified for. 24 | 25 | 26 | 27 | Defines filters on which types to include in the 28 | weaving process. These filters are Regex based and 29 | are matched against the Type.FullName 30 | 31 | 32 | 33 | 34 | Initializes a new instance of . 35 | 36 | The filter to apply to the types in this 37 | assembly. Matching is done by the Regex.IsMatch method using 38 | the Type.FullName as input for the Matching method. 39 | 40 | 41 | 42 | 43 | Injects this property to be notified when a dependent property is set. 44 | 45 | 46 | 47 | 48 | Initializes a new instance of . 49 | 50 | A property that the assigned property depends on. 51 | 52 | 53 | 54 | Initializes a new instance of . 55 | 56 | A property that the assigned property depends on. 57 | The properties that the assigned property depends on. 58 | 59 | 60 | 61 | Exclude a or property from notification. 62 | 63 | 64 | 65 | 66 | Skip equality check before change notification 67 | 68 | 69 | 70 | 71 | Exclude a or property from IsChanged flagging. 72 | 73 | 74 | 75 | 76 | Specifies that PropertyChanged Notification will be added to a class. 77 | 78 | PropertyChanged.Fody will weave the interface and implementation into the class. 79 | When the value of a property changes, the PropertyChanged notification will be raised automatically 80 | 81 | 82 | see https://github.com/Fody/PropertyChanged (link) for more information. 83 | 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /packages/PropertyChanged.Fody.1.52.1/Lib/portable-net4+sl4+wp8+win8+wpa81+MonoAndroid16+MonoTouch40/PropertyChanged.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/PropertyChanged.Fody.1.52.1/Lib/portable-net4+sl4+wp8+win8+wpa81+MonoAndroid16+MonoTouch40/PropertyChanged.dll -------------------------------------------------------------------------------- /packages/PropertyChanged.Fody.1.52.1/Lib/portable-net4+sl4+wp8+win8+wpa81+MonoAndroid16+MonoTouch40/PropertyChanged.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | PropertyChanged 5 | 6 | 7 | 8 | 9 | Injects this property to be notified when a dependent property is set. 10 | 11 | 12 | 13 | 14 | Initializes a new instance of . 15 | 16 | A property that will be notified for. 17 | 18 | 19 | 20 | Initializes a new instance of . 21 | 22 | A property that will be notified for. 23 | The properties that will be notified for. 24 | 25 | 26 | 27 | Defines filters on which types to include in the 28 | weaving process. These filters are Regex based and 29 | are matched against the Type.FullName 30 | 31 | 32 | 33 | 34 | Initializes a new instance of . 35 | 36 | The filter to apply to the types in this 37 | assembly. Matching is done by the Regex.IsMatch method using 38 | the Type.FullName as input for the Matching method. 39 | 40 | 41 | 42 | 43 | Injects this property to be notified when a dependent property is set. 44 | 45 | 46 | 47 | 48 | Initializes a new instance of . 49 | 50 | A property that the assigned property depends on. 51 | 52 | 53 | 54 | Initializes a new instance of . 55 | 56 | A property that the assigned property depends on. 57 | The properties that the assigned property depends on. 58 | 59 | 60 | 61 | Exclude a or property from notification. 62 | 63 | 64 | 65 | 66 | Skip equality check before change notification 67 | 68 | 69 | 70 | 71 | Exclude a or property from IsChanged flagging. 72 | 73 | 74 | 75 | 76 | Specifies that PropertyChanged Notification will be added to a class. 77 | 78 | PropertyChanged.Fody will weave the interface and implementation into the class. 79 | When the value of a property changes, the PropertyChanged notification will be raised automatically 80 | 81 | 82 | see https://github.com/Fody/PropertyChanged (link) for more information. 83 | 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /packages/PropertyChanged.Fody.1.52.1/PropertyChanged.Fody.1.52.1.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/PropertyChanged.Fody.1.52.1/PropertyChanged.Fody.1.52.1.nupkg -------------------------------------------------------------------------------- /packages/PropertyChanged.Fody.1.52.1/PropertyChanged.Fody.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/PropertyChanged.Fody.1.52.1/PropertyChanged.Fody.dll -------------------------------------------------------------------------------- /packages/PropertyChanged.Fody.1.52.1/PropertyChanged.Fody.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R4P3-NET/TS3Slim/5d6bd1a43622f054b17ffe875853daf8e5078354/packages/PropertyChanged.Fody.1.52.1/PropertyChanged.Fody.pdb -------------------------------------------------------------------------------- /packages/PropertyChanged.Fody.1.52.1/Tools/install.ps1: -------------------------------------------------------------------------------- 1 | param($installPath, $toolsPath, $package, $project) 2 | 3 | 4 | function RemoveForceProjectLevelHack($project) 5 | { 6 | Write-Host "RemoveForceProjectLevelHack" 7 | Foreach ($item in $project.ProjectItems) 8 | { 9 | if ($item.Name -eq "Fody_ToBeDeleted.txt") 10 | { 11 | $item.Delete() 12 | } 13 | } 14 | } 15 | 16 | function FlushVariables() 17 | { 18 | Write-Host "Flushing environment variables" 19 | $env:FodyLastProjectPath = "" 20 | $env:FodyLastWeaverName = "" 21 | $env:FodyLastXmlContents = "" 22 | } 23 | 24 | function Update-FodyConfig($addinName, $project) 25 | { 26 | Write-Host "Update-FodyConfig" 27 | $fodyWeaversPath = [System.IO.Path]::Combine([System.IO.Path]::GetDirectoryName($project.FullName), "FodyWeavers.xml") 28 | 29 | $FodyLastProjectPath = $env:FodyLastProjectPath 30 | $FodyLastWeaverName = $env:FodyLastWeaverName 31 | $FodyLastXmlContents = $env:FodyLastXmlContents 32 | 33 | if ( 34 | ($FodyLastProjectPath -eq $project.FullName) -and 35 | ($FodyLastWeaverName -eq $addinName)) 36 | { 37 | Write-Host "Upgrade detected. Restoring content for $addinName" 38 | [System.IO.File]::WriteAllText($fodyWeaversPath, $FodyLastXmlContents) 39 | FlushVariables 40 | return 41 | } 42 | 43 | FlushVariables 44 | 45 | $xml = [xml](get-content $fodyWeaversPath) 46 | 47 | $weavers = $xml["Weavers"] 48 | $node = $weavers.SelectSingleNode($addinName) 49 | 50 | if (-not $node) 51 | { 52 | Write-Host "Appending node" 53 | $newNode = $xml.CreateElement($addinName) 54 | $weavers.AppendChild($newNode) 55 | } 56 | 57 | $xml.Save($fodyWeaversPath) 58 | } 59 | 60 | function Fix-ReferencesCopyLocal($package, $project) 61 | { 62 | Write-Host "Fix-ReferencesCopyLocal $($package.Id)" 63 | $asms = $package.AssemblyReferences | %{$_.Name} 64 | 65 | foreach ($reference in $project.Object.References) 66 | { 67 | if ($asms -contains $reference.Name + ".dll") 68 | { 69 | if($reference.CopyLocal -eq $true) 70 | { 71 | $reference.CopyLocal = $false; 72 | } 73 | } 74 | } 75 | } 76 | 77 | function UnlockWeaversXml($project) 78 | { 79 | $fodyWeaversProjectItem = $project.ProjectItems.Item("FodyWeavers.xml"); 80 | if ($fodyWeaversProjectItem) 81 | { 82 | $fodyWeaversProjectItem.Open("{7651A701-06E5-11D1-8EBD-00A0C90F26EA}") 83 | $fodyWeaversProjectItem.Save() 84 | $fodyWeaversProjectItem.Document.Close() 85 | } 86 | } 87 | 88 | UnlockWeaversXml($project) 89 | 90 | RemoveForceProjectLevelHack $project 91 | 92 | Update-FodyConfig $package.Id.Replace(".Fody", "") $project 93 | 94 | Fix-ReferencesCopyLocal $package $project -------------------------------------------------------------------------------- /packages/PropertyChanged.Fody.1.52.1/Tools/uninstall.ps1: -------------------------------------------------------------------------------- 1 | param($installPath, $toolsPath, $package, $project) 2 | 3 | 4 | function Update-FodyConfig($addinName, $project) 5 | { 6 | $fodyWeaversPath = [System.IO.Path]::Combine([System.IO.Path]::GetDirectoryName($project.FullName), "FodyWeavers.xml") 7 | 8 | if (!(Test-Path ($fodyWeaversPath))) 9 | { 10 | return 11 | } 12 | 13 | Write-Host "Caching variables for possible update" 14 | $env:FodyLastProjectPath = $project.FullName 15 | $env:FodyLastWeaverName = $addinName 16 | $env:FodyLastXmlContents = [IO.File]::ReadAllText($fodyWeaversPath) 17 | 18 | 19 | $xml = [xml](get-content $fodyWeaversPath) 20 | 21 | $weavers = $xml["Weavers"] 22 | $node = $weavers.SelectSingleNode($addinName) 23 | 24 | if ($node) 25 | { 26 | Write-Host "Removing node from FodyWeavers.xml" 27 | $weavers.RemoveChild($node) 28 | } 29 | 30 | $xml.Save($fodyWeaversPath) 31 | } 32 | 33 | 34 | function UnlockWeaversXml($project) 35 | { 36 | $fodyWeaversProjectItem = $project.ProjectItems.Item("FodyWeavers.xml"); 37 | if ($fodyWeaversProjectItem) 38 | { 39 | $fodyWeaversProjectItem.Open("{7651A701-06E5-11D1-8EBD-00A0C90F26EA}") 40 | $fodyWeaversProjectItem.Save() 41 | $fodyWeaversProjectItem.Document.Close() 42 | } 43 | } 44 | 45 | UnlockWeaversXml($project) 46 | 47 | Update-FodyConfig $package.Id.Replace(".Fody", "") $project --------------------------------------------------------------------------------