├── .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
--------------------------------------------------------------------------------