diff --git a/README.md b/README.md index 68fb467..54d0015 100644 --- a/README.md +++ b/README.md @@ -3,22 +3,35 @@ Allows you to interact with the TeamSpeak 3 Client via the ClientQuery (Telnet) with your Stream Deck ## Requirements -You need to have the [ClientQuery plugin](https://www.myteamspeak.com/addons/943dd816-7ef2-48d7-82b8-d60c3b9b10b3) installed in your TeamSpeak 3 Client in order to use this plugin. + +You need to have the [ClientQuery plugin](https://www.myteamspeak.com/addons/943dd816-7ef2-48d7-82b8-d60c3b9b10b3) +installed in your TeamSpeak 3 Client in order to use this plugin. ## Changelog + +[v1.7](https://github.com/ZerGo0/streamdeck-teamspeak3integration/releases/tag/v1.7): + +- Added support for Channel Ids to the `Channel Switch` Action + [v1.6](https://github.com/ZerGo0/streamdeck-teamspeak3integration/releases/tag/v1.6): + - Fixed: "|" in `Change Nickname`, `Away Status Message` and so on not working - Added `Channel Switch` Action which allows you to switch the channel when you press the button [v1.5](https://github.com/ZerGo0/streamdeck-teamspeak3integration/releases/tag/v1.5): + - Fixed: Spaces in `Change Nickname`, `Away Status Message` and so on not working -- Added `Toggle INPUT (Local) Mute` Action which allows you to toggle the input mute status locally so that no one on the server can see it (Currently there is no dynamic way to update this status (couldn't find any public information about this), it will use the button state for now) +- Added `Toggle INPUT (Local) Mute` Action which allows you to toggle the input mute status locally so that no one on + the server can see it (Currently there is no dynamic way to update this status (couldn't find any public information + about this), it will use the button state for now) [v1.4](https://github.com/ZerGo0/streamdeck-teamspeak3integration/releases/tag/v1.4): - All actions use 1 Telnet Client now (This should fix a lot of issues and hopefully it shouldn't use that much resources anymore when it fails to create a new Telnet connection) [v1.3](https://github.com/ZerGo0/streamdeck-teamspeak3integration/releases/tag/v1.3): -- Added `Toggle AFK Status` Action which allows you to toggle the away status, input and output mute.FixTs3SpecificChars() + +- Added `Toggle AFK Status` Action which allows you to toggle the away status, input and output mute when you press the + button [v1.2](https://github.com/ZerGo0/streamdeck-teamspeak3integration/releases/tag/v1.2): - Added `Change Nickname` Action which allows you to change your name when you press the button @@ -46,8 +59,10 @@ You need to have the [ClientQuery plugin](https://www.myteamspeak.com/addons/943 * [Download plugin](https://github.com/ZerGo0/streamdeck-teamspeak3integration/releases/) ## Possible improvements -- ~~1 Telnet Client/Connection for all actions (definitely needed for more actions in the future, the TS3 Client can't handle too many connections)~~ ✔️ Done -- ClientQuery API-Key shared across all actions + +- ~~1 Telnet Client/Connection for all actions (definitely needed for more actions in the future, the TS3 Client can't + handle too many connections)~~ ✔️ Done +- ~~ClientQuery API-Key shared across all actions~~ ## I found a bug, who do I contact? For support please contact the developer. Contact information is available at diff --git a/streamdeck-teamspeak3integration/Actions/TeamSpeak3AFKStatusAction.cs b/streamdeck-teamspeak3integration/Actions/TeamSpeak3AFKStatusAction.cs index 7456408..958d0c5 100644 --- a/streamdeck-teamspeak3integration/Actions/TeamSpeak3AFKStatusAction.cs +++ b/streamdeck-teamspeak3integration/Actions/TeamSpeak3AFKStatusAction.cs @@ -1,16 +1,11 @@ using System; using System.Threading.Tasks; - using BarRaider.SdTools; - using Newtonsoft.Json; using Newtonsoft.Json.Linq; - using streamdeck_client_csharp; using streamdeck_client_csharp.Events; - using ZerGo0.TeamSpeak3Integration.Helpers; - using KeyPayload = BarRaider.SdTools.KeyPayload; namespace ZerGo0.TeamSpeak3Integration.Actions @@ -142,14 +137,14 @@ public static PluginSettings CreateDefaultSettings() } } -#region Private Members + #region Private Members private readonly PluginSettings _settings; private int _savedSatus; -#endregion + #endregion -#region Private Methods + #region Private Methods private Task SaveSettings() { @@ -223,6 +218,6 @@ private async Task SetAwayStatusState(int muted = 0) } } -#endregion + #endregion } } \ No newline at end of file diff --git a/streamdeck-teamspeak3integration/Actions/TeamSpeak3AwayStatusAction.cs b/streamdeck-teamspeak3integration/Actions/TeamSpeak3AwayStatusAction.cs index 9e8c849..73cee93 100644 --- a/streamdeck-teamspeak3integration/Actions/TeamSpeak3AwayStatusAction.cs +++ b/streamdeck-teamspeak3integration/Actions/TeamSpeak3AwayStatusAction.cs @@ -1,16 +1,11 @@ using System; using System.Threading.Tasks; - using BarRaider.SdTools; - using Newtonsoft.Json; using Newtonsoft.Json.Linq; - using streamdeck_client_csharp; using streamdeck_client_csharp.Events; - using ZerGo0.TeamSpeak3Integration.Helpers; - using KeyPayload = BarRaider.SdTools.KeyPayload; namespace ZerGo0.TeamSpeak3Integration.Actions @@ -142,14 +137,14 @@ public static PluginSettings CreateDefaultSettings() } } -#region Private Members + #region Private Members private readonly PluginSettings _settings; private int _savedSatus; -#endregion + #endregion -#region Private Methods + #region Private Methods private Task SaveSettings() { @@ -219,6 +214,6 @@ private async Task SetAwayStatusState(int muted = 0) } } -#endregion + #endregion } } \ No newline at end of file diff --git a/streamdeck-teamspeak3integration/Actions/TeamSpeak3ChangeNicknameAction.cs b/streamdeck-teamspeak3integration/Actions/TeamSpeak3ChangeNicknameAction.cs index 9810ac2..a7794a0 100644 --- a/streamdeck-teamspeak3integration/Actions/TeamSpeak3ChangeNicknameAction.cs +++ b/streamdeck-teamspeak3integration/Actions/TeamSpeak3ChangeNicknameAction.cs @@ -1,18 +1,11 @@ using System; using System.Threading.Tasks; - using BarRaider.SdTools; - using Newtonsoft.Json; using Newtonsoft.Json.Linq; - -using PrimS.Telnet; - using streamdeck_client_csharp; using streamdeck_client_csharp.Events; - using ZerGo0.TeamSpeak3Integration.Helpers; - using KeyPayload = BarRaider.SdTools.KeyPayload; namespace ZerGo0.TeamSpeak3Integration.Actions @@ -20,6 +13,12 @@ namespace ZerGo0.TeamSpeak3Integration.Actions [PluginActionId("com.zergo0.teamspeak3integration.changenickname")] public class TeamSpeak3ChangeNicknameAction : PluginBase { + #region Private Members + + private readonly PluginSettings _settings; + + #endregion + public TeamSpeak3ChangeNicknameAction(SDConnection connection, InitialPayload payload) : base(connection, payload) { @@ -98,13 +97,7 @@ public static PluginSettings CreateDefaultSettings() } } -#region Private Members - - private readonly PluginSettings _settings; - -#endregion - -#region Private Methods + #region Private Methods private Task SaveSettings() { @@ -139,6 +132,6 @@ private void ChangeNickname() } } -#endregion + #endregion } } \ No newline at end of file diff --git a/streamdeck-teamspeak3integration/Actions/TeamSpeak3ChannelSwitchAction.cs b/streamdeck-teamspeak3integration/Actions/TeamSpeak3ChannelSwitchAction.cs index 20e3069..1e6c924 100644 --- a/streamdeck-teamspeak3integration/Actions/TeamSpeak3ChannelSwitchAction.cs +++ b/streamdeck-teamspeak3integration/Actions/TeamSpeak3ChannelSwitchAction.cs @@ -1,16 +1,11 @@ using System; using System.Threading.Tasks; - using BarRaider.SdTools; - using Newtonsoft.Json; using Newtonsoft.Json.Linq; - using streamdeck_client_csharp; using streamdeck_client_csharp.Events; - using ZerGo0.TeamSpeak3Integration.Helpers; - using KeyPayload = BarRaider.SdTools.KeyPayload; namespace ZerGo0.TeamSpeak3Integration.Actions @@ -18,7 +13,14 @@ namespace ZerGo0.TeamSpeak3Integration.Actions [PluginActionId("com.zergo0.teamspeak3integration.channelswitch")] public class TeamSpeak3ChannelSwitchAction : PluginBase { - public TeamSpeak3ChannelSwitchAction(SDConnection connection, InitialPayload payload) : base(connection, payload) + #region Private Members + + private readonly PluginSettings _settings; + + #endregion + + public TeamSpeak3ChannelSwitchAction(SDConnection connection, InitialPayload payload) : base(connection, + payload) { if (payload.Settings == null || payload.Settings.Count == 0) _settings = PluginSettings.CreateDefaultSettings(); @@ -95,12 +97,6 @@ public static PluginSettings CreateDefaultSettings() } } - #region Private Members - - private readonly PluginSettings _settings; - - #endregion - #region Private Methods private Task SaveSettings() diff --git a/streamdeck-teamspeak3integration/Actions/TeamSpeak3InputMuteAction.cs b/streamdeck-teamspeak3integration/Actions/TeamSpeak3InputMuteAction.cs index 48c0a52..0867de5 100644 --- a/streamdeck-teamspeak3integration/Actions/TeamSpeak3InputMuteAction.cs +++ b/streamdeck-teamspeak3integration/Actions/TeamSpeak3InputMuteAction.cs @@ -1,16 +1,11 @@ using System; using System.Threading.Tasks; - using BarRaider.SdTools; - using Newtonsoft.Json; using Newtonsoft.Json.Linq; - using streamdeck_client_csharp; using streamdeck_client_csharp.Events; - using ZerGo0.TeamSpeak3Integration.Helpers; - using KeyPayload = BarRaider.SdTools.KeyPayload; namespace ZerGo0.TeamSpeak3Integration.Actions @@ -138,14 +133,14 @@ public static PluginSettings CreateDefaultSettings() } } -#region Private Members + #region Private Members private readonly PluginSettings _settings; private int _savedSatus; -#endregion + #endregion -#region Private Methods + #region Private Methods private Task SaveSettings() { @@ -213,6 +208,6 @@ private async Task SetInputStatusState(int muted = 0) } } -#endregion + #endregion } } \ No newline at end of file diff --git a/streamdeck-teamspeak3integration/Actions/TeamSpeak3InputMuteLocallyAction.cs b/streamdeck-teamspeak3integration/Actions/TeamSpeak3InputMuteLocallyAction.cs index 3a76791..20530af 100644 --- a/streamdeck-teamspeak3integration/Actions/TeamSpeak3InputMuteLocallyAction.cs +++ b/streamdeck-teamspeak3integration/Actions/TeamSpeak3InputMuteLocallyAction.cs @@ -1,16 +1,11 @@ using System; using System.Threading.Tasks; - using BarRaider.SdTools; - using Newtonsoft.Json; using Newtonsoft.Json.Linq; - using streamdeck_client_csharp; using streamdeck_client_csharp.Events; - using ZerGo0.TeamSpeak3Integration.Helpers; - using KeyPayload = BarRaider.SdTools.KeyPayload; namespace ZerGo0.TeamSpeak3Integration.Actions @@ -18,7 +13,8 @@ namespace ZerGo0.TeamSpeak3Integration.Actions [PluginActionId("com.zergo0.teamspeak3integration.toggleinputmutelocally")] public class TeamSpeak3InputMuteLocallyAction : PluginBase { - public TeamSpeak3InputMuteLocallyAction(SDConnection connection, InitialPayload payload) : base(connection, payload) + public TeamSpeak3InputMuteLocallyAction(SDConnection connection, InitialPayload payload) : base(connection, + payload) { if (payload.Settings == null || payload.Settings.Count == 0) _settings = PluginSettings.CreateDefaultSettings(); @@ -138,14 +134,14 @@ public static PluginSettings CreateDefaultSettings() } } -#region Private Members + #region Private Members private readonly PluginSettings _settings; private int _savedSatus; -#endregion + #endregion -#region Private Methods + #region Private Methods private Task SaveSettings() { @@ -213,6 +209,6 @@ private async Task SetInputStatusStateLocally(int muted = 0) } } -#endregion + #endregion } } \ No newline at end of file diff --git a/streamdeck-teamspeak3integration/Actions/TeamSpeak3OutputMuteAction.cs b/streamdeck-teamspeak3integration/Actions/TeamSpeak3OutputMuteAction.cs index 9581008..42b693b 100644 --- a/streamdeck-teamspeak3integration/Actions/TeamSpeak3OutputMuteAction.cs +++ b/streamdeck-teamspeak3integration/Actions/TeamSpeak3OutputMuteAction.cs @@ -1,16 +1,11 @@ using System; using System.Threading.Tasks; - using BarRaider.SdTools; - using Newtonsoft.Json; using Newtonsoft.Json.Linq; - using streamdeck_client_csharp; using streamdeck_client_csharp.Events; - using ZerGo0.TeamSpeak3Integration.Helpers; - using KeyPayload = BarRaider.SdTools.KeyPayload; namespace ZerGo0.TeamSpeak3Integration.Actions @@ -138,14 +133,14 @@ public static PluginSettings CreateDefaultSettings() } } -#region Private Members + #region Private Members private readonly PluginSettings _settings; private int _savedSatus; -#endregion + #endregion -#region Private Methods + #region Private Methods private Task SaveSettings() { @@ -213,6 +208,6 @@ private async Task SetOutputStatusState(int muted = 0) } } -#endregion + #endregion } } \ No newline at end of file diff --git a/streamdeck-teamspeak3integration/Helpers/TeamSpeak3Telnet.cs b/streamdeck-teamspeak3integration/Helpers/TeamSpeak3Telnet.cs index cfac608..61ef7ad 100644 --- a/streamdeck-teamspeak3integration/Helpers/TeamSpeak3Telnet.cs +++ b/streamdeck-teamspeak3integration/Helpers/TeamSpeak3Telnet.cs @@ -2,7 +2,6 @@ using System.Linq; using System.Net.Sockets; using System.Threading; - using PrimS.Telnet; namespace ZerGo0.TeamSpeak3Integration.Helpers @@ -11,6 +10,7 @@ internal static class TeamSpeak3Telnet { public static Client TS3_CLIENT; private static readonly object ro_TS3_CLIENT_LOCK_OBJ = new object(); + public static void SetupTelnetClient(string apiKey) { lock (ro_TS3_CLIENT_LOCK_OBJ) @@ -34,7 +34,7 @@ public static void SetupTelnetClient(string apiKey) } var welcomeMessage = TS3_CLIENT.ReadAsync().Result; - if (!welcomeMessage.Contains("TS3 Client")) + if (!welcomeMessage.Contains("TS3 Client")) { TS3_CLIENT = null; return; @@ -85,7 +85,7 @@ public static int GetClientId() var whoAmIResponse = TS3_CLIENT.ReadAsync().Result; if (whoAmIResponse.Contains("msg=ok")) - return int.Parse(whoAmIResponse.Split(new[] {"clid="}, StringSplitOptions.None)[1] + return int.Parse(whoAmIResponse.Split(new[] { "clid=" }, StringSplitOptions.None)[1] .Split(' ')[0] .Trim()); @@ -96,14 +96,16 @@ public static int GetClientId() } } - private static string Substring(this string @this, string from = null, string until = null, StringComparison comparison = StringComparison.InvariantCulture) + private static string Substring(this string @this, string from = null, string until = null, + StringComparison comparison = StringComparison.InvariantCulture) { var fromLength = (from ?? string.Empty).Length; var startIndex = !string.IsNullOrEmpty(from) ? @this.IndexOf(from, comparison) + fromLength : 0; - if (startIndex < fromLength) throw new ArgumentException("from: Failed to find an instance of the first anchor"); + if (startIndex < fromLength) + throw new ArgumentException("from: Failed to find an instance of the first anchor"); var endIndex = !string.IsNullOrEmpty(until) ? @this.IndexOf(until, startIndex, comparison) @@ -124,6 +126,27 @@ private static string FixTs3SpecificChars(this string @this) return fixedString; } + #region Nickname Stuff + + public static bool ChangeNickname(string nickname) + { + lock (ro_TS3_CLIENT_LOCK_OBJ) + { + if (!TS3_CLIENT.IsConnected) return false; + + if (string.IsNullOrWhiteSpace(nickname)) return false; + + nickname = nickname.FixTs3SpecificChars(); + + TS3_CLIENT.WriteLine($"clientupdate client_nickname={nickname}"); + var changeNicknameResponse = TS3_CLIENT.ReadAsync().Result; + + return changeNicknameResponse.Contains("msg=ok"); + } + } + + #endregion + #region Channel Stuff public static bool ChannelSwitch(string channelName, int clientId) @@ -144,6 +167,8 @@ public static bool ChannelSwitch(string channelName, int clientId) var channel = channelListArray.FirstOrDefault(tempChannel => tempChannel.Substring("channel_name=", " channel") + .FixTs3SpecificChars().Contains(channelName) || + tempChannel.Substring("cid=", " pid") .FixTs3SpecificChars().Contains(channelName)); if (string.IsNullOrWhiteSpace(channel)) return false; @@ -174,28 +199,7 @@ private static string GetChannelList() #endregion -#region Nickname Stuff - - public static bool ChangeNickname(string nickname) - { - lock (ro_TS3_CLIENT_LOCK_OBJ) - { - if (!TS3_CLIENT.IsConnected) return false; - - if (string.IsNullOrWhiteSpace(nickname)) return false; - - nickname = nickname.FixTs3SpecificChars(); - - TS3_CLIENT.WriteLine($"clientupdate client_nickname={nickname}"); - var changeNicknameResponse = TS3_CLIENT.ReadAsync().Result; - - return changeNicknameResponse.Contains("msg=ok"); - } - } - -#endregion - -#region Input Stuff + #region Input Stuff public static int GetInputMuteStatus(int clientId) { @@ -211,7 +215,7 @@ public static int GetInputMuteStatus(int clientId) if (inputMuteStatusIResponse.Contains("msg=ok")) return int.Parse( - inputMuteStatusIResponse.Split(new[] {"client_input_muted="}, StringSplitOptions.None)[1] + inputMuteStatusIResponse.Split(new[] { "client_input_muted=" }, StringSplitOptions.None)[1] .Split('\n')[0] .Trim()); @@ -243,9 +247,9 @@ public static bool SetInputMuteStatus(int inputMuteStatus) } } -#endregion + #endregion -#region Output Stuff + #region Output Stuff public static int GetOutputMuteStatus(int clientId) { @@ -261,10 +265,10 @@ public static int GetOutputMuteStatus(int clientId) if (inputMuteStatusIResponse.Contains("msg=ok")) return int.Parse( - inputMuteStatusIResponse.Split(new[] {"client_output_muted="}, StringSplitOptions.None)[1] + inputMuteStatusIResponse.Split(new[] { "client_output_muted=" }, StringSplitOptions.None)[1] .Split('\n')[0] .Trim()); - + retries++; } @@ -293,9 +297,9 @@ public static bool SetOutputMuteStatus(int outputMuteStatus) } } -#endregion + #endregion -#region Away Stuff + #region Away Stuff public static bool SetAwayStatus(int status) { @@ -332,7 +336,7 @@ public static int GetAwayStatus(int clientId) if (awayStatusResponse.Contains("msg=ok")) return int.Parse( - awayStatusResponse.Split(new[] {"client_away="}, StringSplitOptions.None)[1] + awayStatusResponse.Split(new[] { "client_away=" }, StringSplitOptions.None)[1] .Split('\n')[0] .Trim()); @@ -367,9 +371,9 @@ public static bool SetAwayMessage(string statusMessage) } } -#endregion + #endregion -#region Input Local Stuff + #region Input Local Stuff //TODO: Check how to actually call this, no public information found sadly, doesn't work currently public static int GetInputMuteStatusLocally(int clientId) @@ -377,7 +381,7 @@ public static int GetInputMuteStatusLocally(int clientId) lock (ro_TS3_CLIENT_LOCK_OBJ) { if (!TS3_CLIENT.IsConnected) return -1; - + var retries = 0; while (retries < 10) { @@ -386,7 +390,8 @@ public static int GetInputMuteStatusLocally(int clientId) if (inputMuteStatusIResponse.Contains("msg=ok")) return int.Parse( - inputMuteStatusIResponse.Split(new[] {"client_input_deactivated="}, StringSplitOptions.None)[1] + inputMuteStatusIResponse.Split(new[] { "client_input_deactivated=" }, + StringSplitOptions.None)[1] .Split('\n')[0] .Trim()); @@ -418,6 +423,6 @@ public static bool SetInputMuteStatusLocally(int inputMuteStatus) } } -#endregion + #endregion } } \ No newline at end of file diff --git a/streamdeck-teamspeak3integration/PropertyInspector/ChannelSwitch/ChannelSwitch.html b/streamdeck-teamspeak3integration/PropertyInspector/ChannelSwitch/ChannelSwitch.html index f4055f3..be67bf1 100644 --- a/streamdeck-teamspeak3integration/PropertyInspector/ChannelSwitch/ChannelSwitch.html +++ b/streamdeck-teamspeak3integration/PropertyInspector/ChannelSwitch/ChannelSwitch.html @@ -29,7 +29,7 @@ Detailed Guide with pictures: Here
-
Channel Name
+
Channel Name / ID