Skip to content

Commit 768c186

Browse files
committed
Merge branch 'develop'
2 parents 4f17b29 + a9337cc commit 768c186

File tree

282 files changed

+12665
-12101
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

282 files changed

+12665
-12101
lines changed

.editorconfig

+51
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,63 @@ insert_final_newline = true
88
charset = utf-8
99

1010
[*.cs]
11+
# General Formatting
1112
indent_style = tab
1213
indent_size = tab
1314
tab_width = 4
1415
trim_trailing_whitespace = true
1516

17+
#### .NET Coding Conventions ####
18+
19+
# Organize usings
20+
dotnet_separate_import_directive_groups = false
21+
dotnet_sort_system_directives_first = false
22+
23+
# this. and Me. preferences
24+
dotnet_style_qualification_for_event = false:silent
25+
dotnet_style_qualification_for_field = false:silent
26+
dotnet_style_qualification_for_method = false:suggestion
27+
dotnet_style_qualification_for_property = false:silent
28+
29+
# Language keywords vs BCL types preferences
30+
dotnet_style_predefined_type_for_locals_parameters_members = true
31+
dotnet_style_predefined_type_for_member_access = true
32+
# var preferences
33+
csharp_style_var_elsewhere = false:silent
34+
csharp_style_var_for_built_in_types = false:silent
35+
csharp_style_var_when_type_is_apparent = true:suggestion
36+
37+
# Expression-bodied members
38+
csharp_style_expression_bodied_accessors = true:silent
39+
csharp_style_expression_bodied_constructors = false:silent
40+
csharp_style_expression_bodied_methods = true:silent
41+
csharp_style_expression_bodied_properties = true:silent
42+
43+
# Expression-level preferences
44+
csharp_style_inlined_variable_declaration = true:suggestion
45+
46+
# 'using' directive preferences
47+
csharp_using_directive_placement = outside_namespace:suggestion
48+
49+
#### C# Formatting Rules ####
50+
51+
# Indentation preferences
1652
csharp_indent_switch_labels = false
1753

54+
# Space preferences
55+
csharp_space_after_cast = false
56+
csharp_space_after_colon_in_inheritance_clause = true
57+
csharp_space_after_keywords_in_control_flow_statements = true
58+
csharp_space_before_colon_in_inheritance_clause = true
59+
csharp_space_between_method_call_empty_parameter_list_parentheses = false
60+
csharp_space_between_method_call_name_and_opening_parenthesis = false
61+
csharp_space_between_method_call_parameter_list_parentheses = false
62+
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
63+
csharp_space_between_method_declaration_parameter_list_parentheses = false
64+
65+
# Wrapping preferences
66+
csharp_preserve_single_line_blocks = true
67+
csharp_preserve_single_line_statements = true
68+
1869
[*.{tt,ttinclude}]
1970
insert_final_newline = false

Directory.Build.targets

-8
This file was deleted.

GitVersion.yml

+2-7
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,14 @@ branches:
55
tag: ''
66
increment: Patch
77
prevent-increment-of-merged-branch-version: true
8-
track-merge-target: false
98
regex: ^master$
10-
tracks-release-branches: false
11-
is-release-branch: false
129
is-mainline: true
1310
develop:
11+
mode: ContinuousDeployment
1412
tag: alpha
1513
increment: Minor
16-
prevent-increment-of-merged-branch-version: false
17-
track-merge-target: true
14+
prevent-increment-of-merged-branch-version: true
1815
regex: ^develop$
19-
tracks-release-branches: true
20-
is-release-branch: false
2116
ignore:
2217
sha: []
2318
merge-message-formats: {}

README.md

