Skip to content

Commit 6162089

Browse files
committed
Merge branch 'develop'
aka Multi-Instance!
2 parents cdc3ee3 + 25b19d7 commit 6162089

File tree

166 files changed

+10845
-9124
lines changed

Some content is hidden

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

166 files changed

+10845
-9124
lines changed

.gitmodules

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "TS3Client/Declarations"]
2+
path = TS3Client/Declarations
3+
url = https://github.com/ReSpeak/tsdeclarations

.travis.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ after_success:
4040
- export MAIN_DIR=`pwd`
4141
- cd ./TS3AudioBot/bin/Release
4242
- ls
43-
- zip TS3AudioBot.zip TS3AudioBot.exe TS3Client.dll Nett.dll LiteDB.dll Heijden.Dns.dll BouncyCastle.Crypto.dll x64/* x86/*
43+
- zip TS3AudioBot.zip NLog.config *.exe *.dll x64/* x86/*
4444
- 'export version=`mono TS3AudioBot.exe --version | grep "Version: "`'
4545
- "curl -I -H \"Content-Type: application/zip\" -X PUT \"https://splamy.de/api/nightly/ts3ab/${TRAVIS_BRANCH}?token=${uploadkey}&filename=TS3AudioBot.zip&commit=${TRAVIS_COMMIT}&version=${version:9}\" --upload-file ./TS3AudioBot.zip"
4646
- cd "$MAIN_DIR"

README.md

+13-8
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,17 @@ Done:
3333
* (un)subscribe to the Bob to hear music in any channel
3434
* (un)subscribe the Bob to certain channels
3535
* Playlist management for all users
36-
* *broken* | Basic plugin support
37-
38-
In progress:
36+
* Advanced permission configuration
37+
* Extensive plugin support
3938
* Web API
4039

41-
In planning:
42-
* Create multiple client instances automatically for different channels
43-
* (Improved) Rights system
40+
In progress:
4441
* Own web-interface
42+
* (Improved) Rights system
43+
* Multi-instance
44+
45+
In planning:
46+
*See issues*
4547

4648
## Bot Commands
4749
All in all, the bot is fully operable only via chat (and actually only via chat).
@@ -61,7 +63,7 @@ You can add a [youtube-dl](https://github.com/rg3/youtube-dl/) binary or source
6163
### Compilation
6264
Before we start: _If you know what you are doing_ you can alternatively compile each dependency referenced here from source/git by yourself, but I won't add a tutorial for that.
6365

64-
Download the git repository with `git clone https://github.com/Splamy/TS3AudioBot.git`.
66+
Download the git repository with `git clone --recurse-submodules https://github.com/Splamy/TS3AudioBot.git`.
6567

6668
#### Linux
6769
1. See if you have NuGet by just executing `nuget`. If not, get `NuGet.exe` with `wget https://dist.nuget.org/win-x86-commandline/latest/nuget.exe`
@@ -95,7 +97,7 @@ or dive into the Rights syntax [here](https://github.com/Splamy/TS3AudioBot/wiki
9597
1. Start the bot again.
9698
1. Send the bot in a private message `!bot setup <key>` where `<key>` is the privilege key from a previous step.
9799
1. Now you can move the process to the background or close the bot with `!quit` in teamspeak and run it in the background.
98-
The recommended start from now on is `mono TS3AudioBot.exe -q` to disable writing to stdout since the bot logs everything to a log file anyway.
100+
1. (optional) You can configure the logging levels and outputs in the `NLog.config` file, read [here](https://github.com/NLog/NLog/wiki/Configuration-file) to learn more.
99101
1. Congratz, you're done! Enjoy listening to your favourite music, experimenting with the crazy command system or do whatever you whish to do ;).
100102
For further reading check out the [CommandSystem](https://github.com/Splamy/TS3AudioBot/wiki/CommandSystem)
101103

@@ -109,3 +111,6 @@ Why OSL-3.0:
109111
- OSL allows you to link to our libraries without needing to disclose your own project, which might be useful if you want to use the TS3Client as a library.
110112
- If you create plugins you do not have to make them public like in GPL. (Although we would be happier if you shared them :)
111113
- With OSL we want to allow you providing the TS3AB as a service (even commercially). We do not want the software to be sold but the service. We want this software to be free for everyone.
114+
115+
# Badges
116+
[![forthebadge](http://forthebadge.com/images/badges/60-percent-of-the-time-works-every-time.svg)](http://forthebadge.com) [![forthebadge](http://forthebadge.com/images/badges/built-by-developers.svg)](http://forthebadge.com) [![forthebadge](http://forthebadge.com/images/badges/built-with-love.svg)](http://forthebadge.com) [![forthebadge](http://forthebadge.com/images/badges/contains-cat-gifs.svg)](http://forthebadge.com) [![forthebadge](http://forthebadge.com/images/badges/made-with-c-sharp.svg)](http://forthebadge.com)

TS3ABotUnitTests/BotCommandTests.cs

+16-8
Original file line numberDiff line numberDiff line change
@@ -24,21 +24,18 @@ namespace TS3ABotUnitTests
2424
[TestFixture]
2525
public class BotCommandTests
2626
{
27-
private readonly MainBot bot;
27+
private readonly CommandManager cmdMgr;
2828

2929
public BotCommandTests()
3030
{
31-
bot = new MainBot();
32-
var prop = typeof(MainBot).GetProperty(nameof(MainBot.CommandManager));
33-
if (prop != null)
34-
prop.SetValue(bot, new CommandManager());
35-
bot.CommandManager.RegisterMain(bot);
31+
cmdMgr = new CommandManager();
32+
cmdMgr.RegisterMain();
33+
Utils.ExecInfo.AddDynamicObject(cmdMgr);
3634
}
3735

3836
private string CallCommand(string command)
3937
{
40-
var info = new ExecutionInformation(null, new InvokerData("InvokerUid"), null) { SkipRightsChecks = true };
41-
return bot.CommandManager.CommandSystem.ExecuteCommand(info, command);
38+
return cmdMgr.CommandSystem.ExecuteCommand(Utils.ExecInfo, command);
4239
}
4340

4441
[Test]
@@ -92,4 +89,15 @@ public void BotCommandTest()
9289
Assert.Throws<CommandException>(() => CallCommand("!if a == b text (!)"));
9390
}
9491
}
92+
93+
static class Utils
94+
{
95+
static Utils()
96+
{
97+
ExecInfo = new ExecutionInformation();
98+
ExecInfo.AddDynamicObject(new CallerInfo(new InvokerData("InvokerUid"), null) { SkipRightsChecks = true });
99+
}
100+
101+
public static ExecutionInformation ExecInfo { get; }
102+
}
95103
}

TS3ABotUnitTests/UnitTests.cs

+77-111
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,22 @@ public void HistoryFileIntergrityTest()
5858
var data2 = new HistorySaveData(ar2, inv2.DatabaseId);
5959
var data3 = new HistorySaveData(ar3, 103);
6060

61-
var hmf = new HistoryManagerData {HistoryFile = testFile, FillDeletedIds = false};
62-
var db = new DbStore(hmf);
63-
var hf = new HistoryManager(hmf, db);
61+
var memcfg = ConfigFile.CreateDummy();
62+
var hmf = memcfg.GetDataStruct<HistoryManagerData>("HistoryManager", true);
63+
hmf.HistoryFile = testFile;
64+
hmf.FillDeletedIds = false;
65+
66+
DbStore db;
67+
HistoryManager hf;
68+
69+
void CreateDbStore()
70+
{
71+
db = new DbStore(hmf);
72+
hf = new HistoryManager(hmf) { Database = db };
73+
hf.Initialize();
74+
}
75+
76+
CreateDbStore();
6477

6578
hf.LogAudioResource(data1);
6679

@@ -71,8 +84,7 @@ public void HistoryFileIntergrityTest()
7184

7285
db.Dispose();
7386

74-
db = new DbStore(hmf);
75-
hf = new HistoryManager(hmf, db);
87+
CreateDbStore();
7688
lastXEntries = hf.GetLastXEntrys(1);
7789
Assert.True(lastXEntries.Any());
7890
lastEntry = lastXEntries.First();
@@ -89,8 +101,7 @@ public void HistoryFileIntergrityTest()
89101
db.Dispose();
90102

91103
// store and order check
92-
db = new DbStore(hmf);
93-
hf = new HistoryManager(hmf, db);
104+
CreateDbStore();
94105
var lastXEntriesArray = hf.GetLastXEntrys(2).ToArray();
95106
Assert.AreEqual(2, lastXEntriesArray.Length);
96107
Assert.AreEqual(ar2, lastXEntriesArray[0].AudioResource);
@@ -104,8 +115,7 @@ public void HistoryFileIntergrityTest()
104115
db.Dispose();
105116

106117
// check entry renaming
107-
db = new DbStore(hmf);
108-
hf = new HistoryManager(hmf, db);
118+
CreateDbStore();
109119
lastXEntriesArray = hf.GetLastXEntrys(2).ToArray();
110120
Assert.AreEqual(2, lastXEntriesArray.Length);
111121
Assert.AreEqual(ar1, lastXEntriesArray[0].AudioResource);
@@ -125,17 +135,15 @@ public void HistoryFileIntergrityTest()
125135
db.Dispose();
126136

127137
// recheck order
128-
db = new DbStore(hmf);
129-
hf = new HistoryManager(hmf, db);
138+
CreateDbStore();
130139
lastXEntriesArray = hf.GetLastXEntrys(2).ToArray();
131140
Assert.AreEqual(2, lastXEntriesArray.Length);
132141
Assert.AreEqual(ar2, lastXEntriesArray[0].AudioResource);
133142
Assert.AreEqual(ar1, lastXEntriesArray[1].AudioResource);
134143
db.Dispose();
135144

136145
// delete entry 1
137-
db = new DbStore(hmf);
138-
hf = new HistoryManager(hmf, db);
146+
CreateDbStore();
139147
hf.RemoveEntry(hf.FindEntryByResource(ar1));
140148

141149
lastXEntriesArray = hf.GetLastXEntrys(3).ToArray();
@@ -149,8 +157,7 @@ public void HistoryFileIntergrityTest()
149157
db.Dispose();
150158

151159
// delete entry 2
152-
db = new DbStore(hmf);
153-
hf = new HistoryManager(hmf, db);
160+
CreateDbStore();
154161
// .. check integrity from previous store
155162
lastXEntriesArray = hf.GetLastXEntrys(3).ToArray();
156163
Assert.AreEqual(2, lastXEntriesArray.Length);
@@ -167,81 +174,6 @@ public void HistoryFileIntergrityTest()
167174
File.Delete(testFile);
168175
}
169176

170-
[Test]
171-
public void PositionedStreamReaderLineEndings()
172-
{
173-
using (var memStream = new MemoryStream())
174-
{
175-
// Setting streams up
176-
var writer = new StreamWriter(memStream);
177-
string[] values = {
178-
"11\n",
179-
"22\n",
180-
"33\n",
181-
"44\r",
182-
"55\r",
183-
"66\r",
184-
"77\r\n",
185-
"88\r\n",
186-
"99\r\n",
187-
"xx\n","\r",
188-
"yy\n","\r",
189-
"zz\n","\r",
190-
"a\r",
191-
"b\n",
192-
"c\r\n",
193-
"d\n","\r",
194-
"e" };
195-
foreach (var val in values)
196-
writer.Write(val);
197-
writer.Flush();
198-
199-
memStream.Seek(0, SeekOrigin.Begin);
200-
var reader = new PositionedStreamReader(memStream);
201-
202-
int pos = 0;
203-
foreach (var val in values)
204-
{
205-
var line = reader.ReadLine();
206-
pos += val.Length;
207-
208-
Assert.AreEqual(val.TrimEnd('\r', '\n'), line);
209-
Assert.AreEqual(pos, reader.ReadPosition);
210-
}
211-
}
212-
}
213-
214-
[Test]
215-
public void PositionedStreamReaderBufferSize()
216-
{
217-
using (var memStream = new MemoryStream())
218-
{
219-
// Setting streams up
220-
var writer = new StreamWriter(memStream);
221-
string[] values = {
222-
new string('1', 1024) + '\n', // 1025: 1 over buffer size
223-
new string('1', 1023) + '\n', // 1024: exactly the buffer size, but 1 over the 1024 line block due to the previous
224-
new string('1', 1022) + '\n', // 1023: 1 less then the buffer size, should now match the line block again
225-
new string('1', 1024) };
226-
foreach (var val in values)
227-
writer.Write(val);
228-
writer.Flush();
229-
230-
memStream.Seek(0, SeekOrigin.Begin);
231-
var reader = new PositionedStreamReader(memStream);
232-
233-
int pos = 0;
234-
foreach (var val in values)
235-
{
236-
var line = reader.ReadLine();
237-
pos += val.Length;
238-
239-
Assert.AreEqual(val.TrimEnd('\r', '\n'), line);
240-
Assert.AreEqual(pos, reader.ReadPosition);
241-
}
242-
}
243-
}
244-
245177
[Test]
246178
public void UtilSeedTest()
247179
{
@@ -310,26 +242,26 @@ public void XCommandSystemTest()
310242
group.AddCommand("one", new FunctionCommand(() => "ONE"));
311243
group.AddCommand("two", new FunctionCommand(() => "TWO"));
312244
group.AddCommand("echo", new FunctionCommand(s => s));
313-
group.AddCommand("optional", new FunctionCommand(new Func<string, string>(s => s == null ? "NULL" : "NOT NULL")).SetRequiredParameters(0));
245+
group.AddCommand("optional", new FunctionCommand(new Func<string, string>(s => s == null ? "NULL" : "NOT NULL"), 0));
314246

315247
// Basic tests
316-
Assert.AreEqual("ONE", ((StringCommandResult)commandSystem.Execute(ExecutionInformation.Debug,
248+
Assert.AreEqual("ONE", ((StringCommandResult)commandSystem.Execute(Utils.ExecInfo,
317249
new ICommand[] { new StringCommand("one") })).Content);
318-
Assert.AreEqual("ONE", commandSystem.ExecuteCommand(ExecutionInformation.Debug, "!one"));
319-
Assert.AreEqual("TWO", commandSystem.ExecuteCommand(ExecutionInformation.Debug, "!t"));
320-
Assert.AreEqual("TEST", commandSystem.ExecuteCommand(ExecutionInformation.Debug, "!e TEST"));
321-
Assert.AreEqual("ONE", commandSystem.ExecuteCommand(ExecutionInformation.Debug, "!o"));
250+
Assert.AreEqual("ONE", commandSystem.ExecuteCommand(Utils.ExecInfo, "!one"));
251+
Assert.AreEqual("TWO", commandSystem.ExecuteCommand(Utils.ExecInfo, "!t"));
252+
Assert.AreEqual("TEST", commandSystem.ExecuteCommand(Utils.ExecInfo, "!e TEST"));
253+
Assert.AreEqual("ONE", commandSystem.ExecuteCommand(Utils.ExecInfo, "!o"));
322254

323255
// Optional parameters
324-
Assert.Throws<CommandException>(() => commandSystem.ExecuteCommand(ExecutionInformation.Debug, "!e"));
325-
Assert.AreEqual("NULL", commandSystem.ExecuteCommand(ExecutionInformation.Debug, "!op"));
326-
Assert.AreEqual("NOT NULL", commandSystem.ExecuteCommand(ExecutionInformation.Debug, "!op 1"));
256+
Assert.Throws<CommandException>(() => commandSystem.ExecuteCommand(Utils.ExecInfo, "!e"));
257+
Assert.AreEqual("NULL", commandSystem.ExecuteCommand(Utils.ExecInfo, "!op"));
258+
Assert.AreEqual("NOT NULL", commandSystem.ExecuteCommand(Utils.ExecInfo, "!op 1"));
327259

328260
// Command chaining
329-
Assert.AreEqual("TEST", commandSystem.ExecuteCommand(ExecutionInformation.Debug, "!e (!e TEST)"));
330-
Assert.AreEqual("TWO", commandSystem.ExecuteCommand(ExecutionInformation.Debug, "!e (!t)"));
331-
Assert.AreEqual("NOT NULL", commandSystem.ExecuteCommand(ExecutionInformation.Debug, "!op (!e TEST)"));
332-
Assert.AreEqual("ONE", commandSystem.ExecuteCommand(ExecutionInformation.Debug, "!(!e on)"));
261+
Assert.AreEqual("TEST", commandSystem.ExecuteCommand(Utils.ExecInfo, "!e (!e TEST)"));
262+
Assert.AreEqual("TWO", commandSystem.ExecuteCommand(Utils.ExecInfo, "!e (!t)"));
263+
Assert.AreEqual("NOT NULL", commandSystem.ExecuteCommand(Utils.ExecInfo, "!op (!e TEST)"));
264+
Assert.AreEqual("ONE", commandSystem.ExecuteCommand(Utils.ExecInfo, "!(!e on)"));
333265

334266
// Command overloading
335267
var intCom = new Func<int, string>(i => "INT");
@@ -339,9 +271,9 @@ public void XCommandSystemTest()
339271
new FunctionCommand(strCom.Method, strCom.Target)
340272
}));
341273

342-
Assert.AreEqual("INT", commandSystem.ExecuteCommand(ExecutionInformation.Debug, "!overlord 1"));
343-
Assert.AreEqual("STRING", commandSystem.ExecuteCommand(ExecutionInformation.Debug, "!overlord a"));
344-
Assert.Throws<CommandException>(() => commandSystem.ExecuteCommand(ExecutionInformation.Debug, "!overlord"));
274+
Assert.AreEqual("INT", commandSystem.ExecuteCommand(Utils.ExecInfo, "!overlord 1"));
275+
Assert.AreEqual("STRING", commandSystem.ExecuteCommand(Utils.ExecInfo, "!overlord a"));
276+
Assert.Throws<CommandException>(() => commandSystem.ExecuteCommand(Utils.ExecInfo, "!overlord"));
345277
}
346278

347279
[Test]
@@ -399,12 +331,11 @@ public void Factory_YoutubeFactoryTest()
399331
[Test]
400332
public void Ts3Client_RingQueueTest()
401333
{
402-
int ov;
403334
var q = new RingQueue<int>(3, 5);
404335

405336
q.Set(0, 42);
406337

407-
Assert.True(q.TryPeekStart(0, out ov));
338+
Assert.True(q.TryPeekStart(0, out int ov));
408339
Assert.AreEqual(ov, 42);
409340

410341
q.Set(1, 43);
@@ -465,11 +396,12 @@ public void Ts3Client_RingQueueTest()
465396
public void Ts3Client_RingQueueTest2()
466397
{
467398
var q = new RingQueue<int>(50, ushort.MaxValue + 1);
468-
399+
469400
for (int i = 0; i < ushort.MaxValue - 10; i++)
470401
{
471-
q.Set(i, 42);
472-
q.TryDequeue(out var _);
402+
q.Set(i, i);
403+
Assert.True(q.TryDequeue(out var iCheck));
404+
Assert.AreEqual(iCheck, i);
473405
}
474406

475407
var setStatus = q.IsSet(ushort.MaxValue - 20);
@@ -480,6 +412,40 @@ public void Ts3Client_RingQueueTest2()
480412
q.Set(i % (ushort.MaxValue + 1), 42);
481413
}
482414
}
415+
416+
[Test]
417+
public void Ts3Client_RingQueueTest3()
418+
{
419+
var q = new RingQueue<int>(100, ushort.MaxValue + 1);
420+
421+
int iSet = 0;
422+
for (int blockSize = 1; blockSize < 100; blockSize++)
423+
{
424+
for (int i = 0; i < blockSize; i++)
425+
{
426+
q.Set(iSet++, i);
427+
}
428+
for (int i = 0; i < blockSize; i++)
429+
{
430+
Assert.True(q.TryDequeue(out var iCheck));
431+
Assert.AreEqual(i, iCheck);
432+
}
433+
}
434+
435+
for (int blockSize = 1; blockSize < 100; blockSize++)
436+
{
437+
q = new RingQueue<int>(100, ushort.MaxValue + 1);
438+
for (int i = 0; i < blockSize; i++)
439+
{
440+
q.Set(i, i);
441+
}
442+
for (int i = 0; i < blockSize; i++)
443+
{
444+
Assert.True(q.TryDequeue(out var iCheck));
445+
Assert.AreEqual(i, iCheck);
446+
}
447+
}
448+
}
483449
}
484450

485451
static class Extensions

0 commit comments

Comments
 (0)