Skip to content

Commit c70bfb4

Browse files
committed
Added detection for new 8192 chat size limit
1 parent daaf71b commit c70bfb4

17 files changed

+388
-327
lines changed

TS3ABotUnitTests/TextSplitterTests.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public void Split()
1616
{
1717
for (int i = 4; i < MaxSplit; i++)
1818
{
19-
var parts = LongTextTransform.Transform(Str1, LongTextBehaviour.SplitHard, maxMessageSize: i).ToArray();
19+
var parts = LongTextTransform.Split(Str1, LongTextBehaviour.SplitHard, maxMessageSize: i).ToArray();
2020
foreach (var part in parts)
2121
{
2222
Assert.LessOrEqual(TsString.TokenLength(part), i);

TS3AudioBot/CommandSystem/Text/LongTextTransform.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public static class LongTextTransform
1919
{
2020
private static readonly byte[] SeparatorWeight = new byte[] { (byte)'\n', (byte)',', (byte)' ' };
2121

22-
public static IEnumerable<string> Transform(string text, LongTextBehaviour behaviour, int limit = int.MaxValue, int maxMessageSize = TsConst.MaxSizeTextMessage)
22+
public static IEnumerable<string> Split(string text, LongTextBehaviour behaviour, int maxMessageSize, int limit = int.MaxValue)
2323
{
2424
if (maxMessageSize < 4)
2525
throw new ArgumentOutOfRangeException(nameof(maxMessageSize), "The minimum split length must be at least 4 bytes to fit all utf8 characters");

TS3AudioBot/History/SmartHistoryFormatter.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public class SmartHistoryFormatter : IHistoryFormatter
2727

2828
public string ProcessQuery(AudioLogEntry entry, Func<AudioLogEntry, string> format)
2929
{
30-
return SubstringToken(format(entry), TsConst.MaxSizeTextMessage);
30+
return SubstringToken(format(entry), TsConst.Default.MaxSizeTextMessage);
3131
}
3232

3333
public string ProcessQuery(IEnumerable<AudioLogEntry> entries, Func<AudioLogEntry, string> format)
@@ -46,7 +46,7 @@ public string ProcessQuery(IEnumerable<AudioLogEntry> entries, Func<AudioLogEntr
4646
StringBuilder strb;
4747

4848
// If the entire content fits within the ts3 limitation, we can concat and return it.
49-
if (queryTokenLen <= TsConst.MaxSizeTextMessage)
49+
if (queryTokenLen <= TsConst.Default.MaxSizeTextMessage)
5050
{
5151
if (queryTokenLen == 0) return "Nothing found!";
5252
strb = new StringBuilder(queryTokenLen, queryTokenLen);
@@ -56,7 +56,7 @@ public string ProcessQuery(IEnumerable<AudioLogEntry> entries, Func<AudioLogEntr
5656
return strb.ToString();
5757
}
5858

59-
int spareToken = TsConst.MaxSizeTextMessage;
59+
int spareToken = TsConst.Default.MaxSizeTextMessage;
6060
int listStart = 0;
6161

6262
// Otherwise we go iteratively through the list to test how many entries we can add with our token
@@ -115,7 +115,7 @@ public string ProcessQuery(IEnumerable<AudioLogEntry> entries, Func<AudioLogEntr
115115
}
116116

117117
// now we can just build our result and return
118-
strb = new StringBuilder(TsConst.MaxSizeTextMessage - spareToken, TsConst.MaxSizeTextMessage);
118+
strb = new StringBuilder(TsConst.Default.MaxSizeTextMessage - spareToken, TsConst.Default.MaxSizeTextMessage);
119119
for (int i = useList.Count - 1; i >= 0; i--)
120120
{
121121
var eL = useList[i];

TS3AudioBot/MainCommands.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1794,7 +1794,7 @@ public static async Task Write(this ExecutionInformation info, string message)
17941794
limit = config.Commands.LongMessageSplitLimit;
17951795
}
17961796

1797-
foreach (var msgPart in LongTextTransform.Transform(message, behaviour, limit))
1797+
foreach (var msgPart in LongTextTransform.Split(message, behaviour, ts3Client.ServerConstants.MaxSizeTextMessage, limit))
17981798
{
17991799
switch (invoker.Visibiliy.Value)
18001800
{

TS3AudioBot/Ts3Client.cs

+7-6
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ public sealed class Ts3Client
6565
private ClientId[] ownChannelClients = Array.Empty<ClientId>();
6666

6767
public bool Connected => ts3FullClient.Connected;
68+
public TsConst ServerConstants => ts3FullClient.ServerConstants;
6869

6970
public Ts3Client(ConfBot config, TsFullClient ts3FullClient, Id id)
7071
{
@@ -142,25 +143,25 @@ private async Task<E<string>> ConnectClient()
142143
if (closed)
143144
return "Bot disposed";
144145

145-
VersionSign versionSign;
146+
TsVersionSigned? versionSign;
146147
if (!string.IsNullOrEmpty(config.Connect.ClientVersion.Build.Value))
147148
{
148149
var versionConf = config.Connect.ClientVersion;
149-
versionSign = new VersionSign(versionConf.Build, versionConf.Platform.Value, versionConf.Sign);
150+
versionSign = TsVersionSigned.TryParse(versionConf.Build, versionConf.Platform.Value, versionConf.Sign);
150151

151-
if (!versionSign.CheckValid())
152+
if (versionSign is null)
152153
{
153154
Log.Warn("Invalid version sign, falling back to unknown :P");
154-
versionSign = VersionSign.VER_WIN_3_X_X;
155+
versionSign = TsVersionSigned.VER_WIN_3_X_X;
155156
}
156157
}
157158
else if (Tools.IsLinux)
158159
{
159-
versionSign = VersionSign.VER_LIN_3_X_X;
160+
versionSign = TsVersionSigned.VER_LIN_3_X_X;
160161
}
161162
else
162163
{
163-
versionSign = VersionSign.VER_WIN_3_X_X;
164+
versionSign = TsVersionSigned.VER_WIN_3_X_X;
164165
}
165166

166167
try

TSLib/Commands/TsConst.cs

+41-24
Original file line numberDiff line numberDiff line change
@@ -9,41 +9,58 @@
99

1010
namespace TSLib.Commands
1111
{
12-
public static class TsConst
12+
public class TsConst
1313
{
14+
public static TsConst Default { get; } = new TsConst();
15+
16+
public static TsConst Server_3_8_0 { get; } = new TsConst()
17+
{
18+
MaxSizeTextMessage = 8192
19+
};
20+
21+
public static TsConst GetByServerBuildNum(ulong buildNum)
22+
{
23+
if (buildNum >= 1558938729UL) // 3.8.0 [Build: 1558938729]
24+
return Server_3_8_0;
25+
26+
return Default;
27+
}
28+
1429
// Common Definitions
1530

1631
//limited length, measured in characters
17-
public const int MaxSizeChannelName = 40;
18-
public const int MaxSizeVirtualserverName = 64;
19-
public const int MaxSizeClientNicknameSdk = 64;
20-
public const int MinSizeClientNicknameSdk = 3;
21-
public const int MaxSizeReasonMessage = 80;
32+
public int MaxSizeChannelName { get; private set; } = 40;
33+
public int MaxSizeVirtualserverName { get; private set; } = 64;
34+
public int MaxSizeClientNicknameSdk { get; private set; } = 64;
35+
public int MinSizeClientNicknameSdk { get; private set; } = 3;
36+
public int MaxSizeReasonMessage { get; private set; } = 80;
2237

2338
//limited length, measured in bytes (utf8 encoded)
24-
public const int MaxSizeTextMessage = 1024;
25-
public const int MaxSizeChannelTopic = 255;
26-
public const int MaxSizeChannelDescription = 8192;
27-
public const int MaxSizeVirtualserverWelcomeMessage = 1024;
39+
public int MaxSizeTextMessage { get; private set; } = 1024;
40+
public int MaxSizeChannelTopic { get; private set; } = 255;
41+
public int MaxSizeChannelDescription { get; private set; } = 8192;
42+
public int MaxSizeVirtualserverWelcomeMessage { get; private set; } = 1024;
2843

2944
// Rare Definitions
3045

3146
//limited length, measured in characters
32-
public const int MaxSizeClientNickname = 30;
33-
public const int MinSizeClientNickname = 3;
34-
public const int MaxSizeAwayMessage = 80;
35-
public const int MaxSizeGroupName = 30;
36-
public const int MaxSizeTalkRequestMessage = 50;
37-
public const int MaxSizeComplainMessage = 200;
38-
public const int MaxSizeClientDescription = 200;
39-
public const int MaxSizeHostMessage = 200;
40-
public const int MaxSizeHostbuttonTooltip = 50;
41-
public const int MaxSizepokeMessage = 100;
42-
public const int MaxSizeOfflineMessage = 4096;
43-
public const int MaxSizeOfflineMessageSubject = 200;
47+
public int MaxSizeClientNickname { get; private set; } = 30;
48+
public int MinSizeClientNickname { get; private set; } = 3;
49+
public int MaxSizeAwayMessage { get; private set; } = 80;
50+
public int MaxSizeGroupName { get; private set; } = 30;
51+
public int MaxSizeTalkRequestMessage { get; private set; } = 50;
52+
public int MaxSizeComplainMessage { get; private set; } = 200;
53+
public int MaxSizeClientDescription { get; private set; } = 200;
54+
public int MaxSizeHostMessage { get; private set; } = 200;
55+
public int MaxSizeHostbuttonTooltip { get; private set; } = 50;
56+
public int MaxSizepokeMessage { get; private set; } = 100;
57+
public int MaxSizeOfflineMessage { get; private set; } = 4096;
58+
public int MaxSizeOfflineMessageSubject { get; private set; } = 200;
4459

4560
//limited length, measured in bytes (utf8 encoded)
46-
public const int MaxSizePluginCommand = 1024 * 8;
47-
public const int MaxSizeVirtualserverHostbannerGfxUrl = 2000;
61+
public int MaxSizePluginCommand { get; private set; } = 1024 * 8;
62+
public int MaxSizeVirtualserverHostbannerGfxUrl { get; private set; } = 2000;
63+
64+
public TsConst() { }
4865
}
4966
}

TSLib/ConnectionData.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,11 @@ public class ConnectionDataFull : ConnectionData
3737
public IdentityData Identity { get; }
3838
/// <summary>
3939
/// Set this to the TeamSpeak 3 Version this client should appear as.
40-
/// You can find predefined version data in the <see cref="Full.VersionSign"/>
40+
/// You can find predefined version data in the <see cref="TsVersionSigned"/>
4141
/// class. Please keep in mind that the version data has to have valid sign
4242
/// to be accepted by an official TeamSpeak 3 Server.
4343
/// </summary>
44-
public VersionSign VersionSign { get; }
44+
public TsVersionSigned VersionSign { get; }
4545
/// <summary>The display username.</summary>
4646
public string Username { get; }
4747
/// <summary>The server password. Leave null if none.</summary>
@@ -58,7 +58,7 @@ public class ConnectionDataFull : ConnectionData
5858
public ConnectionDataFull(
5959
string address,
6060
IdentityData identity,
61-
VersionSign? versionSign = null,
61+
TsVersionSigned? versionSign = null,
6262
string? username = null,
6363
Password? serverPassword = null,
6464
string? defaultChannel = null,
@@ -67,7 +67,7 @@ public ConnectionDataFull(
6767
: base(address, logId)
6868
{
6969
Identity = identity;
70-
VersionSign = versionSign ?? (Tools.IsLinux ? VersionSign.VER_LIN_3_X_X : VersionSign.VER_WIN_3_X_X);
70+
VersionSign = versionSign ?? (Tools.IsLinux ? TsVersionSigned.VER_LIN_3_X_X : TsVersionSigned.VER_WIN_3_X_X);
7171
Username = username ?? "TSLibUser";
7272
ServerPassword = serverPassword ?? Password.Empty;
7373
DefaultChannel = defaultChannel ?? string.Empty;

TSLib/DedicatedTaskScheduler.cs

+12-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
// TSLib - A free TeamSpeak 3 and 5 client library
2+
// Copyright (C) 2017 TSLib contributors
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the Open Software License v. 3.0
6+
//
7+
// You should have received a copy of the Open Software License along with this
8+
// program. If not, see <https://opensource.org/licenses/OSL-3.0>.
9+
110
using System;
211
using System.Collections.Concurrent;
312
using System.Collections.Generic;
@@ -40,14 +49,14 @@ private void DoWork()
4049
{
4150
#if DEBUG
4251
var sw = new System.Diagnostics.Stopwatch();
43-
Log.Debug("Processing Task {0}", task.Id);
52+
Log.Trace("Processing Task {0}", task.Id);
4453
#endif
4554
TryExecuteTask(task);
4655
#if DEBUG
4756
var time = sw.Elapsed;
48-
Log.Debug("Task {0} took {1}. Resulted {2}", task.Id, time, task.Status);
57+
Log.Trace("Task {0} took {1}. Resulted {2}", task.Id, time, task.Status);
4958
if (queue.Count == 0)
50-
Log.Debug("Eoq");
59+
Log.Trace("Eoq");
5160
#endif
5261
}
5362
Log.Debug("Finalizing TaskScheduler");

TSLib/Full/Book/Book.cs

+9
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,15 @@ private Server GetServer()
8888
return Server;
8989
}
9090

91+
public void Reset()
92+
{
93+
Channels.Clear();
94+
Clients.Clear();
95+
Groups.Clear();
96+
OwnClient = ClientId.Null;
97+
Server = new Server();
98+
}
99+
91100
// Manual post event functions
92101

93102
partial void PostClientEnterView(ClientEnterView msg) => SetOwnChannelSubscribed(msg.ClientId);

TSLib/Full/TsCrypt.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -766,9 +766,9 @@ public static bool VerifySign(ECPoint publicKey, byte[] data, byte[] proof)
766766

767767
private static readonly byte[] TsVersionSignPublicKey = Convert.FromBase64String("UrN1jX0dBE1vulTNLCoYwrVpfITyo+NBuq/twbf9hLw=");
768768

769-
public static bool EdCheck(VersionSign sign)
769+
public static bool EdCheck(TsVersionSigned sign)
770770
{
771-
var ver = Encoding.ASCII.GetBytes(sign.PlatformName + sign.Name);
771+
var ver = Encoding.ASCII.GetBytes(sign.Platform + sign.Version);
772772
var signArr = Base64Decode(sign.Sign);
773773
if (signArr is null)
774774
return false;
@@ -777,10 +777,10 @@ public static bool EdCheck(VersionSign sign)
777777

778778
public static void VersionSelfCheck()
779779
{
780-
var versions = typeof(VersionSign).GetProperties().Where(prop => prop.PropertyType == typeof(VersionSign));
780+
var versions = typeof(TsVersionSigned).GetProperties().Where(prop => prop.PropertyType == typeof(TsVersionSigned));
781781
foreach (var ver in versions)
782782
{
783-
var verObj = (VersionSign)ver.GetValue(null)!;
783+
var verObj = (TsVersionSigned)ver.GetValue(null)!;
784784
if (!EdCheck(verObj))
785785
throw new Exception($"Version is invalid: {verObj}");
786786
}

TSLib/Full/TsFullClient.cs

+15-10
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
using System.Buffers.Binary;
1212
using System.Collections.Generic;
1313
using System.Linq;
14-
using System.Threading;
1514
using System.Threading.Tasks;
1615
using TSLib.Audio;
1716
using TSLib.Commands;
@@ -41,16 +40,16 @@ public sealed partial class TsFullClient : TsBaseFunctions, IAudioActiveProducer
4140
public ClientId ClientId => packetHandler.ClientId;
4241
/// <summary>The disonnect message when leaving.</summary>
4342
public string QuitMessage { get; set; } = "Disconnected";
44-
/// <summary>The <see cref="Full.VersionSign"/> used to connect.</summary>
45-
public VersionSign VersionSign => connectionDataFull.VersionSign;
46-
/// <summary>The <see cref="Full.IdentityData"/> used to connect.</summary>
43+
/// <summary>The <see cref="TsVersionSigned"/> used to connect.</summary>
44+
public TsVersionSigned VersionSign => connectionDataFull.VersionSign;
45+
/// <summary>The <see cref="IdentityData"/> used to connect.</summary>
4746
public IdentityData Identity => connectionDataFull.Identity;
4847
private TsClientStatus status;
4948
public override bool Connected { get { lock (statusLock) return status == TsClientStatus.Connected; } }
5049
public override bool Connecting { get { lock (statusLock) return status == TsClientStatus.Connecting; } }
5150
protected override Deserializer Deserializer => msgProc.Deserializer;
5251
private ConnectionDataFull connectionDataFull;
53-
public Connection Book { get; set; } = new Connection();
52+
public Connection Book { get; } = new Connection();
5453

5554
public override event EventHandler<DisconnectEventArgs>? OnDisconnected;
5655
public event EventHandler<CommandError>? OnErrorEvent;
@@ -80,15 +79,18 @@ public override async Task Connect(ConnectionData conData)
8079
if (!(conData is ConnectionDataFull conDataFull)) throw new ArgumentException($"Use the {nameof(ConnectionDataFull)} derivative to connect with the full client.", nameof(conData));
8180
if (conDataFull.Identity is null) throw new ArgumentNullException(nameof(conDataFull.Identity));
8281
if (conDataFull.VersionSign is null) throw new ArgumentNullException(nameof(conDataFull.VersionSign));
83-
connectionDataFull = conDataFull;
84-
ConnectionData = conData;
8582

8683
await Disconnect();
8784

8885
remoteAddress = await TsDnsResolver.TryResolve(conData.Address);
8986
if (remoteAddress is null)
9087
throw new TsException("Could not read or resolve address.");
9188

89+
connectionDataFull = conDataFull;
90+
ConnectionData = conData;
91+
ServerConstants = TsConst.Default;
92+
Book.Reset();
93+
9294
var ctx = new ConnectionContext { WasExit = false };
9395
lock (statusLock)
9496
{
@@ -249,6 +251,9 @@ async partial void ProcessEachInitIvExpand2(InitIvExpand2 initIvExpand2)
249251
partial void ProcessEachInitServer(InitServer initServer)
250252
{
251253
packetHandler.ClientId = initServer.ClientId;
254+
var serverVersion = TsVersion.TryParse(initServer.ServerVersion, initServer.ServerPlatform);
255+
if (serverVersion != null)
256+
ServerConstants = TsConst.GetByServerBuildNum(serverVersion.Build);
252257

253258
lock (statusLock)
254259
status = TsClientStatus.Connected;
@@ -474,11 +479,11 @@ public Task ClientEk(string ek, string proof)
474479

475480
public Task ClientInit(string nickname, bool inputHardware, bool outputHardware,
476481
string defaultChannel, string defaultChannelPassword, string serverPassword, string metaData,
477-
string nicknamePhonetic, string defaultToken, string hwid, VersionSign versionSign)
482+
string nicknamePhonetic, string defaultToken, string hwid, TsVersionSigned versionSign)
478483
=> SendNoResponsed(new TsCommand("clientinit") {
479484
{ "client_nickname", nickname },
480-
{ "client_version", versionSign.Name },
481-
{ "client_platform", versionSign.PlatformName },
485+
{ "client_version", versionSign.Version },
486+
{ "client_platform", versionSign.Platform },
482487
{ "client_input_hardware", inputHardware },
483488
{ "client_output_hardware", outputHardware },
484489
{ "client_default_channel", defaultChannel },

0 commit comments

Comments
 (0)