+20-11
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,14 @@ For an in-depth command tutorial see [here in the wiki](https://github.com/Splam
4242

4343
### Download
4444
Download either one of the latest builds from our [nightly server](https://splamy.de/Nightly#ts3ab):
45-
- [![Download](https://img.shields.io/badge/Download-master-green.svg)](https://splamy.de/api/nightly/ts3ab/master_dotnet_core/download)
45+
- [![Download](https://img.shields.io/badge/Download-master-green.svg)](https://splamy.de/api/nightly/ts3ab/master_dotnet_core_3_1_preview/download)
4646
Versions are mostly considered stable but won't get bigger features as fast.
47-
- [![Download](https://img.shields.io/badge/Download-develop-green.svg)](https://splamy.de/api/nightly/ts3ab/develop_dotnet_core/download)
47+
- [![Download](https://img.shields.io/badge/Download-develop-green.svg)](https://splamy.de/api/nightly/ts3ab/develop/download)
4848
Will always have the latest and greatest but might not be fully stable or have broken features.
49-
- [Docker](https://github.com/getdrunkonmovies-com/TS3AudioBot_docker) (NOTE: This build is community-maintained. It comes with all dependencies as well as youtube-dl preconfigured)
49+
- [![Docker](https://img.shields.io/badge/Docker-0.11.0-0db7ed.svg)](https://github.com/getdrunkonmovies-com/TS3AudioBot_docker) (NOTE: This build is community-maintained. It comes with all dependencies as well as youtube-dl preconfigured)
5050

5151
#### Linux
52-
1. dotnet core: Get the latest `dotnet core 2.2` version by following [this tutorial](https://dotnet.microsoft.com/download/linux-package-manager/ubuntu16-04/sdk-current) and follow the steps after choosing your platform
52+
1. dotnet core: Get the latest `dotnet core 3.1` version by following [this tutorial](https://dotnet.microsoft.com/download/linux-package-manager/ubuntu16-04/sdk-current) and follow the steps after choosing your platform
5353
1. Other dependencies:
5454
* on **Ubuntu**/**Debian**:
5555
Run `sudo apt-get install libopus-dev ffmpeg`
@@ -66,12 +66,12 @@ Run
6666
1. Make sure you have a C compiler installed
6767
1. Make the Opus script runnable with `chmod u+x InstallOpus.sh` and run it with `./InstallOpus.sh`
6868
1. Get the ffmpeg [32bit](https://johnvansickle.com/ffmpeg/builds/ffmpeg-git-i686-static.tar.xz) or [64bit](https://johnvansickle.com/ffmpeg/builds/ffmpeg-git-amd64-static.tar.xz) binary.
69-
1. Extract the ffmpeg archive with `tar -vxf ffmpeg-git-XXbit-static.tar.xz`
70-
1. Get the ffmpeg binary from `ffmpeg-git-*DATE*-amd64-static/ffmpeg` and copy it to `TS3AudioBot/bin/Release/netcoreapp2.2`
69+
1. Extract the ffmpeg archive with `tar -vxf ffmpeg-git-*XXbit*-static.tar.xz`
70+
1. Get the ffmpeg binary from `ffmpeg-git-*DATE*-amd64-static/ffmpeg` and copy it to `TS3AudioBot/bin/Release/netcoreapp3.1`
7171

7272
#### Windows
7373
1. Get the ffmpeg [32bit](https://ffmpeg.zeranoe.com/builds/win32/static/ffmpeg-latest-win32-static.zip) or [64bit](https://ffmpeg.zeranoe.com/builds/win64/static/ffmpeg-latest-win64-static.zip) binary.
74-
1. Open the archive and copy the ffmpeg binary from `ffmpeg-latest-winXX-static/bin/ffmpeg.exe` to `TS3AudioBot/bin/Release/netcoreapp2.2`
74+
1. Open the archive and copy the ffmpeg binary from `ffmpeg-latest-winXX-static/bin/ffmpeg.exe` to `TS3AudioBot/bin/Release/netcoreapp3.1`
7575

7676
### Optional Dependencies
7777
If the bot can't play some youtube videos it might be due to some embedding restrictions which are blocking this.
@@ -99,15 +99,24 @@ For further reading check out the [CommandSystem](https://github.com/Splamy/TS3A
9999
Download the git repository with `git clone --recurse-submodules https://github.com/Splamy/TS3AudioBot.git`.
100100

101101
#### Linux
102-
1. Get the latest `dotnet core 2.2` version by following [this tutorial](https://dotnet.microsoft.com/download/linux-package-manager/ubuntu16-04/sdk-current) and choose your platform
102+
1. Get the latest `dotnet core 3.1` version by following [this tutorial](https://docs.microsoft.com/dotnet/core/install/linux-package-managers) and choose your platform
103103
1. Go into the directory of the repository with `cd TS3AudioBot`
104-
1. Execute `dotnet build --framework netcoreapp2.2 --configuration Release TS3AudioBot` to build the AudioBot
105-
1. The binary will be in `./TS3AudioBot/bin/Release/netcoreapp2.2` and can be run with `dotnet TS3AudioBot.dll`
104+
1. Execute `dotnet build --framework netcoreapp3.1 --configuration Release TS3AudioBot` to build the AudioBot
105+
1. The binary will be in `./TS3AudioBot/bin/Release/netcoreapp3.1` and can be run with `dotnet TS3AudioBot.dll`
106106

107107
#### Windows
108-
1. Make sure you have installed `Visual Studio` with `.NET Framework 4.7.2` and the latest `dotnet core 2.2` or higher
108+
1. Make sure you have `Visual Studio` with the `dotnet core 3.1` development toolchain installed
109109
1. Build the AudioBot with Visual Studio.
110110

111+
### Building the WebInterface
112+
1. Go with the console of your choice into the `./WebInterface` folder
113+
1. Run `npm install` to restore or update all dependencies for this project
114+
1. Run `npm run build` to build the project.
115+
The built project will be in `./WebInterface/dist`.
116+
Make sure to the set the webinterface path in the ts3audiobot.toml to this folder.
117+
1. You can alternatively use `npm run start` for development.
118+
This will use the webpack dev server with live reload instead of the ts3ab server.
119+
111120
## Community
112121

113122
### Localization

TS3ABotUnitTests/BotCommandTests.cs

+59-57
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@
99
using TS3AudioBot.Algorithm;
1010
using TS3AudioBot.CommandSystem;
1111
using TS3AudioBot.CommandSystem.Ast;
12-
using TS3AudioBot.CommandSystem.CommandResults;
1312
using TS3AudioBot.CommandSystem.Commands;
1413
using TS3AudioBot.Dependency;
14+
using TS3AudioBot.Web.Api;
1515
using TSLib;
1616

17+
#nullable enable
1718
namespace TS3ABotUnitTests
1819
{
1920
[TestFixture]
@@ -23,23 +24,17 @@ public class BotCommandTests
2324
public void BotCommandTest()
2425
{
2526
var execInfo = Utils.GetExecInfo("ic3");
26-
string CallCommand(string command)
27-
{
28-
return CommandManager.ExecuteCommand(execInfo, command);
29-
}
27+
string? CallCommand(string command) => CommandManager.Execute(execInfo, command).GetAwaiter().GetResult().AsString();
3028

3129
var output = CallCommand("!help");
3230
Assert.AreEqual(output, CallCommand("!h"));
3331
Assert.AreEqual(output, CallCommand("!eval !h"));
34-
Assert.AreEqual(output, CallCommand("!(!h)"));
35-
output = CallCommand("!h help");
36-
Assert.AreEqual(output, CallCommand("!(!h) help"));
3732
Assert.Throws<CommandException>(() => CallCommand("!"));
3833

3934
// Test random
4035
for (int i = 0; i < 1000; i++)
4136
{
42-
var r = int.Parse(CallCommand("!rng -10 100"));
37+
var r = int.Parse(CallCommand("!rng -10 100")!);
4338
Assert.GreaterOrEqual(r, -10);
4439
Assert.Less(r, 100);
4540
}
@@ -80,12 +75,9 @@ string CallCommand(string command)
8075
public void TailStringTest()
8176
{
8277
var execInfo = Utils.GetExecInfo("ic3");
83-
var group = execInfo.GetModule<CommandManager>().RootGroup;
78+
string? CallCommand(string command) => CommandManager.Execute(execInfo, command).Result.AsString();
79+
var group = execInfo.GetModule<CommandManager>()!.RootGroup;
8480
group.AddCommand("cmd", new FunctionCommand(s => s));
85-
string CallCommand(string command)
86-
{
87-
return CommandManager.ExecuteCommand(execInfo, command);
88-
}
8981

9082
Assert.AreEqual("a", CallCommand("!cmd a"));
9183
Assert.AreEqual("a b", CallCommand("!cmd a b"));
@@ -96,15 +88,15 @@ string CallCommand(string command)
9688
[Test]
9789
public void XCommandSystemFilterTest()
9890
{
99-
var filterList = new Dictionary<string, object>
91+
var filterList = new Dictionary<string, object?>
10092
{
10193
{ "help", null },
10294
{ "quit", null },
10395
{ "play", null },
10496
{ "ply", null }
10597
};
10698

107-
var filter = Filter.GetFilterByName("ic3");
99+
var filter = Filter.GetFilterByName("ic3")!;
108100

109101
// Exact match
110102
var result = filter.Filter(filterList, "help");
@@ -140,35 +132,37 @@ public void XCommandSystemFilterTest()
140132
Assert.IsTrue(result.Any(r => r.Key == "pla"));
141133
}
142134

143-
private static string OptionalFunc(string s = null) => s is null ? "NULL" : "NOT NULL";
135+
private static string OptionalFunc(string? s = null) => s is null ? "NULL" : "NOT NULL";
144136

145137
[Test]
146138
public void XCommandSystemTest()
147139
{
148140
var execInfo = Utils.GetExecInfo("ic3", false);
149-
var group = execInfo.GetModule<CommandManager>().RootGroup;
141+
string? CallCommand(string command) => CommandManager.Execute(execInfo, command).GetAwaiter().GetResult().AsString();
142+
143+
var group = execInfo.GetModule<CommandManager>()!.RootGroup;
150144
group.AddCommand("one", new FunctionCommand(() => "ONE"));
151145
group.AddCommand("two", new FunctionCommand(() => "TWO"));
152146
group.AddCommand("echo", new FunctionCommand(s => s));
153-
group.AddCommand("optional", new FunctionCommand(GetType().GetMethod(nameof(OptionalFunc), BindingFlags.NonPublic | BindingFlags.Static)));
147+
group.AddCommand("optional", new FunctionCommand(GetType().GetMethod(nameof(OptionalFunc), BindingFlags.NonPublic | BindingFlags.Static)!));
154148

155149
// Basic tests
156-
Assert.AreEqual("ONE", CommandManager.ExecuteCommand(execInfo, new ICommand[] { new ResultCommand(new PrimitiveResult<string>("one")) }));
157-
Assert.AreEqual("ONE", CommandManager.ExecuteCommand(execInfo, "!one"));
158-
Assert.AreEqual("TWO", CommandManager.ExecuteCommand(execInfo, "!t"));
159-
Assert.AreEqual("TEST", CommandManager.ExecuteCommand(execInfo, "!e TEST"));
160-
Assert.AreEqual("ONE", CommandManager.ExecuteCommand(execInfo, "!o"));
150+
Assert.AreEqual("ONE", CommandManager.Execute(execInfo, new ICommand[] { new ResultCommand("one") }).Result.AsString());
151+
Assert.AreEqual("ONE", CallCommand("!one"));
152+
Assert.AreEqual("TWO", CallCommand("!t"));
153+
Assert.AreEqual("TEST", CallCommand("!e TEST"));
154+
Assert.AreEqual("ONE", CallCommand("!o"));
161155

162156
// Optional parameters
163-
Assert.Throws<CommandException>(() => CommandManager.ExecuteCommand(execInfo, "!e"));
164-
Assert.AreEqual("NULL", CommandManager.ExecuteCommand(execInfo, "!op"));
165-
Assert.AreEqual("NOT NULL", CommandManager.ExecuteCommand(execInfo, "!op 1"));
157+
Assert.Throws<CommandException>(() => CallCommand("!e"));
158+
Assert.AreEqual("NULL", CallCommand("!op"));
159+
Assert.AreEqual("NOT NULL", CallCommand("!op 1"));
166160

167161
// Command chaining
168-
Assert.AreEqual("TEST", CommandManager.ExecuteCommand(execInfo, "!e (!e TEST)"));
169-
Assert.AreEqual("TWO", CommandManager.ExecuteCommand(execInfo, "!e (!t)"));
170-
Assert.AreEqual("NOT NULL", CommandManager.ExecuteCommand(execInfo, "!op (!e TEST)"));
171-
Assert.AreEqual("ONE", CommandManager.ExecuteCommand(execInfo, "!(!e on)"));
162+
Assert.AreEqual("TEST", CallCommand("!e (!e TEST)"));
163+
Assert.AreEqual("TWO", CallCommand("!e (!t)"));
164+
Assert.AreEqual("NOT NULL", CallCommand("!op (!e TEST)"));
165+
Assert.AreEqual("ONE", CallCommand("!(!e on)"));
172166

173167
// Command overloading
174168
var intCom = new Func<int, string>(_ => "INT");
@@ -178,16 +172,24 @@ public void XCommandSystemTest()
178172
new FunctionCommand(strCom.Method, strCom.Target)
179173
}));
180174

181-
Assert.AreEqual("INT", CommandManager.ExecuteCommand(execInfo, "!overlord 1"));
182-
Assert.AreEqual("STRING", CommandManager.ExecuteCommand(execInfo, "!overlord a"));
183-
Assert.Throws<CommandException>(() => CommandManager.ExecuteCommand(execInfo, "!overlord"));
175+
Assert.AreEqual("INT", CallCommand("!overlord 1"));
176+
Assert.AreEqual("STRING", CallCommand("!overlord a"));
177+
Assert.Throws<CommandException>(() => CallCommand("!overlord"));
178+
179+
// Return unwrap
180+
var json = JsonValue.Create("WRAP");
181+
group.AddCommand("wrapjson", new FunctionCommand(new Func<JsonValue>(() => json)));
182+
Assert.AreEqual(json, CommandManager.Execute(execInfo, "!wrapjson").Result.AsRaw());
183+
Assert.AreEqual("WRAP", CallCommand("!wrapjson")); // AsString()
184+
Assert.AreEqual("WRAP", CallCommand("!echo (!wrapjson)"));
184185
}
185186

186187
[Test]
187188
public void XCommandSystemTest2()
188189
{
189190
var execInfo = Utils.GetExecInfo("exact");
190-
var group = execInfo.GetModule<CommandManager>().RootGroup;
191+
string? CallCommand(string command) => CommandManager.Execute(execInfo!, command).GetAwaiter().GetResult().AsString();
192+
var group = execInfo.GetModule<CommandManager>()!.RootGroup;
191193

192194
var o1 = new OverloadedFunctionCommand();
193195
o1.AddCommand(new FunctionCommand(new Action<int>((_) => { })));
@@ -201,25 +203,25 @@ public void XCommandSystemTest2()
201203
o2.AddCommand("b", new FunctionCommand(new Action(() => { })));
202204
group.AddCommand("three", o2);
203205

204-
Assert.Throws<CommandException>(() => CommandManager.ExecuteCommand(execInfo, "!one"));
205-
Assert.Throws<CommandException>(() => CommandManager.ExecuteCommand(execInfo, "!one \"\""));
206-
Assert.Throws<CommandException>(() => CommandManager.ExecuteCommand(execInfo, "!one (!print \"\")"));
207-
Assert.Throws<CommandException>(() => CommandManager.ExecuteCommand(execInfo, "!one string"));
208-
Assert.DoesNotThrow(() => CommandManager.ExecuteCommand(execInfo, "!one 42"));
209-
Assert.DoesNotThrow(() => CommandManager.ExecuteCommand(execInfo, "!one 4200000000000"));
210-
211-
Assert.Throws<CommandException>(() => CommandManager.ExecuteCommand(execInfo, "!two"));
212-
Assert.Throws<CommandException>(() => CommandManager.ExecuteCommand(execInfo, "!two \"\""));
213-
Assert.Throws<CommandException>(() => CommandManager.ExecuteCommand(execInfo, "!two (!print \"\")"));
214-
Assert.Throws<CommandException>(() => CommandManager.ExecuteCommand(execInfo, "!two 42"));
215-
Assert.DoesNotThrow(() => CommandManager.ExecuteCommand(execInfo, "!two None"));
216-
217-
Assert.Throws<CommandException>(() => CommandManager.ExecuteCommand(execInfo, "!three"));
218-
Assert.Throws<CommandException>(() => CommandManager.ExecuteCommand(execInfo, "!three \"\""));
219-
Assert.Throws<CommandException>(() => CommandManager.ExecuteCommand(execInfo, "!three (!print \"\")"));
220-
Assert.Throws<CommandException>(() => CommandManager.ExecuteCommand(execInfo, "!three c"));
221-
Assert.DoesNotThrow(() => CommandManager.ExecuteCommand(execInfo, "!three a"));
222-
Assert.DoesNotThrow(() => CommandManager.ExecuteCommand(execInfo, "!three b"));
206+
Assert.Throws<CommandException>(() => CallCommand("!one"));
207+
Assert.Throws<CommandException>(() => CallCommand("!one \"\""));
208+
Assert.Throws<CommandException>(() => CallCommand("!one (!print \"\")"));
209+
Assert.Throws<CommandException>(() => CallCommand("!one string"));
210+
Assert.DoesNotThrow(() => CallCommand("!one 42"));
211+
Assert.DoesNotThrow(() => CallCommand("!one 4200000000000"));
212+
213+
Assert.Throws<CommandException>(() => CallCommand("!two"));
214+
Assert.Throws<CommandException>(() => CallCommand("!two \"\""));
215+
Assert.Throws<CommandException>(() => CallCommand("!two (!print \"\")"));
216+
Assert.Throws<CommandException>(() => CallCommand("!two 42"));
217+
Assert.DoesNotThrow(() => CallCommand("!two None"));
218+
219+
Assert.Throws<CommandException>(() => CallCommand("!three"));
220+
Assert.Throws<CommandException>(() => CallCommand("!three \"\""));
221+
Assert.Throws<CommandException>(() => CallCommand("!three (!print \"\")"));
222+
Assert.Throws<CommandException>(() => CallCommand("!three c"));
223+
Assert.DoesNotThrow(() => CallCommand("!three a"));
224+
Assert.DoesNotThrow(() => CallCommand("!three b"));
223225
}
224226

225227
[Test]
@@ -229,7 +231,7 @@ public void EnsureAllCommandsHaveEnglishDocumentationEntry()
229231
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en");
230232

231233
var execInfo = Utils.GetExecInfo("exact");
232-
var cmdMgr = execInfo.GetModule<CommandManager>();
234+
var cmdMgr = execInfo.GetModule<CommandManager>()!;
233235
var errors = new List<string>();
234236
foreach (var cmd in cmdMgr.AllCommands)
235237
{
@@ -274,14 +276,14 @@ internal static class Utils
274276
{
275277
public static ExecutionInformation GetExecInfo(string matcher, bool addMainCommands = true)
276278
{
277-
var cmdMgr = new CommandManager(null);
279+
var cmdMgr = new CommandManager(null!);
278280
if (addMainCommands)
279281
cmdMgr.RegisterCollection(MainCommands.Bag);
280282

281283
var execInfo = new ExecutionInformation();
282284
execInfo.AddModule(new CallerInfo(false) { SkipRightsChecks = true, CommandComplexityMax = int.MaxValue });
283285
execInfo.AddModule(new InvokerData((Uid)"InvokerUid"));
284-
execInfo.AddModule(Filter.GetFilterByName(matcher));
286+
execInfo.AddModule(Filter.GetFilterByName(matcher) ?? throw new Exception("Test filter not found"));
285287
execInfo.AddModule(cmdMgr);
286288
return execInfo;
287289
}

0 commit comments

Comments
 (0)