From d3a6512237bc311aff88ad2770c565c8171a5d38 Mon Sep 17 00:00:00 2001 From: First-Coder Date: Sat, 8 Aug 2020 16:18:22 +0200 Subject: [PATCH 01/14] Bugfixes --- .../{Specialized => }/DataProxy.cs | 5 +- .../{Specialized => Enums}/ClientType.cs | 2 +- .../GetChannelOptions.cs | 2 +- .../GetClientOptions.cs | 2 +- .../GetServerOptions.cs | 2 +- .../{Specialized => Enums}/KickOrigin.cs | 2 +- .../{ => Enums}/ManualEnums.cs | 2 +- .../{Specialized => Enums}/MessageTarget.cs | 2 +- .../NotificationEventTarget.cs | 2 +- .../NotificationType.cs | 2 +- .../{Specialized => Enums}/ReasonId.cs | 2 +- .../{Specialized => Enums}/ServerGroupType.cs | 2 +- .../EnumExtensions.cs | 2 +- .../{ => Extensions}/ListExtensions.cs | 2 +- .../{ => Extensions}/StringExtensions.cs | 2 +- .../{ => Extensions}/TaskExtensions.cs | 2 +- .../{ => FileTransfer}/FileTransferClient.cs | 18 +- .../FileTransferException.cs | 2 +- .../ITeamSpeakSerializable.cs | 2 +- .../ITypeCaster.cs | 3 +- .../Notifications/ChannelCreated.cs | 3 +- .../Notifications/ChannelDeleted.cs | 2 +- .../ChannelDescriptionChanged.cs | 2 +- .../Notifications/ChannelEdited.cs | 3 +- .../Notifications/ChannelMoved.cs | 2 +- .../Notifications/ChannelPasswordChanged.cs | 2 +- .../Notifications/ClientEnterView.cs | 3 +- .../Notifications/ClientLeftView.cs | 3 +- .../Notifications/ClientMoved.cs | 2 +- .../Notifications/InvokerInformation.cs | 4 +- .../Notifications/Notification.cs | 7 + .../{ => Notifications}/NotificationData.cs | 3 +- .../Notifications/ServerEdited.cs | 3 +- .../Notifications/TextMessage.cs | 4 +- .../Notifications/TokenUsed.cs | 2 +- .../{ => Parameters}/IParameterValue.cs | 2 +- .../{ => Parameters}/Parameter.cs | 2 +- .../{ => Parameters}/ParameterValue.cs | 3 +- .../{ => Parameters}/ParameterValueArray.cs | 2 +- .../{ => Query}/QueryClient.cs | 40 +- .../{ => Query}/QueryCommand.cs | 3 +- .../{ => Query}/QueryError.cs | 6 +- .../{ => Query}/QueryException.cs | 4 +- .../{ => Query}/QueryNotification.cs | 3 +- .../{ => Query}/QueryProtocolException.cs | 4 +- .../{ => Query}/QueryResponseDictionary.cs | 2 +- .../QuerySerializeAttribute.cs | 2 +- .../{Specialized => }/Responses/ClientBan.cs | 2 +- .../Responses/CreatedChannel.cs | 2 +- .../Responses/EditChannelInfo.cs | 3 +- .../Responses/FoundChannel.cs | 2 +- .../Responses/GetChannelInfo.cs | 3 +- .../Responses/GetChannelListInfo.cs | 3 +- .../Responses/GetClientDetailedInfo.cs | 3 +- .../Responses/GetClientInfo.cs | 64 +++ .../Responses/GetCurrentFileTransfer.cs | 2 +- .../Responses/GetDbClientInfo.cs | 35 ++ .../Responses/GetFileInfo.cs | 2 +- .../{Specialized => }/Responses/GetFiles.cs | 2 +- .../Responses/GetServerGroup.cs | 2 +- .../Responses/GetServerGroupClientList.cs | 2 +- .../Responses/GetServerGroupListInfo.cs | 4 +- .../Responses/GetServerListInfo.cs | 2 +- .../Responses/InitDownload.cs | 2 +- .../{Specialized => }/Responses/InitUpload.cs | 2 +- src/TeamSpeak3QueryApi/Responses/Response.cs | 7 + .../{Specialized => }/Responses/WhoAmI.cs | 2 +- .../Specialized/Notifications/Notification.cs | 5 - .../Specialized/Responses/GetClientInfo.cs | 20 - .../Specialized/Responses/Response.cs | 5 - .../TeamSpeak3QueryApi.csproj | 6 +- .../{Specialized => }/TeamSpeakClient.cs | 390 +++++++++--------- src/TeamSpeak3QueryApi/ValidationHelper.cs | 6 +- 73 files changed, 455 insertions(+), 301 deletions(-) rename src/TeamSpeak3QueryApi/{Specialized => }/DataProxy.cs (96%) rename src/TeamSpeak3QueryApi/{Specialized => Enums}/ClientType.cs (65%) rename src/TeamSpeak3QueryApi/{Specialized => Enums}/GetChannelOptions.cs (81%) rename src/TeamSpeak3QueryApi/{Specialized => Enums}/GetClientOptions.cs (85%) rename src/TeamSpeak3QueryApi/{Specialized => Enums}/GetServerOptions.cs (79%) rename src/TeamSpeak3QueryApi/{Specialized => Enums}/KickOrigin.cs (64%) rename src/TeamSpeak3QueryApi/{ => Enums}/ManualEnums.cs (98%) rename src/TeamSpeak3QueryApi/{Specialized => Enums}/MessageTarget.cs (70%) rename src/TeamSpeak3QueryApi/{Specialized => Enums}/NotificationEventTarget.cs (77%) rename src/TeamSpeak3QueryApi/{Specialized => Enums}/NotificationType.cs (92%) rename src/TeamSpeak3QueryApi/{Specialized => Enums}/ReasonId.cs (86%) rename src/TeamSpeak3QueryApi/{Specialized => Enums}/ServerGroupType.cs (73%) rename src/TeamSpeak3QueryApi/{Specialized => Extensions}/EnumExtensions.cs (92%) rename src/TeamSpeak3QueryApi/{ => Extensions}/ListExtensions.cs (84%) rename src/TeamSpeak3QueryApi/{ => Extensions}/StringExtensions.cs (97%) rename src/TeamSpeak3QueryApi/{ => Extensions}/TaskExtensions.cs (95%) rename src/TeamSpeak3QueryApi/{ => FileTransfer}/FileTransferClient.cs (82%) rename src/TeamSpeak3QueryApi/{ => FileTransfer}/FileTransferException.cs (96%) rename src/TeamSpeak3QueryApi/{Specialized => Interfaces}/ITeamSpeakSerializable.cs (68%) rename src/TeamSpeak3QueryApi/{Specialized => Interfaces}/ITypeCaster.cs (97%) rename src/TeamSpeak3QueryApi/{Specialized => }/Notifications/ChannelCreated.cs (95%) rename src/TeamSpeak3QueryApi/{Specialized => }/Notifications/ChannelDeleted.cs (78%) rename src/TeamSpeak3QueryApi/{Specialized => }/Notifications/ChannelDescriptionChanged.cs (69%) rename src/TeamSpeak3QueryApi/{Specialized => }/Notifications/ChannelEdited.cs (95%) rename src/TeamSpeak3QueryApi/{Specialized => }/Notifications/ChannelMoved.cs (81%) rename src/TeamSpeak3QueryApi/{Specialized => }/Notifications/ChannelPasswordChanged.cs (69%) rename src/TeamSpeak3QueryApi/{Specialized => }/Notifications/ClientEnterView.cs (97%) rename src/TeamSpeak3QueryApi/{Specialized => }/Notifications/ClientLeftView.cs (89%) rename src/TeamSpeak3QueryApi/{Specialized => }/Notifications/ClientMoved.cs (77%) rename src/TeamSpeak3QueryApi/{Specialized => }/Notifications/InvokerInformation.cs (81%) create mode 100644 src/TeamSpeak3QueryApi/Notifications/Notification.cs rename src/TeamSpeak3QueryApi/{ => Notifications}/NotificationData.cs (89%) rename src/TeamSpeak3QueryApi/{Specialized => }/Notifications/ServerEdited.cs (96%) rename src/TeamSpeak3QueryApi/{Specialized => }/Notifications/TextMessage.cs (80%) rename src/TeamSpeak3QueryApi/{Specialized => }/Notifications/TokenUsed.cs (90%) rename src/TeamSpeak3QueryApi/{ => Parameters}/IParameterValue.cs (89%) rename src/TeamSpeak3QueryApi/{ => Parameters}/Parameter.cs (98%) rename src/TeamSpeak3QueryApi/{ => Parameters}/ParameterValue.cs (97%) rename src/TeamSpeak3QueryApi/{ => Parameters}/ParameterValueArray.cs (98%) rename src/TeamSpeak3QueryApi/{ => Query}/QueryClient.cs (91%) rename src/TeamSpeak3QueryApi/{ => Query}/QueryCommand.cs (91%) rename src/TeamSpeak3QueryApi/{ => Query}/QueryError.cs (80%) rename src/TeamSpeak3QueryApi/{ => Query}/QueryException.cs (94%) rename src/TeamSpeak3QueryApi/{ => Query}/QueryNotification.cs (80%) rename src/TeamSpeak3QueryApi/{ => Query}/QueryProtocolException.cs (93%) rename src/TeamSpeak3QueryApi/{ => Query}/QueryResponseDictionary.cs (91%) rename src/TeamSpeak3QueryApi/{Specialized => }/QuerySerializeAttribute.cs (87%) rename src/TeamSpeak3QueryApi/{Specialized => }/Responses/ClientBan.cs (66%) rename src/TeamSpeak3QueryApi/{Specialized => }/Responses/CreatedChannel.cs (67%) rename src/TeamSpeak3QueryApi/{Specialized => }/Responses/EditChannelInfo.cs (97%) rename src/TeamSpeak3QueryApi/{Specialized => }/Responses/FoundChannel.cs (76%) rename src/TeamSpeak3QueryApi/{Specialized => }/Responses/GetChannelInfo.cs (97%) rename src/TeamSpeak3QueryApi/{Specialized => }/Responses/GetChannelListInfo.cs (95%) rename src/TeamSpeak3QueryApi/{Specialized => }/Responses/GetClientDetailedInfo.cs (96%) create mode 100644 src/TeamSpeak3QueryApi/Responses/GetClientInfo.cs rename src/TeamSpeak3QueryApi/{Specialized => }/Responses/GetCurrentFileTransfer.cs (94%) create mode 100644 src/TeamSpeak3QueryApi/Responses/GetDbClientInfo.cs rename src/TeamSpeak3QueryApi/{Specialized => }/Responses/GetFileInfo.cs (85%) rename src/TeamSpeak3QueryApi/{Specialized => }/Responses/GetFiles.cs (87%) rename src/TeamSpeak3QueryApi/{Specialized => }/Responses/GetServerGroup.cs (81%) rename src/TeamSpeak3QueryApi/{Specialized => }/Responses/GetServerGroupClientList.cs (71%) rename src/TeamSpeak3QueryApi/{Specialized => }/Responses/GetServerGroupListInfo.cs (90%) rename src/TeamSpeak3QueryApi/{Specialized => }/Responses/GetServerListInfo.cs (94%) rename src/TeamSpeak3QueryApi/{Specialized => }/Responses/InitDownload.cs (89%) rename src/TeamSpeak3QueryApi/{Specialized => }/Responses/InitUpload.cs (88%) create mode 100644 src/TeamSpeak3QueryApi/Responses/Response.cs rename src/TeamSpeak3QueryApi/{Specialized => }/Responses/WhoAmI.cs (95%) delete mode 100644 src/TeamSpeak3QueryApi/Specialized/Notifications/Notification.cs delete mode 100644 src/TeamSpeak3QueryApi/Specialized/Responses/GetClientInfo.cs delete mode 100644 src/TeamSpeak3QueryApi/Specialized/Responses/Response.cs rename src/TeamSpeak3QueryApi/{Specialized => }/TeamSpeakClient.cs (57%) diff --git a/src/TeamSpeak3QueryApi/Specialized/DataProxy.cs b/src/TeamSpeak3QueryApi/DataProxy.cs similarity index 96% rename from src/TeamSpeak3QueryApi/Specialized/DataProxy.cs rename to src/TeamSpeak3QueryApi/DataProxy.cs index 847827a..63b1f45 100644 --- a/src/TeamSpeak3QueryApi/Specialized/DataProxy.cs +++ b/src/TeamSpeak3QueryApi/DataProxy.cs @@ -4,8 +4,11 @@ using System.Diagnostics; using System.Linq; using System.Reflection; +using TeamSpeak3QueryApi.Net.Enums; +using TeamSpeak3QueryApi.Net.Interfaces; +using TeamSpeak3QueryApi.Net.Query; -namespace TeamSpeak3QueryApi.Net.Specialized +namespace TeamSpeak3QueryApi.Net { internal static class DataProxy { diff --git a/src/TeamSpeak3QueryApi/Specialized/ClientType.cs b/src/TeamSpeak3QueryApi/Enums/ClientType.cs similarity index 65% rename from src/TeamSpeak3QueryApi/Specialized/ClientType.cs rename to src/TeamSpeak3QueryApi/Enums/ClientType.cs index f685ac2..e51f039 100644 --- a/src/TeamSpeak3QueryApi/Specialized/ClientType.cs +++ b/src/TeamSpeak3QueryApi/Enums/ClientType.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Specialized +namespace TeamSpeak3QueryApi.Net.Enums { public enum ClientType { diff --git a/src/TeamSpeak3QueryApi/Specialized/GetChannelOptions.cs b/src/TeamSpeak3QueryApi/Enums/GetChannelOptions.cs similarity index 81% rename from src/TeamSpeak3QueryApi/Specialized/GetChannelOptions.cs rename to src/TeamSpeak3QueryApi/Enums/GetChannelOptions.cs index 6c55f8e..8468b90 100644 --- a/src/TeamSpeak3QueryApi/Specialized/GetChannelOptions.cs +++ b/src/TeamSpeak3QueryApi/Enums/GetChannelOptions.cs @@ -1,6 +1,6 @@ using System; -namespace TeamSpeak3QueryApi.Net.Specialized +namespace TeamSpeak3QueryApi.Net.Enums { [Flags] public enum GetChannelOptions diff --git a/src/TeamSpeak3QueryApi/Specialized/GetClientOptions.cs b/src/TeamSpeak3QueryApi/Enums/GetClientOptions.cs similarity index 85% rename from src/TeamSpeak3QueryApi/Specialized/GetClientOptions.cs rename to src/TeamSpeak3QueryApi/Enums/GetClientOptions.cs index 90ae501..b500d0e 100644 --- a/src/TeamSpeak3QueryApi/Specialized/GetClientOptions.cs +++ b/src/TeamSpeak3QueryApi/Enums/GetClientOptions.cs @@ -1,6 +1,6 @@ using System; -namespace TeamSpeak3QueryApi.Net.Specialized +namespace TeamSpeak3QueryApi.Net.Enums { [Flags] public enum GetClientOptions diff --git a/src/TeamSpeak3QueryApi/Specialized/GetServerOptions.cs b/src/TeamSpeak3QueryApi/Enums/GetServerOptions.cs similarity index 79% rename from src/TeamSpeak3QueryApi/Specialized/GetServerOptions.cs rename to src/TeamSpeak3QueryApi/Enums/GetServerOptions.cs index 72ff8b0..c72cde8 100644 --- a/src/TeamSpeak3QueryApi/Specialized/GetServerOptions.cs +++ b/src/TeamSpeak3QueryApi/Enums/GetServerOptions.cs @@ -1,6 +1,6 @@ using System; -namespace TeamSpeak3QueryApi.Net.Specialized +namespace TeamSpeak3QueryApi.Net.Enums { [Flags] public enum GetServerOptions diff --git a/src/TeamSpeak3QueryApi/Specialized/KickOrigin.cs b/src/TeamSpeak3QueryApi/Enums/KickOrigin.cs similarity index 64% rename from src/TeamSpeak3QueryApi/Specialized/KickOrigin.cs rename to src/TeamSpeak3QueryApi/Enums/KickOrigin.cs index 5779d00..4e626d4 100644 --- a/src/TeamSpeak3QueryApi/Specialized/KickOrigin.cs +++ b/src/TeamSpeak3QueryApi/Enums/KickOrigin.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Specialized +namespace TeamSpeak3QueryApi.Net.Enums { public enum KickOrigin { diff --git a/src/TeamSpeak3QueryApi/ManualEnums.cs b/src/TeamSpeak3QueryApi/Enums/ManualEnums.cs similarity index 98% rename from src/TeamSpeak3QueryApi/ManualEnums.cs rename to src/TeamSpeak3QueryApi/Enums/ManualEnums.cs index 6d92b9a..934038f 100644 --- a/src/TeamSpeak3QueryApi/ManualEnums.cs +++ b/src/TeamSpeak3QueryApi/Enums/ManualEnums.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net +namespace TeamSpeak3QueryApi.Net.Enums { public enum HostMessageMode { diff --git a/src/TeamSpeak3QueryApi/Specialized/MessageTarget.cs b/src/TeamSpeak3QueryApi/Enums/MessageTarget.cs similarity index 70% rename from src/TeamSpeak3QueryApi/Specialized/MessageTarget.cs rename to src/TeamSpeak3QueryApi/Enums/MessageTarget.cs index cd8983c..993d157 100644 --- a/src/TeamSpeak3QueryApi/Specialized/MessageTarget.cs +++ b/src/TeamSpeak3QueryApi/Enums/MessageTarget.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Specialized +namespace TeamSpeak3QueryApi.Net.Enums { public enum MessageTarget { diff --git a/src/TeamSpeak3QueryApi/Specialized/NotificationEventTarget.cs b/src/TeamSpeak3QueryApi/Enums/NotificationEventTarget.cs similarity index 77% rename from src/TeamSpeak3QueryApi/Specialized/NotificationEventTarget.cs rename to src/TeamSpeak3QueryApi/Enums/NotificationEventTarget.cs index 68b6cba..c730746 100644 --- a/src/TeamSpeak3QueryApi/Specialized/NotificationEventTarget.cs +++ b/src/TeamSpeak3QueryApi/Enums/NotificationEventTarget.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Specialized +namespace TeamSpeak3QueryApi.Net.Enums { internal enum NotificationEventTarget { diff --git a/src/TeamSpeak3QueryApi/Specialized/NotificationType.cs b/src/TeamSpeak3QueryApi/Enums/NotificationType.cs similarity index 92% rename from src/TeamSpeak3QueryApi/Specialized/NotificationType.cs rename to src/TeamSpeak3QueryApi/Enums/NotificationType.cs index ae4539c..d6f6de6 100644 --- a/src/TeamSpeak3QueryApi/Specialized/NotificationType.cs +++ b/src/TeamSpeak3QueryApi/Enums/NotificationType.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Specialized +namespace TeamSpeak3QueryApi.Net.Enums { ///http://redeemer.biz/medien/artikel/ts3-query-notify/ public enum NotificationType diff --git a/src/TeamSpeak3QueryApi/Specialized/ReasonId.cs b/src/TeamSpeak3QueryApi/Enums/ReasonId.cs similarity index 86% rename from src/TeamSpeak3QueryApi/Specialized/ReasonId.cs rename to src/TeamSpeak3QueryApi/Enums/ReasonId.cs index b4fdfb5..7e37598 100644 --- a/src/TeamSpeak3QueryApi/Specialized/ReasonId.cs +++ b/src/TeamSpeak3QueryApi/Enums/ReasonId.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Specialized +namespace TeamSpeak3QueryApi.Net.Enums { public enum ReasonId { diff --git a/src/TeamSpeak3QueryApi/Specialized/ServerGroupType.cs b/src/TeamSpeak3QueryApi/Enums/ServerGroupType.cs similarity index 73% rename from src/TeamSpeak3QueryApi/Specialized/ServerGroupType.cs rename to src/TeamSpeak3QueryApi/Enums/ServerGroupType.cs index 175effa..9c03c19 100644 --- a/src/TeamSpeak3QueryApi/Specialized/ServerGroupType.cs +++ b/src/TeamSpeak3QueryApi/Enums/ServerGroupType.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Specialized +namespace TeamSpeak3QueryApi.Net.Enums { public enum ServerGroupType { diff --git a/src/TeamSpeak3QueryApi/Specialized/EnumExtensions.cs b/src/TeamSpeak3QueryApi/Extensions/EnumExtensions.cs similarity index 92% rename from src/TeamSpeak3QueryApi/Specialized/EnumExtensions.cs rename to src/TeamSpeak3QueryApi/Extensions/EnumExtensions.cs index bbae776..10de798 100644 --- a/src/TeamSpeak3QueryApi/Specialized/EnumExtensions.cs +++ b/src/TeamSpeak3QueryApi/Extensions/EnumExtensions.cs @@ -2,7 +2,7 @@ using System.Linq; using System.Collections.Generic; -namespace TeamSpeak3QueryApi.Net.Specialized +namespace TeamSpeak3QueryApi.Net.Extensions { internal static class EnumExtensions { diff --git a/src/TeamSpeak3QueryApi/ListExtensions.cs b/src/TeamSpeak3QueryApi/Extensions/ListExtensions.cs similarity index 84% rename from src/TeamSpeak3QueryApi/ListExtensions.cs rename to src/TeamSpeak3QueryApi/Extensions/ListExtensions.cs index a247d6e..0094c3b 100644 --- a/src/TeamSpeak3QueryApi/ListExtensions.cs +++ b/src/TeamSpeak3QueryApi/Extensions/ListExtensions.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace TeamSpeak3QueryApi.Net +namespace TeamSpeak3QueryApi.Net.Extensions { internal static class ListExtensions { diff --git a/src/TeamSpeak3QueryApi/StringExtensions.cs b/src/TeamSpeak3QueryApi/Extensions/StringExtensions.cs similarity index 97% rename from src/TeamSpeak3QueryApi/StringExtensions.cs rename to src/TeamSpeak3QueryApi/Extensions/StringExtensions.cs index a11db9c..6280f91 100644 --- a/src/TeamSpeak3QueryApi/StringExtensions.cs +++ b/src/TeamSpeak3QueryApi/Extensions/StringExtensions.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net +namespace TeamSpeak3QueryApi.Net.Extensions { internal static class StringExtensions { diff --git a/src/TeamSpeak3QueryApi/TaskExtensions.cs b/src/TeamSpeak3QueryApi/Extensions/TaskExtensions.cs similarity index 95% rename from src/TeamSpeak3QueryApi/TaskExtensions.cs rename to src/TeamSpeak3QueryApi/Extensions/TaskExtensions.cs index efb4544..347723e 100644 --- a/src/TeamSpeak3QueryApi/TaskExtensions.cs +++ b/src/TeamSpeak3QueryApi/Extensions/TaskExtensions.cs @@ -1,7 +1,7 @@ using System.Threading; using System.Threading.Tasks; -namespace TeamSpeak3QueryApi.Net +namespace TeamSpeak3QueryApi.Net.Extensions { internal static class TaskExtensions { diff --git a/src/TeamSpeak3QueryApi/FileTransferClient.cs b/src/TeamSpeak3QueryApi/FileTransfer/FileTransferClient.cs similarity index 82% rename from src/TeamSpeak3QueryApi/FileTransferClient.cs rename to src/TeamSpeak3QueryApi/FileTransfer/FileTransferClient.cs index 18fa8b5..f9569c2 100644 --- a/src/TeamSpeak3QueryApi/FileTransferClient.cs +++ b/src/TeamSpeak3QueryApi/FileTransfer/FileTransferClient.cs @@ -3,7 +3,7 @@ using System.Text; using System.Threading.Tasks; -namespace TeamSpeak3QueryApi.Net +namespace TeamSpeak3QueryApi.Net.FileTransfer { internal class FileTransferClient { @@ -20,43 +20,43 @@ public int GetFileTransferId() return _currentFileTransferId++; } - public async Task SendFile(byte[] data, int port, string key) + public async Task SendFileAsync(byte[] data, int port, string key) { using var client = new TcpClient(); await client.ConnectAsync(_host, port).ConfigureAwait(false); using var ns = client.GetStream(); - // Send key + // SendAsync key var keyBytes = Encoding.ASCII.GetBytes(key); await ns.WriteAsync(keyBytes, 0, keyBytes.Length).ConfigureAwait(false); await ns.FlushAsync().ConfigureAwait(false); - // Send data + // SendAsync data await ns.WriteAsync(data, 0, data.Length).ConfigureAwait(false); } - public async Task SendFile(Stream dataStream, int port, string key) + public async Task SendFileAsync(Stream dataStream, int port, string key) { using var client = new TcpClient(); await client.ConnectAsync(_host, port).ConfigureAwait(false); using var ns = client.GetStream(); - // Send key + // SendAsync key var keyBytes = Encoding.ASCII.GetBytes(key); await ns.WriteAsync(keyBytes, 0, keyBytes.Length).ConfigureAwait(false); await ns.FlushAsync().ConfigureAwait(false); - // Send data + // SendAsync data await dataStream.CopyToAsync(ns).ConfigureAwait(false); } - public async Task ReceiveFile(int size, int port, string key) + public async Task ReceiveFileAsync(int size, int port, string key) { using var client = new TcpClient(); await client.ConnectAsync(_host, port).ConfigureAwait(false); using var ns = client.GetStream(); - // Send key + // SendAsync key var keyBytes = Encoding.ASCII.GetBytes(key); await ns.WriteAsync(keyBytes, 0, keyBytes.Length).ConfigureAwait(false); await ns.FlushAsync().ConfigureAwait(false); diff --git a/src/TeamSpeak3QueryApi/FileTransferException.cs b/src/TeamSpeak3QueryApi/FileTransfer/FileTransferException.cs similarity index 96% rename from src/TeamSpeak3QueryApi/FileTransferException.cs rename to src/TeamSpeak3QueryApi/FileTransfer/FileTransferException.cs index 21ce6e4..00c48b0 100644 --- a/src/TeamSpeak3QueryApi/FileTransferException.cs +++ b/src/TeamSpeak3QueryApi/FileTransfer/FileTransferException.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text; -namespace TeamSpeak3QueryApi.Net +namespace TeamSpeak3QueryApi.Net.FileTransfer { /// Represents errors that occur during file transfers. [Serializable] diff --git a/src/TeamSpeak3QueryApi/Specialized/ITeamSpeakSerializable.cs b/src/TeamSpeak3QueryApi/Interfaces/ITeamSpeakSerializable.cs similarity index 68% rename from src/TeamSpeak3QueryApi/Specialized/ITeamSpeakSerializable.cs rename to src/TeamSpeak3QueryApi/Interfaces/ITeamSpeakSerializable.cs index 2042c29..614e7c6 100644 --- a/src/TeamSpeak3QueryApi/Specialized/ITeamSpeakSerializable.cs +++ b/src/TeamSpeak3QueryApi/Interfaces/ITeamSpeakSerializable.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Specialized +namespace TeamSpeak3QueryApi.Net.Interfaces { interface ITeamSpeakSerializable { diff --git a/src/TeamSpeak3QueryApi/Specialized/ITypeCaster.cs b/src/TeamSpeak3QueryApi/Interfaces/ITypeCaster.cs similarity index 97% rename from src/TeamSpeak3QueryApi/Specialized/ITypeCaster.cs rename to src/TeamSpeak3QueryApi/Interfaces/ITypeCaster.cs index 789acdb..4c6386d 100644 --- a/src/TeamSpeak3QueryApi/Specialized/ITypeCaster.cs +++ b/src/TeamSpeak3QueryApi/Interfaces/ITypeCaster.cs @@ -2,8 +2,9 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; +using TeamSpeak3QueryApi.Net.Extensions; -namespace TeamSpeak3QueryApi.Net.Specialized +namespace TeamSpeak3QueryApi.Net.Interfaces { interface ITypeCaster { diff --git a/src/TeamSpeak3QueryApi/Specialized/Notifications/ChannelCreated.cs b/src/TeamSpeak3QueryApi/Notifications/ChannelCreated.cs similarity index 95% rename from src/TeamSpeak3QueryApi/Specialized/Notifications/ChannelCreated.cs rename to src/TeamSpeak3QueryApi/Notifications/ChannelCreated.cs index 9f1367a..f705f59 100644 --- a/src/TeamSpeak3QueryApi/Specialized/Notifications/ChannelCreated.cs +++ b/src/TeamSpeak3QueryApi/Notifications/ChannelCreated.cs @@ -1,6 +1,7 @@ using System; +using TeamSpeak3QueryApi.Net.Enums; -namespace TeamSpeak3QueryApi.Net.Specialized.Notifications +namespace TeamSpeak3QueryApi.Net.Notifications { public class ChannelCreated : InvokerInformation { diff --git a/src/TeamSpeak3QueryApi/Specialized/Notifications/ChannelDeleted.cs b/src/TeamSpeak3QueryApi/Notifications/ChannelDeleted.cs similarity index 78% rename from src/TeamSpeak3QueryApi/Specialized/Notifications/ChannelDeleted.cs rename to src/TeamSpeak3QueryApi/Notifications/ChannelDeleted.cs index 85f6b64..dadc3f7 100644 --- a/src/TeamSpeak3QueryApi/Specialized/Notifications/ChannelDeleted.cs +++ b/src/TeamSpeak3QueryApi/Notifications/ChannelDeleted.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Specialized.Notifications +namespace TeamSpeak3QueryApi.Net.Notifications { public class ChannelDeleted : InvokerInformation { diff --git a/src/TeamSpeak3QueryApi/Specialized/Notifications/ChannelDescriptionChanged.cs b/src/TeamSpeak3QueryApi/Notifications/ChannelDescriptionChanged.cs similarity index 69% rename from src/TeamSpeak3QueryApi/Specialized/Notifications/ChannelDescriptionChanged.cs rename to src/TeamSpeak3QueryApi/Notifications/ChannelDescriptionChanged.cs index 99e8da8..f127ed6 100644 --- a/src/TeamSpeak3QueryApi/Specialized/Notifications/ChannelDescriptionChanged.cs +++ b/src/TeamSpeak3QueryApi/Notifications/ChannelDescriptionChanged.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Specialized.Notifications +namespace TeamSpeak3QueryApi.Net.Notifications { public class ChannelDescriptionChanged : Notification { diff --git a/src/TeamSpeak3QueryApi/Specialized/Notifications/ChannelEdited.cs b/src/TeamSpeak3QueryApi/Notifications/ChannelEdited.cs similarity index 95% rename from src/TeamSpeak3QueryApi/Specialized/Notifications/ChannelEdited.cs rename to src/TeamSpeak3QueryApi/Notifications/ChannelEdited.cs index ac7d75b..8ea2824 100644 --- a/src/TeamSpeak3QueryApi/Specialized/Notifications/ChannelEdited.cs +++ b/src/TeamSpeak3QueryApi/Notifications/ChannelEdited.cs @@ -1,6 +1,7 @@ using System; +using TeamSpeak3QueryApi.Net.Enums; -namespace TeamSpeak3QueryApi.Net.Specialized.Notifications +namespace TeamSpeak3QueryApi.Net.Notifications { public class ChannelEdited : InvokerInformation { diff --git a/src/TeamSpeak3QueryApi/Specialized/Notifications/ChannelMoved.cs b/src/TeamSpeak3QueryApi/Notifications/ChannelMoved.cs similarity index 81% rename from src/TeamSpeak3QueryApi/Specialized/Notifications/ChannelMoved.cs rename to src/TeamSpeak3QueryApi/Notifications/ChannelMoved.cs index e2bc1ce..ef3b4bd 100644 --- a/src/TeamSpeak3QueryApi/Specialized/Notifications/ChannelMoved.cs +++ b/src/TeamSpeak3QueryApi/Notifications/ChannelMoved.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Specialized.Notifications +namespace TeamSpeak3QueryApi.Net.Notifications { public class ChannelMoved : InvokerInformation { diff --git a/src/TeamSpeak3QueryApi/Specialized/Notifications/ChannelPasswordChanged.cs b/src/TeamSpeak3QueryApi/Notifications/ChannelPasswordChanged.cs similarity index 69% rename from src/TeamSpeak3QueryApi/Specialized/Notifications/ChannelPasswordChanged.cs rename to src/TeamSpeak3QueryApi/Notifications/ChannelPasswordChanged.cs index efd9ae7..a1a0abf 100644 --- a/src/TeamSpeak3QueryApi/Specialized/Notifications/ChannelPasswordChanged.cs +++ b/src/TeamSpeak3QueryApi/Notifications/ChannelPasswordChanged.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Specialized.Notifications +namespace TeamSpeak3QueryApi.Net.Notifications { public class ChannelPasswordChanged : Notification { diff --git a/src/TeamSpeak3QueryApi/Specialized/Notifications/ClientEnterView.cs b/src/TeamSpeak3QueryApi/Notifications/ClientEnterView.cs similarity index 97% rename from src/TeamSpeak3QueryApi/Specialized/Notifications/ClientEnterView.cs rename to src/TeamSpeak3QueryApi/Notifications/ClientEnterView.cs index 0a31352..10fee21 100644 --- a/src/TeamSpeak3QueryApi/Specialized/Notifications/ClientEnterView.cs +++ b/src/TeamSpeak3QueryApi/Notifications/ClientEnterView.cs @@ -1,6 +1,7 @@ using System; +using TeamSpeak3QueryApi.Net.Enums; -namespace TeamSpeak3QueryApi.Net.Specialized.Notifications +namespace TeamSpeak3QueryApi.Net.Notifications { public class ClientEnterView : Notification { diff --git a/src/TeamSpeak3QueryApi/Specialized/Notifications/ClientLeftView.cs b/src/TeamSpeak3QueryApi/Notifications/ClientLeftView.cs similarity index 89% rename from src/TeamSpeak3QueryApi/Specialized/Notifications/ClientLeftView.cs rename to src/TeamSpeak3QueryApi/Notifications/ClientLeftView.cs index 0cdc6a1..b1ccdd4 100644 --- a/src/TeamSpeak3QueryApi/Specialized/Notifications/ClientLeftView.cs +++ b/src/TeamSpeak3QueryApi/Notifications/ClientLeftView.cs @@ -1,6 +1,7 @@ using System; +using TeamSpeak3QueryApi.Net.Enums; -namespace TeamSpeak3QueryApi.Net.Specialized.Notifications +namespace TeamSpeak3QueryApi.Net.Notifications { public class ClientLeftView : Notification { diff --git a/src/TeamSpeak3QueryApi/Specialized/Notifications/ClientMoved.cs b/src/TeamSpeak3QueryApi/Notifications/ClientMoved.cs similarity index 77% rename from src/TeamSpeak3QueryApi/Specialized/Notifications/ClientMoved.cs rename to src/TeamSpeak3QueryApi/Notifications/ClientMoved.cs index 449bedc..0ea7812 100644 --- a/src/TeamSpeak3QueryApi/Specialized/Notifications/ClientMoved.cs +++ b/src/TeamSpeak3QueryApi/Notifications/ClientMoved.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Specialized.Notifications +namespace TeamSpeak3QueryApi.Net.Notifications { public class ClientMoved : InvokerInformation { diff --git a/src/TeamSpeak3QueryApi/Specialized/Notifications/InvokerInformation.cs b/src/TeamSpeak3QueryApi/Notifications/InvokerInformation.cs similarity index 81% rename from src/TeamSpeak3QueryApi/Specialized/Notifications/InvokerInformation.cs rename to src/TeamSpeak3QueryApi/Notifications/InvokerInformation.cs index 7d02567..cce4c0f 100644 --- a/src/TeamSpeak3QueryApi/Specialized/Notifications/InvokerInformation.cs +++ b/src/TeamSpeak3QueryApi/Notifications/InvokerInformation.cs @@ -1,4 +1,6 @@ -namespace TeamSpeak3QueryApi.Net.Specialized.Notifications +using TeamSpeak3QueryApi.Net.Enums; + +namespace TeamSpeak3QueryApi.Net.Notifications { public abstract class InvokerInformation : Notification { diff --git a/src/TeamSpeak3QueryApi/Notifications/Notification.cs b/src/TeamSpeak3QueryApi/Notifications/Notification.cs new file mode 100644 index 0000000..d9fddf5 --- /dev/null +++ b/src/TeamSpeak3QueryApi/Notifications/Notification.cs @@ -0,0 +1,7 @@ +using TeamSpeak3QueryApi.Net.Interfaces; + +namespace TeamSpeak3QueryApi.Net.Notifications +{ + public abstract class Notification : ITeamSpeakSerializable + { } +} diff --git a/src/TeamSpeak3QueryApi/NotificationData.cs b/src/TeamSpeak3QueryApi/Notifications/NotificationData.cs similarity index 89% rename from src/TeamSpeak3QueryApi/NotificationData.cs rename to src/TeamSpeak3QueryApi/Notifications/NotificationData.cs index 9afab69..d05bd22 100644 --- a/src/TeamSpeak3QueryApi/NotificationData.cs +++ b/src/TeamSpeak3QueryApi/Notifications/NotificationData.cs @@ -1,8 +1,9 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; +using TeamSpeak3QueryApi.Net.Query; -namespace TeamSpeak3QueryApi.Net +namespace TeamSpeak3QueryApi.Net.Notifications { /// Provides data that was retrieved by a notification. public class NotificationData diff --git a/src/TeamSpeak3QueryApi/Specialized/Notifications/ServerEdited.cs b/src/TeamSpeak3QueryApi/Notifications/ServerEdited.cs similarity index 96% rename from src/TeamSpeak3QueryApi/Specialized/Notifications/ServerEdited.cs rename to src/TeamSpeak3QueryApi/Notifications/ServerEdited.cs index 190fb18..0371873 100644 --- a/src/TeamSpeak3QueryApi/Specialized/Notifications/ServerEdited.cs +++ b/src/TeamSpeak3QueryApi/Notifications/ServerEdited.cs @@ -1,6 +1,7 @@ using System; +using TeamSpeak3QueryApi.Net.Enums; -namespace TeamSpeak3QueryApi.Net.Specialized.Notifications +namespace TeamSpeak3QueryApi.Net.Notifications { public class ServerEdited : Notification { diff --git a/src/TeamSpeak3QueryApi/Specialized/Notifications/TextMessage.cs b/src/TeamSpeak3QueryApi/Notifications/TextMessage.cs similarity index 80% rename from src/TeamSpeak3QueryApi/Specialized/Notifications/TextMessage.cs rename to src/TeamSpeak3QueryApi/Notifications/TextMessage.cs index 371749c..4a9bd38 100644 --- a/src/TeamSpeak3QueryApi/Specialized/Notifications/TextMessage.cs +++ b/src/TeamSpeak3QueryApi/Notifications/TextMessage.cs @@ -1,4 +1,6 @@ -namespace TeamSpeak3QueryApi.Net.Specialized.Notifications +using TeamSpeak3QueryApi.Net.Enums; + +namespace TeamSpeak3QueryApi.Net.Notifications { public class TextMessage : InvokerInformation { diff --git a/src/TeamSpeak3QueryApi/Specialized/Notifications/TokenUsed.cs b/src/TeamSpeak3QueryApi/Notifications/TokenUsed.cs similarity index 90% rename from src/TeamSpeak3QueryApi/Specialized/Notifications/TokenUsed.cs rename to src/TeamSpeak3QueryApi/Notifications/TokenUsed.cs index 46675d4..26d6d8b 100644 --- a/src/TeamSpeak3QueryApi/Specialized/Notifications/TokenUsed.cs +++ b/src/TeamSpeak3QueryApi/Notifications/TokenUsed.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Specialized.Notifications +namespace TeamSpeak3QueryApi.Net.Notifications { public class TokenUsed : InvokerInformation { diff --git a/src/TeamSpeak3QueryApi/IParameterValue.cs b/src/TeamSpeak3QueryApi/Parameters/IParameterValue.cs similarity index 89% rename from src/TeamSpeak3QueryApi/IParameterValue.cs rename to src/TeamSpeak3QueryApi/Parameters/IParameterValue.cs index 5541fd5..b774ea5 100644 --- a/src/TeamSpeak3QueryApi/IParameterValue.cs +++ b/src/TeamSpeak3QueryApi/Parameters/IParameterValue.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net +namespace TeamSpeak3QueryApi.Net.Parameters { /// Represents an abstraction of a parameter value. public interface IParameterValue diff --git a/src/TeamSpeak3QueryApi/Parameter.cs b/src/TeamSpeak3QueryApi/Parameters/Parameter.cs similarity index 98% rename from src/TeamSpeak3QueryApi/Parameter.cs rename to src/TeamSpeak3QueryApi/Parameters/Parameter.cs index 20c484e..24010f5 100644 --- a/src/TeamSpeak3QueryApi/Parameter.cs +++ b/src/TeamSpeak3QueryApi/Parameters/Parameter.cs @@ -1,7 +1,7 @@ using System; using System.Diagnostics; -namespace TeamSpeak3QueryApi.Net +namespace TeamSpeak3QueryApi.Net.Parameters { /// Represents a Query API parameter. public class Parameter diff --git a/src/TeamSpeak3QueryApi/ParameterValue.cs b/src/TeamSpeak3QueryApi/Parameters/ParameterValue.cs similarity index 97% rename from src/TeamSpeak3QueryApi/ParameterValue.cs rename to src/TeamSpeak3QueryApi/Parameters/ParameterValue.cs index 80fcd8a..09f9c53 100644 --- a/src/TeamSpeak3QueryApi/ParameterValue.cs +++ b/src/TeamSpeak3QueryApi/Parameters/ParameterValue.cs @@ -1,6 +1,7 @@ using System.Globalization; +using TeamSpeak3QueryApi.Net.Extensions; -namespace TeamSpeak3QueryApi.Net +namespace TeamSpeak3QueryApi.Net.Parameters { /// Represents the value of a parameter which consits of a single value. public class ParameterValue : IParameterValue diff --git a/src/TeamSpeak3QueryApi/ParameterValueArray.cs b/src/TeamSpeak3QueryApi/Parameters/ParameterValueArray.cs similarity index 98% rename from src/TeamSpeak3QueryApi/ParameterValueArray.cs rename to src/TeamSpeak3QueryApi/Parameters/ParameterValueArray.cs index e04635e..7b1f1df 100644 --- a/src/TeamSpeak3QueryApi/ParameterValueArray.cs +++ b/src/TeamSpeak3QueryApi/Parameters/ParameterValueArray.cs @@ -1,6 +1,6 @@ using System.Linq; -namespace TeamSpeak3QueryApi.Net +namespace TeamSpeak3QueryApi.Net.Parameters { /// Represents the value of a parameter which consits of a multiple values. public class ParameterValueArray : IParameterValue diff --git a/src/TeamSpeak3QueryApi/QueryClient.cs b/src/TeamSpeak3QueryApi/Query/QueryClient.cs similarity index 91% rename from src/TeamSpeak3QueryApi/QueryClient.cs rename to src/TeamSpeak3QueryApi/Query/QueryClient.cs index f47c778..4a0a47d 100644 --- a/src/TeamSpeak3QueryApi/QueryClient.cs +++ b/src/TeamSpeak3QueryApi/Query/QueryClient.cs @@ -9,12 +9,22 @@ using System.Text; using System.Threading; using System.Threading.Tasks; +using TeamSpeak3QueryApi.Net.Extensions; +using TeamSpeak3QueryApi.Net.Notifications; +using TeamSpeak3QueryApi.Net.Parameters; -namespace TeamSpeak3QueryApi.Net +namespace TeamSpeak3QueryApi.Net.Query { /// Represents a client that can be used to access the TeamSpeak Query API on a remote server. public class QueryClient : IDisposable { + /// + /// Events for handling in the correct moment + /// + public EventHandler OnConnectionLost; + public EventHandler OnConnected; + public EventHandler OnDisconnected; + /// Gets the remote host of the Query API client. /// The remote host of the Query API client. public string Host { get; } @@ -71,7 +81,7 @@ public QueryClient(string hostName, int port) /// Connects to the Query API server. /// An awaitable . - public async Task Connect() + public async Task ConnectAsync() { await Client.ConnectAsync(Host, Port).ConfigureAwait(false); if (!Client.Connected) @@ -82,8 +92,14 @@ public async Task Connect() _writer = new StreamWriter(_ns) { NewLine = "\n" }; IsConnected = true; + OnConnected?.Invoke(this, EventArgs.Empty); - await _reader.ReadLineAsync().ConfigureAwait(false); + + var headline = await _reader.ReadLineAsync().ConfigureAwait(false); + if(headline != "TS3") + { + throw new QueryProtocolException("Telnet Query isn't a valid Teamspeak Query"); + } await _reader.ReadLineAsync().ConfigureAwait(false); // Ignore welcome message await _reader.ReadLineAsync().ConfigureAwait(false); @@ -95,6 +111,7 @@ public void Disconnect() if (_cts == null) return; + OnDisconnected?.Invoke(this, EventArgs.Empty); _cts.Cancel(); } @@ -103,20 +120,20 @@ public void Disconnect() /// Sends a Query API command wihtout parameters to the server. /// The command. /// An awaitable . - public Task Send(string cmd) => Send(cmd, null); + public Task SendAsync(string cmd) => SendAsync(cmd, null); /// Sends a Query API command with parameters to the server. /// The command. /// The parameters of the command. /// An awaitable . - public Task Send(string cmd, params Parameter[] parameters) => Send(cmd, parameters, null); + public Task SendAsync(string cmd, params Parameter[] parameters) => SendAsync(cmd, parameters, null); /// Sends a Query API command with parameters and options to the server. /// The command. /// The parameters of the command. /// The options of the command. /// An awaitable . - public async Task Send(string cmd, Parameter[] parameters, string[] options) + public async Task SendAsync(string cmd, Parameter[] parameters, string[] options) { if (string.IsNullOrWhiteSpace(cmd)) throw new ArgumentNullException(nameof(cmd)); //return Task.Run( () => throw new ArgumentNullException("cmd")); @@ -144,7 +161,7 @@ public async Task Send(string cmd, Parameter[] parame _queue.Enqueue(newItem); - await CheckQueue().ConfigureAwait(false); + await CheckQueueAsync().ConfigureAwait(false); return await d.Task.ConfigureAwait(false); } @@ -276,6 +293,9 @@ private static QueryError ParseError(string errorString) case "FAILED_PERMID": parsedError.FailedPermissionId = errData.Length > 1 ? int.Parse(errData[1], NumberStyles.AllowLeadingWhite | NumberStyles.AllowTrailingWhite, CultureInfo.CurrentCulture) : -1; continue; + case "EXTRA_MSG": + parsedError.ExtraMessage = errData.Length > 1 ? errData[1].TeamSpeakUnescape() : null; + continue; default: throw new QueryProtocolException(); } @@ -369,6 +389,7 @@ private CancellationTokenSource ResponseProcessingLoop() continue; var s = line.Trim(); + if (s.StartsWith("error", StringComparison.OrdinalIgnoreCase)) { Debug.Assert(_currentCommand != null); @@ -392,12 +413,15 @@ private CancellationTokenSource ResponseProcessingLoop() } IsConnected = false; + OnConnectionLost?.Invoke(this, EventArgs.Empty); + OnDisconnected?.Invoke(this, EventArgs.Empty); + }); return cts; } private QueryCommand _currentCommand; - private async Task CheckQueue() + private async Task CheckQueueAsync() { if (_queue.Count > 0) { diff --git a/src/TeamSpeak3QueryApi/QueryCommand.cs b/src/TeamSpeak3QueryApi/Query/QueryCommand.cs similarity index 91% rename from src/TeamSpeak3QueryApi/QueryCommand.cs rename to src/TeamSpeak3QueryApi/Query/QueryCommand.cs index aae8ac9..8e770fd 100644 --- a/src/TeamSpeak3QueryApi/QueryCommand.cs +++ b/src/TeamSpeak3QueryApi/Query/QueryCommand.cs @@ -1,7 +1,8 @@ using System.Collections.Generic; using System.Threading.Tasks; +using TeamSpeak3QueryApi.Net.Parameters; -namespace TeamSpeak3QueryApi.Net +namespace TeamSpeak3QueryApi.Net.Query { internal class QueryCommand { diff --git a/src/TeamSpeak3QueryApi/QueryError.cs b/src/TeamSpeak3QueryApi/Query/QueryError.cs similarity index 80% rename from src/TeamSpeak3QueryApi/QueryError.cs rename to src/TeamSpeak3QueryApi/Query/QueryError.cs index 069f90d..c5a0637 100644 --- a/src/TeamSpeak3QueryApi/QueryError.cs +++ b/src/TeamSpeak3QueryApi/Query/QueryError.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net +namespace TeamSpeak3QueryApi.Net.Query { /// Represents a query error that comes with every API response. public class QueryError @@ -11,6 +11,10 @@ public class QueryError /// The error message. public string Message { get; internal set; } + /// The extra error message. Is only set if there is an extra error message. + /// The error message. + public string ExtraMessage { get; internal set; } + /// If the cause of the error was a missing permission, this property represents the ID of the permission the client does not have. A value of 0 means that there was no permission error. /// The ID of the missing permission. If there is none, 0. /// Check the of the to determine if there was a permission error. diff --git a/src/TeamSpeak3QueryApi/QueryException.cs b/src/TeamSpeak3QueryApi/Query/QueryException.cs similarity index 94% rename from src/TeamSpeak3QueryApi/QueryException.cs rename to src/TeamSpeak3QueryApi/Query/QueryException.cs index 188ee10..5719fef 100644 --- a/src/TeamSpeak3QueryApi/QueryException.cs +++ b/src/TeamSpeak3QueryApi/Query/QueryException.cs @@ -1,7 +1,7 @@ using System; using System.Runtime.Serialization; -namespace TeamSpeak3QueryApi.Net +namespace TeamSpeak3QueryApi.Net.Query { /// Represents errors that occur during query execution. [Serializable] @@ -27,7 +27,7 @@ public QueryException(string message, Exception innerException) /// Initializes a new instance of the class with a specified error returned by the Query API. /// The that was returned by the Query API. public QueryException(QueryError error) - : this("An error occurred during the query.") + : this("An error occurred during the teamspeak query.") { Error = error; } diff --git a/src/TeamSpeak3QueryApi/QueryNotification.cs b/src/TeamSpeak3QueryApi/Query/QueryNotification.cs similarity index 80% rename from src/TeamSpeak3QueryApi/QueryNotification.cs rename to src/TeamSpeak3QueryApi/Query/QueryNotification.cs index 5d3cd7e..7d641dd 100644 --- a/src/TeamSpeak3QueryApi/QueryNotification.cs +++ b/src/TeamSpeak3QueryApi/Query/QueryNotification.cs @@ -1,6 +1,7 @@ using System.Diagnostics; +using TeamSpeak3QueryApi.Net.Notifications; -namespace TeamSpeak3QueryApi.Net +namespace TeamSpeak3QueryApi.Net.Query { internal class QueryNotification { diff --git a/src/TeamSpeak3QueryApi/QueryProtocolException.cs b/src/TeamSpeak3QueryApi/Query/QueryProtocolException.cs similarity index 93% rename from src/TeamSpeak3QueryApi/QueryProtocolException.cs rename to src/TeamSpeak3QueryApi/Query/QueryProtocolException.cs index 23c081a..ec76b1c 100644 --- a/src/TeamSpeak3QueryApi/QueryProtocolException.cs +++ b/src/TeamSpeak3QueryApi/Query/QueryProtocolException.cs @@ -1,7 +1,7 @@ using System; using System.Runtime.Serialization; -namespace TeamSpeak3QueryApi.Net +namespace TeamSpeak3QueryApi.Net.Query { /// Represents errors that occur during queries caused by protcol violations. [Serializable] @@ -9,7 +9,7 @@ public class QueryProtocolException : Exception { /// Initializes a new instance of the class. public QueryProtocolException() - : this("An error occurred during the query.") + : this("An error occurred during the teamspeak query.") { } /// Initializes a new instance of the class with a specified error message. diff --git a/src/TeamSpeak3QueryApi/QueryResponseDictionary.cs b/src/TeamSpeak3QueryApi/Query/QueryResponseDictionary.cs similarity index 91% rename from src/TeamSpeak3QueryApi/QueryResponseDictionary.cs rename to src/TeamSpeak3QueryApi/Query/QueryResponseDictionary.cs index 8aae0b8..36b4a8c 100644 --- a/src/TeamSpeak3QueryApi/QueryResponseDictionary.cs +++ b/src/TeamSpeak3QueryApi/Query/QueryResponseDictionary.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Runtime.Serialization; -namespace TeamSpeak3QueryApi.Net +namespace TeamSpeak3QueryApi.Net.Query { /// Represents the data of a query response. [Serializable] diff --git a/src/TeamSpeak3QueryApi/Specialized/QuerySerializeAttribute.cs b/src/TeamSpeak3QueryApi/QuerySerializeAttribute.cs similarity index 87% rename from src/TeamSpeak3QueryApi/Specialized/QuerySerializeAttribute.cs rename to src/TeamSpeak3QueryApi/QuerySerializeAttribute.cs index 006711d..f52f917 100644 --- a/src/TeamSpeak3QueryApi/Specialized/QuerySerializeAttribute.cs +++ b/src/TeamSpeak3QueryApi/QuerySerializeAttribute.cs @@ -1,6 +1,6 @@ using System; -namespace TeamSpeak3QueryApi.Net.Specialized +namespace TeamSpeak3QueryApi.Net { [AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)] class QuerySerializeAttribute : Attribute diff --git a/src/TeamSpeak3QueryApi/Specialized/Responses/ClientBan.cs b/src/TeamSpeak3QueryApi/Responses/ClientBan.cs similarity index 66% rename from src/TeamSpeak3QueryApi/Specialized/Responses/ClientBan.cs rename to src/TeamSpeak3QueryApi/Responses/ClientBan.cs index 491c9fb..71bb8d5 100644 --- a/src/TeamSpeak3QueryApi/Specialized/Responses/ClientBan.cs +++ b/src/TeamSpeak3QueryApi/Responses/ClientBan.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Specialized.Responses +namespace TeamSpeak3QueryApi.Net.Responses { public class ClientBan : Response { diff --git a/src/TeamSpeak3QueryApi/Specialized/Responses/CreatedChannel.cs b/src/TeamSpeak3QueryApi/Responses/CreatedChannel.cs similarity index 67% rename from src/TeamSpeak3QueryApi/Specialized/Responses/CreatedChannel.cs rename to src/TeamSpeak3QueryApi/Responses/CreatedChannel.cs index b2b3c23..a8bb4de 100644 --- a/src/TeamSpeak3QueryApi/Specialized/Responses/CreatedChannel.cs +++ b/src/TeamSpeak3QueryApi/Responses/CreatedChannel.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Specialized.Responses +namespace TeamSpeak3QueryApi.Net.Responses { public class CreatedChannel : Response { diff --git a/src/TeamSpeak3QueryApi/Specialized/Responses/EditChannelInfo.cs b/src/TeamSpeak3QueryApi/Responses/EditChannelInfo.cs similarity index 97% rename from src/TeamSpeak3QueryApi/Specialized/Responses/EditChannelInfo.cs rename to src/TeamSpeak3QueryApi/Responses/EditChannelInfo.cs index e8bcae2..7b254f1 100644 --- a/src/TeamSpeak3QueryApi/Specialized/Responses/EditChannelInfo.cs +++ b/src/TeamSpeak3QueryApi/Responses/EditChannelInfo.cs @@ -1,6 +1,7 @@ using System; +using TeamSpeak3QueryApi.Net.Enums; -namespace TeamSpeak3QueryApi.Net.Specialized.Responses +namespace TeamSpeak3QueryApi.Net.Responses { public class EditChannelInfo : Response { diff --git a/src/TeamSpeak3QueryApi/Specialized/Responses/FoundChannel.cs b/src/TeamSpeak3QueryApi/Responses/FoundChannel.cs similarity index 76% rename from src/TeamSpeak3QueryApi/Specialized/Responses/FoundChannel.cs rename to src/TeamSpeak3QueryApi/Responses/FoundChannel.cs index a2c08b3..b4ad866 100644 --- a/src/TeamSpeak3QueryApi/Specialized/Responses/FoundChannel.cs +++ b/src/TeamSpeak3QueryApi/Responses/FoundChannel.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Specialized.Responses +namespace TeamSpeak3QueryApi.Net.Responses { public class FoundChannel : Response { diff --git a/src/TeamSpeak3QueryApi/Specialized/Responses/GetChannelInfo.cs b/src/TeamSpeak3QueryApi/Responses/GetChannelInfo.cs similarity index 97% rename from src/TeamSpeak3QueryApi/Specialized/Responses/GetChannelInfo.cs rename to src/TeamSpeak3QueryApi/Responses/GetChannelInfo.cs index dcd3633..5fe4ace 100644 --- a/src/TeamSpeak3QueryApi/Specialized/Responses/GetChannelInfo.cs +++ b/src/TeamSpeak3QueryApi/Responses/GetChannelInfo.cs @@ -1,6 +1,7 @@ using System; +using TeamSpeak3QueryApi.Net.Enums; -namespace TeamSpeak3QueryApi.Net.Specialized.Responses +namespace TeamSpeak3QueryApi.Net.Responses { public class GetChannelInfo : Response { diff --git a/src/TeamSpeak3QueryApi/Specialized/Responses/GetChannelListInfo.cs b/src/TeamSpeak3QueryApi/Responses/GetChannelListInfo.cs similarity index 95% rename from src/TeamSpeak3QueryApi/Specialized/Responses/GetChannelListInfo.cs rename to src/TeamSpeak3QueryApi/Responses/GetChannelListInfo.cs index f3518ba..06a921f 100644 --- a/src/TeamSpeak3QueryApi/Specialized/Responses/GetChannelListInfo.cs +++ b/src/TeamSpeak3QueryApi/Responses/GetChannelListInfo.cs @@ -1,6 +1,7 @@ using System; +using TeamSpeak3QueryApi.Net.Enums; -namespace TeamSpeak3QueryApi.Net.Specialized.Responses +namespace TeamSpeak3QueryApi.Net.Responses { public class GetChannelListInfo : Response { diff --git a/src/TeamSpeak3QueryApi/Specialized/Responses/GetClientDetailedInfo.cs b/src/TeamSpeak3QueryApi/Responses/GetClientDetailedInfo.cs similarity index 96% rename from src/TeamSpeak3QueryApi/Specialized/Responses/GetClientDetailedInfo.cs rename to src/TeamSpeak3QueryApi/Responses/GetClientDetailedInfo.cs index 20c2d6a..29c14fe 100644 --- a/src/TeamSpeak3QueryApi/Specialized/Responses/GetClientDetailedInfo.cs +++ b/src/TeamSpeak3QueryApi/Responses/GetClientDetailedInfo.cs @@ -1,8 +1,9 @@ using System; using System.Collections.Generic; using System.Linq; +using TeamSpeak3QueryApi.Net.Enums; -namespace TeamSpeak3QueryApi.Net.Specialized.Responses +namespace TeamSpeak3QueryApi.Net.Responses { public class GetClientDetailedInfo : Response { diff --git a/src/TeamSpeak3QueryApi/Responses/GetClientInfo.cs b/src/TeamSpeak3QueryApi/Responses/GetClientInfo.cs new file mode 100644 index 0000000..9afef25 --- /dev/null +++ b/src/TeamSpeak3QueryApi/Responses/GetClientInfo.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using TeamSpeak3QueryApi.Net.Enums; + +namespace TeamSpeak3QueryApi.Net.Responses +{ + public class GetClientInfo : Response + { + [QuerySerialize("clid")] + public int Id; + + [QuerySerialize("cid")] + public int ChannelId; + + [QuerySerialize("client_database_id")] + public int DatabaseId; + + [QuerySerialize("client_nickname")] + public string NickName; + + [QuerySerialize("client_type")] + public ClientType Type; + + [QuerySerialize("client_unique_identifier")] + public string UniqueIdentifier; + + [QuerySerialize("client_version")] + public string Version; + + [QuerySerialize("client_platform")] + public string Plattform; + + [QuerySerialize("client_input_muted")] + public bool InputMuted; + + [QuerySerialize("client_output_muted")] + public bool OutputMuted; + + [QuerySerialize("client_is_recording")] + public bool IsRecording; + + [QuerySerialize("client_servergroups")] + public IReadOnlyList ServerGroupIds; + + [QuerySerialize("client_channel_group_id")] + public IReadOnlyList ChannelGroupsIds; + + [QuerySerialize("client_created")] + public DateTime Created; + + [QuerySerialize("client_lastconnected")] + public DateTime LastConnected; + + [QuerySerialize("client_away")] + public bool Away; + + [QuerySerialize("client_away_message")] + public string AwayMessage; + + [QuerySerialize("client_idle_time")] + private long _idleTime; //Because it is in ms instead if s defined in Typecaster + public TimeSpan IdleTime => TimeSpan.FromMilliseconds(_idleTime); + } +} diff --git a/src/TeamSpeak3QueryApi/Specialized/Responses/GetCurrentFileTransfer.cs b/src/TeamSpeak3QueryApi/Responses/GetCurrentFileTransfer.cs similarity index 94% rename from src/TeamSpeak3QueryApi/Specialized/Responses/GetCurrentFileTransfer.cs rename to src/TeamSpeak3QueryApi/Responses/GetCurrentFileTransfer.cs index 9dfbd39..b1e3aad 100644 --- a/src/TeamSpeak3QueryApi/Specialized/Responses/GetCurrentFileTransfer.cs +++ b/src/TeamSpeak3QueryApi/Responses/GetCurrentFileTransfer.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text; -namespace TeamSpeak3QueryApi.Net.Specialized.Responses +namespace TeamSpeak3QueryApi.Net.Responses { public class GetCurrentFileTransfer : Response { diff --git a/src/TeamSpeak3QueryApi/Responses/GetDbClientInfo.cs b/src/TeamSpeak3QueryApi/Responses/GetDbClientInfo.cs new file mode 100644 index 0000000..94c6596 --- /dev/null +++ b/src/TeamSpeak3QueryApi/Responses/GetDbClientInfo.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; + +namespace TeamSpeak3QueryApi.Net.Responses +{ + public class GetDbClientInfo : Response + { + [QuerySerialize("cldbid")] + public int DatabaseId; + + [QuerySerialize("client_nickname")] + public string NickName; + + [QuerySerialize("client_unique_identifier")] + public string UniqueIdentifier; + + [QuerySerialize("client_created")] + public DateTime Created; + + [QuerySerialize("client_lastconnected")] + public DateTime LastConnected; + + [QuerySerialize("client_totalconnections")] + public int TotalConnectionCount; + + [QuerySerialize("client_description")] + public string Description; + + [QuerySerialize("client_login_name")] + public string LoginName; + + [QuerySerialize("client_lastip")] + public string LastConnectionIp; + } +} diff --git a/src/TeamSpeak3QueryApi/Specialized/Responses/GetFileInfo.cs b/src/TeamSpeak3QueryApi/Responses/GetFileInfo.cs similarity index 85% rename from src/TeamSpeak3QueryApi/Specialized/Responses/GetFileInfo.cs rename to src/TeamSpeak3QueryApi/Responses/GetFileInfo.cs index 45f0709..216f182 100644 --- a/src/TeamSpeak3QueryApi/Specialized/Responses/GetFileInfo.cs +++ b/src/TeamSpeak3QueryApi/Responses/GetFileInfo.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text; -namespace TeamSpeak3QueryApi.Net.Specialized.Responses +namespace TeamSpeak3QueryApi.Net.Responses { public class GetFileInfo : Response { diff --git a/src/TeamSpeak3QueryApi/Specialized/Responses/GetFiles.cs b/src/TeamSpeak3QueryApi/Responses/GetFiles.cs similarity index 87% rename from src/TeamSpeak3QueryApi/Specialized/Responses/GetFiles.cs rename to src/TeamSpeak3QueryApi/Responses/GetFiles.cs index 773797e..83674ea 100644 --- a/src/TeamSpeak3QueryApi/Specialized/Responses/GetFiles.cs +++ b/src/TeamSpeak3QueryApi/Responses/GetFiles.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text; -namespace TeamSpeak3QueryApi.Net.Specialized.Responses +namespace TeamSpeak3QueryApi.Net.Responses { public class GetFiles : Response { diff --git a/src/TeamSpeak3QueryApi/Specialized/Responses/GetServerGroup.cs b/src/TeamSpeak3QueryApi/Responses/GetServerGroup.cs similarity index 81% rename from src/TeamSpeak3QueryApi/Specialized/Responses/GetServerGroup.cs rename to src/TeamSpeak3QueryApi/Responses/GetServerGroup.cs index 2774918..6938475 100644 --- a/src/TeamSpeak3QueryApi/Specialized/Responses/GetServerGroup.cs +++ b/src/TeamSpeak3QueryApi/Responses/GetServerGroup.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Specialized.Responses +namespace TeamSpeak3QueryApi.Net.Responses { public class GetServerGroup : Response { diff --git a/src/TeamSpeak3QueryApi/Specialized/Responses/GetServerGroupClientList.cs b/src/TeamSpeak3QueryApi/Responses/GetServerGroupClientList.cs similarity index 71% rename from src/TeamSpeak3QueryApi/Specialized/Responses/GetServerGroupClientList.cs rename to src/TeamSpeak3QueryApi/Responses/GetServerGroupClientList.cs index f987ff9..4bc1f4f 100644 --- a/src/TeamSpeak3QueryApi/Specialized/Responses/GetServerGroupClientList.cs +++ b/src/TeamSpeak3QueryApi/Responses/GetServerGroupClientList.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Specialized.Responses +namespace TeamSpeak3QueryApi.Net.Responses { public class GetServerGroupClientList : Response { diff --git a/src/TeamSpeak3QueryApi/Specialized/Responses/GetServerGroupListInfo.cs b/src/TeamSpeak3QueryApi/Responses/GetServerGroupListInfo.cs similarity index 90% rename from src/TeamSpeak3QueryApi/Specialized/Responses/GetServerGroupListInfo.cs rename to src/TeamSpeak3QueryApi/Responses/GetServerGroupListInfo.cs index f92f58a..17151bc 100644 --- a/src/TeamSpeak3QueryApi/Specialized/Responses/GetServerGroupListInfo.cs +++ b/src/TeamSpeak3QueryApi/Responses/GetServerGroupListInfo.cs @@ -1,4 +1,6 @@ -namespace TeamSpeak3QueryApi.Net.Specialized.Responses +using TeamSpeak3QueryApi.Net.Enums; + +namespace TeamSpeak3QueryApi.Net.Responses { public class GetServerGroupListInfo : Response { diff --git a/src/TeamSpeak3QueryApi/Specialized/Responses/GetServerListInfo.cs b/src/TeamSpeak3QueryApi/Responses/GetServerListInfo.cs similarity index 94% rename from src/TeamSpeak3QueryApi/Specialized/Responses/GetServerListInfo.cs rename to src/TeamSpeak3QueryApi/Responses/GetServerListInfo.cs index 0d01187..7cb3998 100644 --- a/src/TeamSpeak3QueryApi/Specialized/Responses/GetServerListInfo.cs +++ b/src/TeamSpeak3QueryApi/Responses/GetServerListInfo.cs @@ -1,6 +1,6 @@ using System; -namespace TeamSpeak3QueryApi.Net.Specialized.Responses +namespace TeamSpeak3QueryApi.Net.Responses { public class GetServerListInfo : Response { diff --git a/src/TeamSpeak3QueryApi/Specialized/Responses/InitDownload.cs b/src/TeamSpeak3QueryApi/Responses/InitDownload.cs similarity index 89% rename from src/TeamSpeak3QueryApi/Specialized/Responses/InitDownload.cs rename to src/TeamSpeak3QueryApi/Responses/InitDownload.cs index 624f805..dd80c92 100644 --- a/src/TeamSpeak3QueryApi/Specialized/Responses/InitDownload.cs +++ b/src/TeamSpeak3QueryApi/Responses/InitDownload.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text; -namespace TeamSpeak3QueryApi.Net.Specialized.Responses +namespace TeamSpeak3QueryApi.Net.Responses { public class InitDownload : Response { diff --git a/src/TeamSpeak3QueryApi/Specialized/Responses/InitUpload.cs b/src/TeamSpeak3QueryApi/Responses/InitUpload.cs similarity index 88% rename from src/TeamSpeak3QueryApi/Specialized/Responses/InitUpload.cs rename to src/TeamSpeak3QueryApi/Responses/InitUpload.cs index 092396e..7dcaed6 100644 --- a/src/TeamSpeak3QueryApi/Specialized/Responses/InitUpload.cs +++ b/src/TeamSpeak3QueryApi/Responses/InitUpload.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text; -namespace TeamSpeak3QueryApi.Net.Specialized.Responses +namespace TeamSpeak3QueryApi.Net.Responses { public class InitUpload : Response { diff --git a/src/TeamSpeak3QueryApi/Responses/Response.cs b/src/TeamSpeak3QueryApi/Responses/Response.cs new file mode 100644 index 0000000..eb0354a --- /dev/null +++ b/src/TeamSpeak3QueryApi/Responses/Response.cs @@ -0,0 +1,7 @@ +using TeamSpeak3QueryApi.Net.Interfaces; + +namespace TeamSpeak3QueryApi.Net.Responses +{ + public abstract class Response : ITeamSpeakSerializable + { } +} diff --git a/src/TeamSpeak3QueryApi/Specialized/Responses/WhoAmI.cs b/src/TeamSpeak3QueryApi/Responses/WhoAmI.cs similarity index 95% rename from src/TeamSpeak3QueryApi/Specialized/Responses/WhoAmI.cs rename to src/TeamSpeak3QueryApi/Responses/WhoAmI.cs index 1e0d0c7..64804ba 100644 --- a/src/TeamSpeak3QueryApi/Specialized/Responses/WhoAmI.cs +++ b/src/TeamSpeak3QueryApi/Responses/WhoAmI.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Specialized.Responses +namespace TeamSpeak3QueryApi.Net.Responses { public class WhoAmI : Response { diff --git a/src/TeamSpeak3QueryApi/Specialized/Notifications/Notification.cs b/src/TeamSpeak3QueryApi/Specialized/Notifications/Notification.cs deleted file mode 100644 index 5844791..0000000 --- a/src/TeamSpeak3QueryApi/Specialized/Notifications/Notification.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace TeamSpeak3QueryApi.Net.Specialized.Notifications -{ - public abstract class Notification : ITeamSpeakSerializable - { } -} diff --git a/src/TeamSpeak3QueryApi/Specialized/Responses/GetClientInfo.cs b/src/TeamSpeak3QueryApi/Specialized/Responses/GetClientInfo.cs deleted file mode 100644 index 40acc11..0000000 --- a/src/TeamSpeak3QueryApi/Specialized/Responses/GetClientInfo.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace TeamSpeak3QueryApi.Net.Specialized.Responses -{ - public class GetClientInfo : Response - { - [QuerySerialize("clid")] - public int Id; - - [QuerySerialize("cid")] - public int ChannelId; - - [QuerySerialize("client_database_id")] - public int DatabaseId; - - [QuerySerialize("client_nickname")] - public string NickName; - - [QuerySerialize("client_type")] - public ClientType Type; - } -} diff --git a/src/TeamSpeak3QueryApi/Specialized/Responses/Response.cs b/src/TeamSpeak3QueryApi/Specialized/Responses/Response.cs deleted file mode 100644 index 587cd21..0000000 --- a/src/TeamSpeak3QueryApi/Specialized/Responses/Response.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace TeamSpeak3QueryApi.Net.Specialized.Responses -{ - public abstract class Response : ITeamSpeakSerializable - { } -} diff --git a/src/TeamSpeak3QueryApi/TeamSpeak3QueryApi.csproj b/src/TeamSpeak3QueryApi/TeamSpeak3QueryApi.csproj index 3e01ff1..eb2b2ad 100644 --- a/src/TeamSpeak3QueryApi/TeamSpeak3QueryApi.csproj +++ b/src/TeamSpeak3QueryApi/TeamSpeak3QueryApi.csproj @@ -25,9 +25,13 @@ - + + + + + diff --git a/src/TeamSpeak3QueryApi/Specialized/TeamSpeakClient.cs b/src/TeamSpeak3QueryApi/TeamSpeakClient.cs similarity index 57% rename from src/TeamSpeak3QueryApi/Specialized/TeamSpeakClient.cs rename to src/TeamSpeak3QueryApi/TeamSpeakClient.cs index f57e000..c6947b4 100644 --- a/src/TeamSpeak3QueryApi/Specialized/TeamSpeakClient.cs +++ b/src/TeamSpeak3QueryApi/TeamSpeakClient.cs @@ -6,10 +6,15 @@ using System.Linq; using System.Text.RegularExpressions; using System.Threading.Tasks; -using TeamSpeak3QueryApi.Net.Specialized.Notifications; -using TeamSpeak3QueryApi.Net.Specialized.Responses; - -namespace TeamSpeak3QueryApi.Net.Specialized +using TeamSpeak3QueryApi.Net.FileTransfer; +using TeamSpeak3QueryApi.Net.Parameters; +using TeamSpeak3QueryApi.Net.Query; +using TeamSpeak3QueryApi.Net.Responses; +using TeamSpeak3QueryApi.Net.Enums; +using TeamSpeak3QueryApi.Net.Notifications; +using TeamSpeak3QueryApi.Net.Extensions; + +namespace TeamSpeak3QueryApi.Net { public class TeamSpeakClient : IDisposable { @@ -44,7 +49,7 @@ public TeamSpeakClient(string hostName, int port) #endregion - public Task Connect() => Client.Connect(); + public Task Connect() => Client.ConnectAsync(); #region Subscriptions @@ -85,38 +90,39 @@ private static NotificationType GetNotificationType() #endregion #region Implented api methods - public Task Login(string userName, string password) + public Task LoginAsync(string userName, string password) { - return Client.Send("login", new Parameter("client_login_name", userName), new Parameter("client_login_password", password)); + return Client.SendAsync("login", new Parameter("client_login_name", userName), new Parameter("client_login_password", password)); } - public Task Logout() => Client.Send("logout"); + public Task LogoutAsync() => Client.SendAsync("logout"); - public Task UseServer(int serverId) + public Task UseServerAsync(int serverId) { - return Client.Send("use", new Parameter("sid", serverId.ToString(CultureInfo.InvariantCulture))); + return Client.SendAsync("use", new Parameter("sid", serverId.ToString(CultureInfo.InvariantCulture))); } - public async Task WhoAmI() + public async Task WhoAmIAsync() { - var res = await Client.Send("whoami").ConfigureAwait(false); + var res = await Client.SendAsync("whoami").ConfigureAwait(false); var proxied = DataProxy.SerializeGeneric(res); return proxied.FirstOrDefault(); } #region Notification Methods - public Task RegisterChannelNotification(int channelId) => RegisterNotification(NotificationEventTarget.Channel, channelId); - public Task RegisterServerNotification() => RegisterNotification(NotificationEventTarget.Server, -1); - public Task RegisterTextServerNotification() => RegisterNotification(NotificationEventTarget.TextServer, -1); - public Task RegisterTextChannelNotification() => RegisterNotification(NotificationEventTarget.TextChannel, -1); - public Task RegisterTextPrivateNotification() => RegisterNotification(NotificationEventTarget.TextPrivate, -1); - private Task RegisterNotification(NotificationEventTarget target, int channelId) + public Task RegisterChannelNotificationAsync(int channelId) => RegisterNotificationAsync(NotificationEventTarget.Channel, channelId); + public Task RegisterAllChannelNotificationAsync() => RegisterNotificationAsync(NotificationEventTarget.Channel, 0); + public Task RegisterServerNotificationAsync() => RegisterNotificationAsync(NotificationEventTarget.Server, -1); + public Task RegisterTextServerNotificationAsync() => RegisterNotificationAsync(NotificationEventTarget.TextServer, -1); + public Task RegisterTextChannelNotificationAsync() => RegisterNotificationAsync(NotificationEventTarget.TextChannel, -1); + public Task RegisterTextPrivateNotificationAsync() => RegisterNotificationAsync(NotificationEventTarget.TextPrivate, -1); + private Task RegisterNotificationAsync(NotificationEventTarget target, int channelId) { var ev = new Parameter("event", target.ToString().ToLowerInvariant()); if (target == NotificationEventTarget.Channel) - return Client.Send("servernotifyregister", ev, new Parameter("id", channelId)); - return Client.Send("servernotifyregister", ev); + return Client.SendAsync("servernotifyregister", ev, new Parameter("id", channelId)); + return Client.SendAsync("servernotifyregister", ev); } #endregion @@ -125,29 +131,29 @@ private Task RegisterNotification(NotificationEventTarget target, int channelId) #region MoveClient - public Task MoveClient(int clientId, int targetChannelId) => MoveClient(new[] { clientId }, targetChannelId); - public Task MoveClient(int clientId, int targetChannelId, string channelPassword) => MoveClient(new[] { clientId }, targetChannelId, channelPassword); + public Task MoveClientAsync(int clientId, int targetChannelId) => MoveClientAsync(new[] { clientId }, targetChannelId); + public Task MoveClientAsync(int clientId, int targetChannelId, string channelPassword) => MoveClientAsync(new[] { clientId }, targetChannelId, channelPassword); - public Task MoveClient(IEnumerable clients, int targetChannelId) + public Task MoveClientAsync(IEnumerable clients, int targetChannelId) { var clIds = clients.Select(c => c.Id).ToArray(); - return MoveClient(clIds, targetChannelId); + return MoveClientAsync(clIds, targetChannelId); } - public Task MoveClient(IEnumerable clients, int targetChannelId, string channelPassword) + public Task MoveClientAsync(IEnumerable clients, int targetChannelId, string channelPassword) { var clIds = clients.Select(c => c.Id).ToArray(); - return MoveClient(clIds, targetChannelId, channelPassword); + return MoveClientAsync(clIds, targetChannelId, channelPassword); } - public Task MoveClient(IList clientIds, int targetChannelId) + public Task MoveClientAsync(IList clientIds, int targetChannelId) { - return Client.Send("clientmove", + return Client.SendAsync("clientmove", new Parameter("clid", clientIds.Select(i => new ParameterValue(i)).ToArray()), new Parameter("cid", targetChannelId)); } - public Task MoveClient(IList clientIds, int targetChannelId, string channelPassword) + public Task MoveClientAsync(IList clientIds, int targetChannelId, string channelPassword) { - return Client.Send("clientmove", + return Client.SendAsync("clientmove", new Parameter("clid", clientIds.Select(i => new ParameterValue(i)).ToArray()), new Parameter("cid", targetChannelId), new Parameter("cpw", channelPassword)); @@ -156,23 +162,23 @@ public Task MoveClient(IList clientIds, int targetChannelId, string channel #endregion #region KickClient - public Task KickClient(int clientId, KickOrigin from) => KickClient(new[] { clientId }, from); - public Task KickClient(int clientId, KickOrigin from, string reasonMessage) => KickClient(new[] { clientId }, from, reasonMessage); - public Task KickClient(GetClientInfo client, KickOrigin from) => KickClient(client.Id, from); - public Task KickClient(IEnumerable clients, KickOrigin from) + public Task KickClientAsync(int clientId, KickOrigin from) => KickClientAsync(new[] { clientId }, from); + public Task KickClientAsync(int clientId, KickOrigin from, string reasonMessage) => KickClientAsync(new[] { clientId }, from, reasonMessage); + public Task KickClientAsync(GetClientInfo client, KickOrigin from) => KickClientAsync(client.Id, from); + public Task KickClientAsync(IEnumerable clients, KickOrigin from, string v) { var clIds = clients.Select(c => c.Id).ToArray(); - return KickClient(clIds, from); + return KickClientAsync(clIds, from); } - public Task KickClient(IList clientIds, KickOrigin from) + public Task KickClientAsync(IList clientIds, KickOrigin from) { - return Client.Send("clientkick", + return Client.SendAsync("clientkick", new Parameter("reasonid", (int)from), new Parameter("clid", clientIds.Select(i => new ParameterValue(i)).ToArray())); } - public Task KickClient(IList clientIds, KickOrigin from, string reasonMessage) + public Task KickClientAsync(IList clientIds, KickOrigin from, string reasonMessage) { - return Client.Send("clientkick", + return Client.SendAsync("clientkick", new Parameter("reasonid", (int)from), new Parameter("reasonmsg", reasonMessage), new Parameter("clid", clientIds.Select(i => new ParameterValue(i)).ToArray())); @@ -181,43 +187,43 @@ public Task KickClient(IList clientIds, KickOrigin from, string reasonMessa #endregion #region BanClient - public Task> BanClient(GetClientInfo client) + public Task> BanClientAsync(GetClientInfo client) { if (client == null) throw new ArgumentNullException(nameof(client)); - return BanClient(client.Id); + return BanClientAsync(client.Id); } - public Task> BanClient(GetClientInfo client, TimeSpan duration) + public Task> BanClientAsync(GetClientInfo client, TimeSpan duration) { if (client == null) throw new ArgumentNullException(nameof(client)); - return BanClient(client.Id, duration); + return BanClientAsync(client.Id, duration); } - public Task> BanClient(GetClientInfo client, TimeSpan duration, string reason) + public Task> BanClientAsync(GetClientInfo client, TimeSpan duration, string reason) { if (client == null) throw new ArgumentNullException(nameof(client)); - return BanClient(client.Id, duration, reason); + return BanClientAsync(client.Id, duration, reason); } - public async Task> BanClient(int clientId) + public async Task> BanClientAsync(int clientId) { - var res = await Client.Send("banclient", + var res = await Client.SendAsync("banclient", new Parameter("clid", clientId)) .ConfigureAwait(false); return DataProxy.SerializeGeneric(res); } - public async Task> BanClient(int clientId, TimeSpan duration) + public async Task> BanClientAsync(int clientId, TimeSpan duration) { - var res = await Client.Send("banclient", + var res = await Client.SendAsync("banclient", new Parameter("clid", clientId), new Parameter("time", (int)Math.Ceiling(duration.TotalSeconds))) .ConfigureAwait(false); return DataProxy.SerializeGeneric(res); } - public async Task> BanClient(int clientId, TimeSpan duration, string reason) + public async Task> BanClientAsync(int clientId, TimeSpan duration, string reason) { - var res = await Client.Send("banclient", + var res = await Client.SendAsync("banclient", new Parameter("clid", clientId), new Parameter("time", (int)Math.Ceiling(duration.TotalSeconds)), new Parameter("banreason", reason ?? string.Empty)) @@ -228,43 +234,53 @@ public async Task> BanClient(int clientId, TimeSpan dur #endregion #region GetClients - public async Task> GetClients() + public async Task> GetClientsAsync() { - var res = await Client.Send("clientlist").ConfigureAwait(false); + var res = await Client.SendAsync("clientlist").ConfigureAwait(false); return DataProxy.SerializeGeneric(res); } - public async Task> GetClients(GetClientOptions options) + public async Task> GetClientsAsync(GetClientOptions options) { var optionList = options.GetFlagsName(); - var res = await Client.Send("clientlist", null, optionList.ToArray()).ConfigureAwait(false); + var res = await Client.SendAsync("clientlist", null, optionList.ToArray()).ConfigureAwait(false); return DataProxy.SerializeGeneric(res); } - public Task GetClientInfo(GetClientInfo client) => GetClientInfo(client.Id); + public Task GetClientInfoAsync(GetClientInfo client) => GetClientInfoAsync(client.Id); - public async Task GetClientInfo(int clientId) + public async Task GetClientInfoAsync(int clientId) { - var res = await Client.Send("clientinfo", + var res = await Client.SendAsync("clientinfo", new Parameter("clid", clientId)) .ConfigureAwait(false); return DataProxy.SerializeGeneric(res).FirstOrDefault(); } + public async Task> GetDbClientsAsync(int start = 0, long duration = 9999999999) // Duration must be that long cause without this parameters it won't work. Bug from Teamspeak... + { + var res = await Client.SendAsync("clientdblist", + new Parameter("start", start), + new Parameter("duration", duration)) + .ConfigureAwait(false); + + return DataProxy.SerializeGeneric(res); + } + #endregion #region GetServerGroups - public async Task> GetServerGroups(int clientDatabaseId) + public async Task> GetServerGroupsAsync(int clientDatabaseId) { - var res = await Client.Send("servergroupsbyclientid", new Parameter("cldbid", clientDatabaseId)).ConfigureAwait(false); + var res = await Client.SendAsync("servergroupsbyclientid", new Parameter("cldbid", clientDatabaseId)).ConfigureAwait(false); return DataProxy.SerializeGeneric(res); } - public Task> GetServerGroups(GetClientInfo clientInfo) => GetServerGroups(clientInfo.DatabaseId); + public Task> GetServerGroupsAsync(GetClientInfo clientInfo) => GetServerGroupsAsync(clientInfo.DatabaseId); - public Task> GetServerGroups(WhoAmI clientInfo) => GetServerGroups(clientInfo.DatabaseId); + public Task> GetServerGroupsAsync(WhoAmI clientInfo) => GetServerGroupsAsync(clientInfo.DatabaseId); #endregion @@ -272,27 +288,27 @@ public async Task> GetServerGroups(int clientDatab #region One User - public Task AddServerGroup(int serverGroupId, int clientDatabaseId) => AddServerGroup(serverGroupId, new int[] { clientDatabaseId }); + public Task AddServerGroupAsync(int serverGroupId, int clientDatabaseId) => AddServerGroupAsync(serverGroupId, new int[] { clientDatabaseId }); - public Task AddServerGroup(int serverGroupId, GetClientInfo clientInfo) => AddServerGroup(serverGroupId, clientInfo.DatabaseId); + public Task AddServerGroupAsync(int serverGroupId, GetClientInfo clientInfo) => AddServerGroupAsync(serverGroupId, clientInfo.DatabaseId); - public Task AddServerGroup(GetServerGroup serverGroup, int clientDatabaseId) => AddServerGroup(serverGroup.Id, clientDatabaseId); + public Task AddServerGroupAsync(GetServerGroup serverGroup, int clientDatabaseId) => AddServerGroupAsync(serverGroup.Id, clientDatabaseId); - public Task AddServerGroup(GetServerGroup serverGroup, GetClientInfo clientInfo) => AddServerGroup(serverGroup.Id, clientInfo.DatabaseId); + public Task AddServerGroupAsync(GetServerGroup serverGroup, GetClientInfo clientInfo) => AddServerGroupAsync(serverGroup.Id, clientInfo.DatabaseId); #endregion #region Multiple Users - public Task AddServerGroup(int serverGroupId, IEnumerable clientInfo) => AddServerGroup(serverGroupId, clientInfo.Select(info => info.DatabaseId)); + public Task AddServerGroupAsync(int serverGroupId, IEnumerable clientInfo) => AddServerGroupAsync(serverGroupId, clientInfo.Select(info => info.DatabaseId)); - public Task AddServerGroup(GetServerGroup serverGroup, IEnumerable clientDatabaseIds) => AddServerGroup(serverGroup.Id, clientDatabaseIds); + public Task AddServerGroupAsync(GetServerGroup serverGroup, IEnumerable clientDatabaseIds) => AddServerGroupAsync(serverGroup.Id, clientDatabaseIds); - public Task AddServerGroup(GetServerGroup serverGroup, IEnumerable clientInfo) => AddServerGroup(serverGroup.Id, clientInfo.Select(info => info.DatabaseId)); + public Task AddServerGroupAsync(GetServerGroup serverGroup, IEnumerable clientInfo) => AddServerGroupAsync(serverGroup.Id, clientInfo.Select(info => info.DatabaseId)); - public Task AddServerGroup(int serverGroupId, IEnumerable clientDatabaseIds) + public Task AddServerGroupAsync(int serverGroupId, IEnumerable clientDatabaseIds) { - return Client.Send("servergroupaddclient", + return Client.SendAsync("servergroupaddclient", new Parameter("sgid", serverGroupId), new Parameter("cldbid", clientDatabaseIds.Select(id => new ParameterValue(id)).ToArray())); } @@ -305,27 +321,27 @@ public Task AddServerGroup(int serverGroupId, IEnumerable clientDatabaseIds #region One User - public Task RemoveServerGroup(int serverGroupId, int clientDatabaseId) => RemoveServerGroup(serverGroupId, new int[] { clientDatabaseId }); + public Task RemoveServerGroupAsync(int serverGroupId, int clientDatabaseId) => RemoveServerGroupAsync(serverGroupId, new int[] { clientDatabaseId }); - public Task RemoveServerGroup(int serverGroupId, GetClientInfo clientInfo) => RemoveServerGroup(serverGroupId, clientInfo.DatabaseId); + public Task RemoveServerGroupAsync(int serverGroupId, GetClientInfo clientInfo) => RemoveServerGroupAsync(serverGroupId, clientInfo.DatabaseId); - public Task RemoveServerGroup(GetServerGroup serverGroup, int clientDatabaseId) => RemoveServerGroup(serverGroup.Id, clientDatabaseId); + public Task RemoveServerGroupAsync(GetServerGroup serverGroup, int clientDatabaseId) => RemoveServerGroupAsync(serverGroup.Id, clientDatabaseId); - public Task RemoveServerGroup(GetServerGroup serverGroup, GetClientInfo clientInfo) => RemoveServerGroup(serverGroup.Id, clientInfo.DatabaseId); + public Task RemoveServerGroupAsync(GetServerGroup serverGroup, GetClientInfo clientInfo) => RemoveServerGroupAsync(serverGroup.Id, clientInfo.DatabaseId); #endregion #region Multiple Users - public Task RemoveServerGroup(int serverGroupId, IEnumerable clientInfo) => RemoveServerGroup(serverGroupId, clientInfo.Select(info => info.DatabaseId)); + public Task RemoveServerGroupAsync(int serverGroupId, IEnumerable clientInfo) => RemoveServerGroupAsync(serverGroupId, clientInfo.Select(info => info.DatabaseId)); - public Task RemoveServerGroup(GetServerGroup serverGroup, IEnumerable clientDatabaseIds) => RemoveServerGroup(serverGroup.Id, clientDatabaseIds); + public Task RemoveServerGroupAsync(GetServerGroup serverGroup, IEnumerable clientDatabaseIds) => RemoveServerGroupAsync(serverGroup.Id, clientDatabaseIds); - public Task RemoveServerGroup(GetServerGroup serverGroup, IEnumerable clientInfo) => RemoveServerGroup(serverGroup.Id, clientInfo.Select(info => info.DatabaseId)); + public Task RemoveServerGroupAsync(GetServerGroup serverGroup, IEnumerable clientInfo) => RemoveServerGroupAsync(serverGroup.Id, clientInfo.Select(info => info.DatabaseId)); - public Task RemoveServerGroup(int serverGroupId, IEnumerable clientDatabaseIds) + public Task RemoveServerGroupAsync(int serverGroupId, IEnumerable clientDatabaseIds) { - return Client.Send("servergroupdelclient", + return Client.SendAsync("servergroupdelclient", new Parameter("sgid", serverGroupId), new Parameter("cldbid", clientDatabaseIds.Select(id => new ParameterValue(id)).ToArray())); } @@ -340,32 +356,32 @@ public Task RemoveServerGroup(int serverGroupId, IEnumerable clientDatabase #region GetChannels - public async Task> GetChannels() + public async Task> GetChannelsAsync() { - var res = await Client.Send("channellist").ConfigureAwait(false); + var res = await Client.SendAsync("channellist").ConfigureAwait(false); return DataProxy.SerializeGeneric(res); } - public async Task> GetChannels(GetChannelOptions options) + public async Task> GetChannelsAsync(GetChannelOptions options) { var optionList = options.GetFlagsName(); - var res = await Client.Send("channellist", null, optionList.ToArray()).ConfigureAwait(false); + var res = await Client.SendAsync("channellist", null, optionList.ToArray()).ConfigureAwait(false); return DataProxy.SerializeGeneric(res); } #endregion #region GetChannelInfo - public Task GetChannelInfo(GetChannelListInfo channel) + public Task GetChannelInfoAsync(GetChannelListInfo channel) { if (channel == null) throw new ArgumentNullException(nameof(channel)); - return GetChannelInfo(channel.Id); + return GetChannelInfoAsync(channel.Id); } - public async Task GetChannelInfo(int channelId) + public async Task GetChannelInfoAsync(int channelId) { - var res = await Client.Send("channelinfo", + var res = await Client.SendAsync("channelinfo", new Parameter("cid", channelId)) .ConfigureAwait(false); return DataProxy.SerializeGeneric(res).FirstOrDefault(); @@ -374,14 +390,14 @@ public async Task GetChannelInfo(int channelId) #endregion #region FindChannel - public async Task> FindChannel() + public async Task> FindChannelAsync() { - var res = await Client.Send("channelfind").ConfigureAwait(false); + var res = await Client.SendAsync("channelfind").ConfigureAwait(false); return DataProxy.SerializeGeneric(res); } - public async Task> FindChannel(string pattern) + public async Task> FindChannelAsync(string pattern) { - var res = await Client.Send("channelfind", + var res = await Client.SendAsync("channelfind", new Parameter("pattern", pattern ?? string.Empty)) .ConfigureAwait(false); return DataProxy.SerializeGeneric(res); @@ -390,32 +406,32 @@ public async Task> FindChannel(string pattern) #endregion #region MoveChannel - public Task MoveChannel(GetChannelListInfo channel, GetChannelListInfo parent) + public Task MoveChannelAsync(GetChannelListInfo channel, GetChannelListInfo parent) { if (channel == null) throw new ArgumentNullException(nameof(channel)); if (parent == null) throw new ArgumentNullException(nameof(parent)); - return MoveChannel(channel.Id, parent.Id); + return MoveChannelAsync(channel.Id, parent.Id); } - public Task MoveChannel(GetChannelListInfo channel, GetChannelListInfo parent, int order) + public Task MoveChannelAsync(GetChannelListInfo channel, GetChannelListInfo parent, int order) { if (channel == null) throw new ArgumentNullException(nameof(channel)); if (parent == null) throw new ArgumentNullException(nameof(parent)); - return MoveChannel(channel.Id, parent.Id, order); + return MoveChannelAsync(channel.Id, parent.Id, order); } - public Task MoveChannel(int channelId, int parentChannelId) + public Task MoveChannelAsync(int channelId, int parentChannelId) { - return Client.Send("channelmove", + return Client.SendAsync("channelmove", new Parameter("cid", channelId), new Parameter("cpid", parentChannelId)); } - public Task MoveChannel(int channelId, int parentChannelId, int order) + public Task MoveChannelAsync(int channelId, int parentChannelId, int order) { - return Client.Send("channelmove", + return Client.SendAsync("channelmove", new Parameter("cid", channelId), new Parameter("cpid", parentChannelId), new Parameter("order", order)); @@ -426,12 +442,12 @@ public Task MoveChannel(int channelId, int parentChannelId, int order) // Region setting properties not supported yet - public async Task CreateChannel(string name) + public async Task CreateChannelAsync(string name) { if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name)); - var res = await Client.Send("channelcreate", + var res = await Client.SendAsync("channelcreate", new Parameter("channel_name", name)) .ConfigureAwait(false); return DataProxy.SerializeGeneric(res).FirstOrDefault(); @@ -440,27 +456,27 @@ public async Task CreateChannel(string name) #endregion #region DeleteChannel - public Task DeleteChannel(GetChannelListInfo channel) + public Task DeleteChannelAsync(GetChannelListInfo channel) { if (channel == null) throw new ArgumentNullException(nameof(channel)); - return DeleteChannel(channel.Id); + return DeleteChannelAsync(channel.Id); } - public Task DeleteChannel(GetChannelListInfo channel, bool force) + public Task DeleteChannelAsync(GetChannelListInfo channel, bool force) { if (channel == null) throw new ArgumentNullException(nameof(channel)); - return DeleteChannel(channel.Id, force); + return DeleteChannelAsync(channel.Id, force); } - public Task DeleteChannel(int channelId) + public Task DeleteChannelAsync(int channelId) { - return Client.Send("channeldelete", + return Client.SendAsync("channeldelete", new Parameter("cid", channelId)); } - public Task DeleteChannel(int channelId, bool force) + public Task DeleteChannelAsync(int channelId, bool force) { - return Client.Send("channeldelete", + return Client.SendAsync("channeldelete", new Parameter("cid", channelId), new Parameter("force", force)); } @@ -468,7 +484,7 @@ public Task DeleteChannel(int channelId, bool force) #endregion #region EditChannel - public Task EditChannel(int channelId, EditChannelInfo channel) + public Task EditChannelAsync(int channelId, EditChannelInfo channel) { var updateParameters = new List { @@ -497,14 +513,14 @@ public Task EditChannel(int channelId, EditChannelInfo channel) if (channel.IsCodecUnencrypted != null) { updateParameters.Add(new Parameter("channel_codec_is_unencrypted", channel.IsCodecUnencrypted)); } if (channel.ParentChannelId != null) { updateParameters.Add(new Parameter("channel_cpid", channel.ParentChannelId)); } - return Client.Send("channeledit", updateParameters.ToArray()); + return Client.SendAsync("channeledit", updateParameters.ToArray()); } #endregion #region ChannelAddPerm - public Task ChannelAddPerm(int channelId, string permsId, int permValue) + public Task ChannelAddPermAsync(int channelId, string permsId, int permValue) { - return Client.Send("channeladdperm", + return Client.SendAsync("channeladdperm", new Parameter("cid", channelId), new Parameter("permsid", permsId), new Parameter("permvalue", permValue)); @@ -517,28 +533,28 @@ public Task ChannelAddPerm(int channelId, string permsId, int permValue) #region GetServers - public async Task> GetServers() + public async Task> GetServersAsync() { - var res = await Client.Send("serverlist").ConfigureAwait(false); + var res = await Client.SendAsync("serverlist").ConfigureAwait(false); return DataProxy.SerializeGeneric(res); } - public async Task> GetServers(GetServerOptions options) + public async Task> GetServersAsync(GetServerOptions options) { var optionList = options.GetFlagsName(); - var res = await Client.Send("serverlist", null, optionList.ToArray()).ConfigureAwait(false); + var res = await Client.SendAsync("serverlist", null, optionList.ToArray()).ConfigureAwait(false); return DataProxy.SerializeGeneric(res); } - public async Task> GetServerGroups() + public async Task> GetServerGroupsAsync() { - var res = await Client.Send("servergrouplist").ConfigureAwait(false); + var res = await Client.SendAsync("servergrouplist").ConfigureAwait(false); return DataProxy.SerializeGeneric(res); } - public async Task> GetServerGroupClientList(int serverGroupDatabaseId) + public async Task> GetServerGroupClientListAsync(int serverGroupDatabaseId) { - var res = await Client.Send("servergroupclientlist", new Parameter("sgid", serverGroupDatabaseId)).ConfigureAwait(false); + var res = await Client.SendAsync("servergroupclientlist", new Parameter("sgid", serverGroupDatabaseId)).ConfigureAwait(false); return DataProxy.SerializeGeneric(res); } @@ -550,28 +566,28 @@ public async Task> GetServerGroupClientL #region SendTextMessage - public Task SendMessage(string message, GetServerListInfo targetServer) + public Task SendMessageAsync(string message, GetServerListInfo targetServer) { if (targetServer == null) throw new ArgumentNullException(nameof(targetServer)); - return SendMessage(message, MessageTarget.Server, targetServer.Id); + return SendMessageAsync(message, MessageTarget.Server, targetServer.Id); } - public Task SendMessage(string message, GetChannelListInfo targetChannel) + public Task SendMessageAsync(string message, GetChannelListInfo targetChannel) { if (targetChannel == null) throw new ArgumentNullException(nameof(targetChannel)); - return SendMessage(message, MessageTarget.Channel, targetChannel.Id); + return SendMessageAsync(message, MessageTarget.Channel, targetChannel.Id); } - public Task SendMessage(string message, GetClientInfo targetClient) + public Task SendMessageAsync(string message, GetClientInfo targetClient) { if (targetClient == null) throw new ArgumentNullException(nameof(targetClient)); - return SendMessage(message, MessageTarget.Private, targetClient.Id); + return SendMessageAsync(message, MessageTarget.Private, targetClient.Id); } - public Task SendMessage(string message, MessageTarget target, int targetId) + public Task SendMessageAsync(string message, MessageTarget target, int targetId) { message = message ?? string.Empty; - return Client.Send("sendtextmessage", + return Client.SendAsync("sendtextmessage", new Parameter("targetmode", (int)target), new Parameter("target", targetId), new Parameter("msg", message)); @@ -580,35 +596,35 @@ public Task SendMessage(string message, MessageTarget target, int targetId) #endregion #region SendGlobalMessage - public Task SendGlobalMessage(string message) + public Task SendGlobalMessageAsync(string message) { - return Client.Send("gm", + return Client.SendAsync("gm", new Parameter("msg", message ?? string.Empty)); } #endregion #region PokeClient - public Task PokeClient(GetClientInfo client) + public Task PokeClientAsync(GetClientInfo client) { if (client == null) throw new ArgumentNullException(nameof(client)); - return PokeClient(client.Id); + return PokeClientAsync(client.Id); } - public Task PokeClient(int clientId) + public Task PokeClientAsync(int clientId) { - return PokeClient(clientId, string.Empty); + return PokeClientAsync(clientId, string.Empty); } - public Task PokeClient(GetClientInfo client, string message) + public Task PokeClientAsync(GetClientInfo client, string message) { if (client == null) throw new ArgumentNullException(nameof(client)); - return PokeClient(client.Id, message); + return PokeClientAsync(client.Id, message); } - public Task PokeClient(int clientId, string message) + public Task PokeClientAsync(int clientId, string message) { - return Client.Send("clientpoke", + return Client.SendAsync("clientpoke", new Parameter("msg", message ?? string.Empty), new Parameter("clid", clientId)); } @@ -616,13 +632,13 @@ public Task PokeClient(int clientId, string message) #endregion #region ChangeNickName - public Task ChangeNickName(string nickName) => ChangeNickName(nickName, default); + public Task ChangeNickNameAsync(string nickName) => ChangeNickNameAsync(nickName, default); - public Task ChangeNickName(string nickName, WhoAmI whoAmI) + public Task ChangeNickNameAsync(string nickName, WhoAmI whoAmI) { if (whoAmI != null) whoAmI.NickName = nickName; - return Client.Send("clientupdate", + return Client.SendAsync("clientupdate", new Parameter("client_nickname", nickName)); } #endregion @@ -633,11 +649,11 @@ public Task ChangeNickName(string nickName, WhoAmI whoAmI) #region CreateDirectory - public Task CreateDirectory(int channelId, string dirPath) => CreateDirectory(channelId, string.Empty, dirPath); + public Task CreateDirectoryAsync(int channelId, string dirPath) => CreateDirectoryAsync(channelId, string.Empty, dirPath); - public Task CreateDirectory(int channelId, string channelPassword, string dirPath) + public Task CreateDirectoryAsync(int channelId, string channelPassword, string dirPath) { - return Client.Send("ftcreatedir", + return Client.SendAsync("ftcreatedir", new Parameter("cid", channelId), new Parameter("cpw", channelPassword), new Parameter("dirname", NormalizePath(dirPath))); @@ -647,15 +663,15 @@ public Task CreateDirectory(int channelId, string channelPassword, string dirPat #region DeleteFile - public Task DeleteFile(int channelId, string filePath) => DeleteFile(channelId, string.Empty, new string[] { filePath }); + public Task DeleteFileAsync(int channelId, string filePath) => DeleteFileAsync(channelId, string.Empty, new string[] { filePath }); - public Task DeleteFile(int channelId, string channelPassword, string filePath) => DeleteFile(channelId, channelPassword, new string[] { filePath }); + public Task DeleteFileAsync(int channelId, string channelPassword, string filePath) => DeleteFileAsync(channelId, channelPassword, new string[] { filePath }); - public Task DeleteFile(int channelId, IEnumerable filePaths) => DeleteFile(channelId, string.Empty, filePaths); + public Task DeleteFileAsync(int channelId, IEnumerable filePaths) => DeleteFileAsync(channelId, string.Empty, filePaths); - public Task DeleteFile(int channelId, string channelPassword, IEnumerable filePaths) + public Task DeleteFileAsync(int channelId, string channelPassword, IEnumerable filePaths) { - return Client.Send("ftdeletefile", + return Client.SendAsync("ftdeletefile", new Parameter("cid", channelId), new Parameter("cpw", channelPassword), new Parameter("name", filePaths.Select(path => new ParameterValue(NormalizePath(path))).ToArray())); @@ -665,11 +681,11 @@ public Task DeleteFile(int channelId, string channelPassword, IEnumerable GetFileInfo(int channelId, string filePath) => GetFileInfo(channelId, string.Empty, filePath); + public Task GetFileInfoAsync(int channelId, string filePath) => GetFileInfoAsync(channelId, string.Empty, filePath); - public async Task GetFileInfo(int channelId, string channelPassword, string filePath) + public async Task GetFileInfoAsync(int channelId, string channelPassword, string filePath) { - var res = await Client.Send("ftgetfileinfo", + var res = await Client.SendAsync("ftgetfileinfo", new Parameter("cid", channelId), new Parameter("cpw", channelPassword), new Parameter("name", NormalizePath(filePath))).ConfigureAwait(false); @@ -681,13 +697,13 @@ public async Task GetFileInfo(int channelId, string channelPassword #region GetFileList - public Task> GetFiles(int channelId) => GetFiles(channelId, string.Empty, "/"); + public Task> GetFilesAsync(int channelId) => GetFilesAsync(channelId, string.Empty, "/"); - public Task> GetFiles(int channelId, string dirPath) => GetFiles(channelId, string.Empty, dirPath); + public Task> GetFilesAsync(int channelId, string dirPath) => GetFilesAsync(channelId, string.Empty, dirPath); - public async Task> GetFiles(int channelId, string channelPassword, string dirPath) + public async Task> GetFilesAsync(int channelId, string channelPassword, string dirPath) { - var res = await Client.Send("ftgetfilelist", + var res = await Client.SendAsync("ftgetfilelist", new Parameter("cid", channelId), new Parameter("cpw", channelPassword), new Parameter("path", NormalizePath(dirPath))).ConfigureAwait(false); @@ -701,11 +717,11 @@ public async Task> GetFiles(int channelId, string channe #region Same Channel - public Task MoveFile(int channelId, string oldFilePath, string newFilePath) => MoveFile(channelId, string.Empty, oldFilePath, newFilePath); + public Task MoveFileAsync(int channelId, string oldFilePath, string newFilePath) => MoveFileAsync(channelId, string.Empty, oldFilePath, newFilePath); - public Task MoveFile(int channelId, string channelPassword, string oldFilePath, string newFilePath) + public Task MoveFileAsync(int channelId, string channelPassword, string oldFilePath, string newFilePath) { - return Client.Send("ftrenamefile", + return Client.SendAsync("ftrenamefile", new Parameter("cid", channelId), new Parameter("cpw", channelPassword), new Parameter("oldname", NormalizePath(oldFilePath)), @@ -716,15 +732,15 @@ public Task MoveFile(int channelId, string channelPassword, string oldFilePath, #region Other Channel - public Task MoveFile(int channelId, string oldFilePath, int targetChannelId, string newFilePath) => MoveFile(channelId, string.Empty, oldFilePath, targetChannelId, string.Empty, newFilePath); + public Task MoveFileAsync(int channelId, string oldFilePath, int targetChannelId, string newFilePath) => MoveFileAsync(channelId, string.Empty, oldFilePath, targetChannelId, string.Empty, newFilePath); - public Task MoveFile(int channelId, string channelPassword, string oldFilePath, int targetChannelId, string newFilePath) => MoveFile(channelId, channelPassword, oldFilePath, targetChannelId, string.Empty, newFilePath); + public Task MoveFileAsync(int channelId, string channelPassword, string oldFilePath, int targetChannelId, string newFilePath) => MoveFileAsync(channelId, channelPassword, oldFilePath, targetChannelId, string.Empty, newFilePath); - public Task MoveFile(int channelId, string oldFilePath, int targetChannelId, string targetChannelPassword, string newFilePath) => MoveFile(channelId, string.Empty, oldFilePath, targetChannelId, targetChannelPassword, newFilePath); + public Task MoveFileAsync(int channelId, string oldFilePath, int targetChannelId, string targetChannelPassword, string newFilePath) => MoveFileAsync(channelId, string.Empty, oldFilePath, targetChannelId, targetChannelPassword, newFilePath); - public Task MoveFile(int channelId, string channelPassword, string oldFilePath, int targetChannelId, string targetChannelPassword, string newFilePath) + public Task MoveFileAsync(int channelId, string channelPassword, string oldFilePath, int targetChannelId, string targetChannelPassword, string newFilePath) { - return Client.Send("ftrenamefile", + return Client.SendAsync("ftrenamefile", new Parameter("cid", channelId), new Parameter("cpw", channelPassword), new Parameter("tcid", targetChannelId), @@ -739,11 +755,11 @@ public Task MoveFile(int channelId, string channelPassword, string oldFilePath, #region UploadFile - public Task UploadFile(int channelId, string filePath, byte[] data, bool overwrite = true, bool verify = true) => UploadFile(channelId, string.Empty, filePath, data, overwrite, verify); + public Task UploadFileAsync(int channelId, string filePath, byte[] data, bool overwrite = true, bool verify = true) => UploadFileAsync(channelId, string.Empty, filePath, data, overwrite, verify); - public async Task UploadFile(int channelId, string channelPassword, string filePath, byte[] data, bool overwrite = true, bool verify = true) + public async Task UploadFileAsync(int channelId, string channelPassword, string filePath, byte[] data, bool overwrite = true, bool verify = true) { - var res = await Client.Send("ftinitupload", + var res = await Client.SendAsync("ftinitupload", new Parameter("clientftfid", _fileTransferClient.GetFileTransferId()), new Parameter("cid", channelId), new Parameter("cpw", channelPassword), @@ -754,19 +770,19 @@ public async Task UploadFile(int channelId, string channelPassword, string fileP var parsedRes = DataProxy.SerializeGeneric(res).First(); - await _fileTransferClient.SendFile(data, parsedRes.Port, parsedRes.FileTransferKey).ConfigureAwait(false); + await _fileTransferClient.SendFileAsync(data, parsedRes.Port, parsedRes.FileTransferKey).ConfigureAwait(false); if (verify) { - await VerifyUpload(parsedRes.ServerFileTransferId).ConfigureAwait(false); + await VerifyUploadAsync(parsedRes.ServerFileTransferId).ConfigureAwait(false); } } - public Task UploadFile(int channelId, string filePath, Stream dataStream, long size, bool overwrite = true, bool verify = true) => UploadFile(channelId, string.Empty, filePath, dataStream, size, overwrite, verify); + public Task UploadFileAsync(int channelId, string filePath, Stream dataStream, long size, bool overwrite = true, bool verify = true) => UploadFileAsync(channelId, string.Empty, filePath, dataStream, size, overwrite, verify); - public async Task UploadFile(int channelId, string channelPassword, string filePath, Stream dataStream, long size, bool overwrite = true, bool verify = true) + public async Task UploadFileAsync(int channelId, string channelPassword, string filePath, Stream dataStream, long size, bool overwrite = true, bool verify = true) { - var res = await Client.Send("ftinitupload", + var res = await Client.SendAsync("ftinitupload", new Parameter("clientftfid", _fileTransferClient.GetFileTransferId()), new Parameter("cid", channelId), new Parameter("cpw", channelPassword), @@ -777,16 +793,16 @@ public async Task UploadFile(int channelId, string channelPassword, string fileP var parsedRes = DataProxy.SerializeGeneric(res).First(); - await _fileTransferClient.SendFile(dataStream, parsedRes.Port, parsedRes.FileTransferKey).ConfigureAwait(false); + await _fileTransferClient.SendFileAsync(dataStream, parsedRes.Port, parsedRes.FileTransferKey).ConfigureAwait(false); if (verify) { - await VerifyUpload(parsedRes.ServerFileTransferId).ConfigureAwait(false); + await VerifyUploadAsync(parsedRes.ServerFileTransferId).ConfigureAwait(false); } } /// Waits until the server fully receives the file or throws an exception when the upload times out. - private async Task VerifyUpload(int serverFileTransferId) + private async Task VerifyUploadAsync(int serverFileTransferId) { long arrivedBytes = 0; var intervalMillis = 100; @@ -795,7 +811,7 @@ private async Task VerifyUpload(int serverFileTransferId) while (true) { - var transfers = await GetCurrentFileTransfers(); + var transfers = await GetCurrentFileTransfersAsync(); var currentTransfer = transfers.Where(transfer => transfer.ServerFileTransferId == serverFileTransferId).FirstOrDefault(); if (currentTransfer == null) @@ -813,7 +829,7 @@ private async Task VerifyUpload(int serverFileTransferId) { try { - await StopFileTransfer(serverFileTransferId).ConfigureAwait(false); + await StopFileTransferAsync(serverFileTransferId).ConfigureAwait(false); } catch { } @@ -836,11 +852,11 @@ private async Task VerifyUpload(int serverFileTransferId) #region DownloadFile - public Task DownloadFile(int channelId, string filePath) => DownloadFile(channelId, string.Empty, filePath); + public Task DownloadFileAsync(int channelId, string filePath) => DownloadFileAsync(channelId, string.Empty, filePath); - public async Task DownloadFile(int channelId, string channelPassword, string filePath) + public async Task DownloadFileAsync(int channelId, string channelPassword, string filePath) { - var res = await Client.Send("ftinitdownload", + var res = await Client.SendAsync("ftinitdownload", new Parameter("clientftfid", _fileTransferClient.GetFileTransferId()), new Parameter("cid", channelId), new Parameter("cpw", channelPassword), @@ -854,18 +870,18 @@ public async Task DownloadFile(int channelId, string channelPassword, st throw new FileTransferException("The file is too big for a single byte array."); } - return await _fileTransferClient.ReceiveFile((int)parsedRes.Size, parsedRes.Port, parsedRes.FileTransferKey).ConfigureAwait(false); + return await _fileTransferClient.ReceiveFileAsync((int)parsedRes.Size, parsedRes.Port, parsedRes.FileTransferKey).ConfigureAwait(false); } #endregion #region GetCurrentFileTransfers - public async Task> GetCurrentFileTransfers() + public async Task> GetCurrentFileTransfersAsync() { try { - var res = await Client.Send("ftlist").ConfigureAwait(false); + var res = await Client.SendAsync("ftlist").ConfigureAwait(false); return DataProxy.SerializeGeneric(res); } @@ -885,9 +901,9 @@ public async Task> GetCurrentFileTransfers #endregion - private Task StopFileTransfer(int serverFileTransferId, bool delete = true) + private Task StopFileTransferAsync(int serverFileTransferId, bool delete = true) { - return Client.Send("ftstop", + return Client.SendAsync("ftstop", new Parameter("serverftfid", serverFileTransferId), new Parameter("delete", delete)); } diff --git a/src/TeamSpeak3QueryApi/ValidationHelper.cs b/src/TeamSpeak3QueryApi/ValidationHelper.cs index 74a1a7a..9b87eac 100644 --- a/src/TeamSpeak3QueryApi/ValidationHelper.cs +++ b/src/TeamSpeak3QueryApi/ValidationHelper.cs @@ -1,17 +1,17 @@ using System; using System.Collections.Generic; -using System.Net; +using System.Net; using System.Text; namespace TeamSpeak3QueryApi { internal class ValidationHelper - { + { /// /// on false, API should throw new ArgumentOutOfRangeException("port"); /// /// - /// + /// public static bool ValidateTcpPort(int port) => port >= IPEndPoint.MinPort && port <= IPEndPoint.MaxPort; } } From bb62f739322fbeb4844407d96411c145d0c5b1f4 Mon Sep 17 00:00:00 2001 From: First-Coder Date: Sat, 8 Aug 2020 16:23:34 +0200 Subject: [PATCH 02/14] Remove Client folder --- src/TeamSpeak3QueryApi/TeamSpeak3QueryApi.csproj | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/TeamSpeak3QueryApi/TeamSpeak3QueryApi.csproj b/src/TeamSpeak3QueryApi/TeamSpeak3QueryApi.csproj index eb2b2ad..e8f9fa2 100644 --- a/src/TeamSpeak3QueryApi/TeamSpeak3QueryApi.csproj +++ b/src/TeamSpeak3QueryApi/TeamSpeak3QueryApi.csproj @@ -30,8 +30,4 @@ - - - - From 9bb4fa265cdfcdf790119009db290b81a81ea7c3 Mon Sep 17 00:00:00 2001 From: First-Coder Date: Sat, 8 Aug 2020 17:51:32 +0200 Subject: [PATCH 03/14] Updated demo code --- src/TeamSpeak3QueryApi.Demo/Program.cs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/TeamSpeak3QueryApi.Demo/Program.cs b/src/TeamSpeak3QueryApi.Demo/Program.cs index 6520838..80a51b7 100644 --- a/src/TeamSpeak3QueryApi.Demo/Program.cs +++ b/src/TeamSpeak3QueryApi.Demo/Program.cs @@ -4,8 +4,8 @@ using System.IO; using System.Linq; using System.Threading.Tasks; -using TeamSpeak3QueryApi.Net.Specialized; -using TeamSpeak3QueryApi.Net.Specialized.Notifications; +using TeamSpeak3QueryApi.Net.Enums; +using TeamSpeak3QueryApi.Net.Notifications; namespace TeamSpeak3QueryApi.Net.Demo { @@ -23,25 +23,25 @@ static async Task Main(string[] args) await rc.Connect(); - await rc.Login(user, password); - await rc.UseServer(1); + await rc.LoginAsync(user, password); + await rc.UseServerAsync(1); - await rc.WhoAmI(); + await rc.WhoAmIAsync(); - await rc.RegisterServerNotification(); - await rc.RegisterChannelNotification(30); + await rc.RegisterServerNotificationAsync(); + await rc.RegisterChannelNotificationAsync(30); - var serverGroups = await rc.GetServerGroups(); + var serverGroups = await rc.GetServerGroupsAsync(); var firstNormalGroup = serverGroups?.FirstOrDefault(s => s.ServerGroupType == ServerGroupType.NormalGroup); - var groupClients = await rc.GetServerGroupClientList(firstNormalGroup.Id); + var groupClients = await rc.GetServerGroupClientListAsync(firstNormalGroup.Id); - var currentClients = await rc.GetClients(); + var currentClients = await rc.GetClientsAsync(); var fullClients = currentClients.Where(c => c.Type == ClientType.FullClient).ToList(); - await rc.KickClient(fullClients, KickOrigin.Channel); + await rc.KickClientAsync(fullClients, KickOrigin.Channel, "You're kicked from channel"); - // await rc.MoveClient(1, 1); - // await rc.KickClient(1, KickTarget.Server); + // await rc.MoveClientAsync(1, 1); + // await rc.KickClientAsync(1, KickTarget.Server); rc.Subscribe(data => data.ForEach(c => Debug.WriteLine($"Client {c.NickName} joined."))); rc.Subscribe(data => data.ForEach(c => Debug.WriteLine($"Client with id {c.Id} left (kicked/banned/left)."))); From 9941271ef80229f41bdd7efc9a411fe789651275 Mon Sep 17 00:00:00 2001 From: First-Coder Date: Sat, 8 Aug 2020 19:18:22 +0200 Subject: [PATCH 04/14] Update netcoreapp cause of compile problems --- src/TeamSpeak3QueryApi.Demo/Program.cs | 9 ++++----- .../TeamSpeak3QueryApi.Demo.csproj | 2 +- src/TeamSpeak3QueryApi/TeamSpeak3QueryApi.csproj | 1 + 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/TeamSpeak3QueryApi.Demo/Program.cs b/src/TeamSpeak3QueryApi.Demo/Program.cs index 80a51b7..0246410 100644 --- a/src/TeamSpeak3QueryApi.Demo/Program.cs +++ b/src/TeamSpeak3QueryApi.Demo/Program.cs @@ -20,7 +20,6 @@ static async Task Main(string[] args) var password = loginData[2].Trim(); var rc = new TeamSpeakClient(host); - await rc.Connect(); await rc.LoginAsync(user, password); @@ -29,12 +28,12 @@ static async Task Main(string[] args) await rc.WhoAmIAsync(); await rc.RegisterServerNotificationAsync(); - await rc.RegisterChannelNotificationAsync(30); - + await rc.RegisterAllChannelNotificationAsync(); + var serverGroups = await rc.GetServerGroupsAsync(); - var firstNormalGroup = serverGroups?.FirstOrDefault(s => s.ServerGroupType == ServerGroupType.NormalGroup); - var groupClients = await rc.GetServerGroupClientListAsync(firstNormalGroup.Id); + var firstNormalGroup = serverGroups?.FirstOrDefault(s => s.ServerGroupType == ServerGroupType.NormalGroup && s.Id != 46); // Id 46 is default Servergroup + var groupClients = await rc.GetServerGroupClientListAsync(firstNormalGroup.Id); var currentClients = await rc.GetClientsAsync(); var fullClients = currentClients.Where(c => c.Type == ClientType.FullClient).ToList(); diff --git a/src/TeamSpeak3QueryApi.Demo/TeamSpeak3QueryApi.Demo.csproj b/src/TeamSpeak3QueryApi.Demo/TeamSpeak3QueryApi.Demo.csproj index 10ece9a..8566bf3 100644 --- a/src/TeamSpeak3QueryApi.Demo/TeamSpeak3QueryApi.Demo.csproj +++ b/src/TeamSpeak3QueryApi.Demo/TeamSpeak3QueryApi.Demo.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp1.1 + netcoreapp3.1 diff --git a/src/TeamSpeak3QueryApi/TeamSpeak3QueryApi.csproj b/src/TeamSpeak3QueryApi/TeamSpeak3QueryApi.csproj index e8f9fa2..6d58760 100644 --- a/src/TeamSpeak3QueryApi/TeamSpeak3QueryApi.csproj +++ b/src/TeamSpeak3QueryApi/TeamSpeak3QueryApi.csproj @@ -26,6 +26,7 @@ + From c202911d9bc3e50cd0b3354701adfa64a99c263f Mon Sep 17 00:00:00 2001 From: First-Coder Date: Sat, 8 Aug 2020 23:35:04 +0200 Subject: [PATCH 05/14] Added Ssh support --- src/TeamSpeak3QueryApi.Demo/Program.cs | 10 ++- .../Enums/TeamspeakConnectionType.cs | 12 +++ src/TeamSpeak3QueryApi/Query/QueryClient.cs | 77 +++++++++++++++---- src/TeamSpeak3QueryApi/TeamSpeakClient.cs | 15 ++-- 4 files changed, 90 insertions(+), 24 deletions(-) create mode 100644 src/TeamSpeak3QueryApi/Enums/TeamspeakConnectionType.cs diff --git a/src/TeamSpeak3QueryApi.Demo/Program.cs b/src/TeamSpeak3QueryApi.Demo/Program.cs index 0246410..7670c90 100644 --- a/src/TeamSpeak3QueryApi.Demo/Program.cs +++ b/src/TeamSpeak3QueryApi.Demo/Program.cs @@ -19,8 +19,14 @@ static async Task Main(string[] args) var user = loginData[1].Trim(); var password = loginData[2].Trim(); - var rc = new TeamSpeakClient(host); - await rc.Connect(); + // Ssh connection + var rc = new TeamSpeakClient(host, TeamspeakConnectionType.SSH); + rc.ConnectSsh(user, password); + + // Telnet connection + //var rc = new TeamSpeakClient(host); + //await rc.ConnectTelnetAsync(); + //await rc.LoginAsync(user, password); await rc.LoginAsync(user, password); await rc.UseServerAsync(1); diff --git a/src/TeamSpeak3QueryApi/Enums/TeamspeakConnectionType.cs b/src/TeamSpeak3QueryApi/Enums/TeamspeakConnectionType.cs new file mode 100644 index 0000000..89a1d0c --- /dev/null +++ b/src/TeamSpeak3QueryApi/Enums/TeamspeakConnectionType.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace TeamSpeak3QueryApi.Net.Enums +{ + public enum TeamspeakConnectionType + { + Telnet = 0, + SSH = 1 + } +} diff --git a/src/TeamSpeak3QueryApi/Query/QueryClient.cs b/src/TeamSpeak3QueryApi/Query/QueryClient.cs index 4a0a47d..db77262 100644 --- a/src/TeamSpeak3QueryApi/Query/QueryClient.cs +++ b/src/TeamSpeak3QueryApi/Query/QueryClient.cs @@ -7,8 +7,12 @@ using System.Linq; using System.Net.Sockets; using System.Text; +using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; +using Renci.SshNet; +using Renci.SshNet.Common; +using TeamSpeak3QueryApi.Net.Enums; using TeamSpeak3QueryApi.Net.Extensions; using TeamSpeak3QueryApi.Net.Notifications; using TeamSpeak3QueryApi.Net.Parameters; @@ -33,13 +37,15 @@ public class QueryClient : IDisposable /// The remote port of the Query API client. public int Port { get; } + public TeamspeakConnectionType ConnectionType { get; set; } + public bool IsConnected { get; private set; } /// The default host which is used when no host is provided. public const string DefaultHost = "localhost"; /// The default port which is used when no port is provided. - public const short DefaultPort = 10011; + public const short DefaultPort = 10022; public TcpClient Client { get; } private StreamReader _reader; @@ -49,22 +55,26 @@ public class QueryClient : IDisposable private readonly Queue _queue = new Queue(); private readonly ConcurrentDictionary>> _subscriptions = new ConcurrentDictionary>>(); + SshClient _sshClient; + ShellStream _shell; + string username; + #region Ctors /// Creates a new instance of using the and . - public QueryClient() - : this(DefaultHost, DefaultPort) + public QueryClient(TeamspeakConnectionType type) + : this(DefaultHost, DefaultPort, type) { } /// Creates a new instance of using the provided host and the . /// The host name of the remote server. - public QueryClient(string hostName) - : this(hostName, DefaultPort) + public QueryClient(string hostName, TeamspeakConnectionType type) + : this(hostName, DefaultPort, type) { } /// Creates a new instance of using the provided host TCP port. /// The host name of the remote server. /// The TCP port of the Query API server. - public QueryClient(string hostName, int port) + public QueryClient(string hostName, int port, TeamspeakConnectionType type) { if (string.IsNullOrWhiteSpace(hostName)) throw new ArgumentNullException(nameof(hostName)); @@ -73,6 +83,7 @@ public QueryClient(string hostName, int port) Host = hostName; Port = port; + ConnectionType = type; IsConnected = false; Client = new TcpClient(); } @@ -83,6 +94,9 @@ public QueryClient(string hostName, int port) /// An awaitable . public async Task ConnectAsync() { + if(ConnectionType != TeamspeakConnectionType.Telnet) + throw new InvalidOperationException("ConnectAsync Method without parameters can only be used with telnet Query. Please use ConnectSsh method."); + await Client.ConnectAsync(Host, Port).ConfigureAwait(false); if (!Client.Connected) throw new InvalidOperationException("Could not connect."); @@ -96,7 +110,7 @@ public async Task ConnectAsync() var headline = await _reader.ReadLineAsync().ConfigureAwait(false); - if(headline != "TS3") + if (headline != "TS3") { throw new QueryProtocolException("Telnet Query isn't a valid Teamspeak Query"); } @@ -106,6 +120,32 @@ public async Task ConnectAsync() return ResponseProcessingLoop(); } + public CancellationTokenSource ConnectSsh(string username, string password) + { + this.username = username; + + _sshClient = new SshClient(Host, Port, username, password); + _sshClient.Connect(); + + var terminalMode = new Dictionary(); + terminalMode.Add(TerminalModes.ECHO, 53); + + _shell = _sshClient.CreateShellStream("", 0, 0, 0, 0, 4096); + + _reader = new StreamReader(_shell, Encoding.UTF8, true, 1024, true); + _writer = new StreamWriter(_shell) { NewLine = "\n", AutoFlush = true }; + + var headline = _shell.Expect("\r\n", new TimeSpan(0, 0, 3)); + if (!headline.Contains("TS3")) + { + throw new QueryProtocolException("Telnet Query isn't a valid Teamspeak Query"); + } + _shell.Expect("\n", new TimeSpan(0, 0, 3)); // Ignore welcome message + _shell.Expect("\n", new TimeSpan(0, 0, 3)); // Ignore welcome message + + return ResponseProcessingLoop(); + } + public void Disconnect() { if (_cts == null) @@ -158,11 +198,10 @@ public async Task SendAsync(string cmd, Parameter[] p var d = new TaskCompletionSource(); var newItem = new QueryCommand(cmd, ps.AsReadOnly(), options, d, toSend.ToString()); - + _queue.Enqueue(newItem); await CheckQueueAsync().ConfigureAwait(false); - return await d.Task.ConfigureAwait(false); } @@ -370,26 +409,30 @@ private CancellationTokenSource ResponseProcessingLoop() string line = null; try { - line = await _reader.ReadLineAsync().WithCancellation(cts.Token).ConfigureAwait(false); + if(ConnectionType == TeamspeakConnectionType.SSH) + { + line = _shell.ReadLine(); + } + else + { + line = await _reader.ReadLineAsync().WithCancellation(cts.Token).ConfigureAwait(false); + } } catch (OperationCanceledException) { break; } - Debug.WriteLine(line); - if (line == null) { cts.Cancel(); continue; } - if (string.IsNullOrWhiteSpace(line)) + if (string.IsNullOrWhiteSpace(line) || string.IsNullOrEmpty(line) || line.StartsWith(username)) continue; var s = line.Trim(); - if (s.StartsWith("error", StringComparison.OrdinalIgnoreCase)) { Debug.Assert(_currentCommand != null); @@ -426,8 +469,8 @@ private async Task CheckQueueAsync() if (_queue.Count > 0) { _currentCommand = _queue.Dequeue(); - Debug.WriteLine(_currentCommand.SentText); - await _writer.WriteLineAsync(_currentCommand.SentText).ConfigureAwait(false); + Debug.WriteLine($"{ConnectionType}: {_currentCommand.SentText}"); + await _writer.WriteLineAsync((ConnectionType == TeamspeakConnectionType.Telnet ? _currentCommand.SentText : _currentCommand.SentText + "\n")).ConfigureAwait(false); await _writer.FlushAsync().ConfigureAwait(false); } } @@ -460,6 +503,8 @@ protected virtual void Dispose(bool disposing) _ns?.Dispose(); _reader?.Dispose(); _writer?.Dispose(); + _shell?.Dispose(); + _sshClient?.Dispose(); } } diff --git a/src/TeamSpeak3QueryApi/TeamSpeakClient.cs b/src/TeamSpeak3QueryApi/TeamSpeakClient.cs index c6947b4..798a487 100644 --- a/src/TeamSpeak3QueryApi/TeamSpeakClient.cs +++ b/src/TeamSpeak3QueryApi/TeamSpeakClient.cs @@ -13,6 +13,7 @@ using TeamSpeak3QueryApi.Net.Enums; using TeamSpeak3QueryApi.Net.Notifications; using TeamSpeak3QueryApi.Net.Extensions; +using System.Diagnostics; namespace TeamSpeak3QueryApi.Net { @@ -29,27 +30,29 @@ public class TeamSpeakClient : IDisposable /// Creates a new instance of using the and . public TeamSpeakClient() - : this(QueryClient.DefaultHost, QueryClient.DefaultPort) + : this(QueryClient.DefaultHost, QueryClient.DefaultPort, TeamspeakConnectionType.Telnet) { } /// Creates a new instance of using the provided host and the . /// The host name of the remote server. - public TeamSpeakClient(string hostName) - : this(hostName, QueryClient.DefaultPort) + public TeamSpeakClient(string hostName, TeamspeakConnectionType type = TeamspeakConnectionType.Telnet) + : this(hostName, QueryClient.DefaultPort, type) { } /// Creates a new instance of using the provided host TCP port. /// The host name of the remote server. /// The TCP port of the Query API server. - public TeamSpeakClient(string hostName, int port) + public TeamSpeakClient(string hostName, int port, TeamspeakConnectionType type) { - Client = new QueryClient(hostName, port); + Client = new QueryClient(hostName, port, type); _fileTransferClient = new FileTransferClient(hostName); } #endregion - public Task Connect() => Client.ConnectAsync(); + public Task ConnectTelnetAsync() => Client.ConnectAsync(); + public void ConnectSsh(string username, string password) => Client.ConnectSsh(username, password); + #region Subscriptions From c07a073a60b707a3bead02a7d779fce2a2af12fb Mon Sep 17 00:00:00 2001 From: First-Coder Date: Sun, 9 Aug 2020 00:02:08 +0200 Subject: [PATCH 06/14] Add debug line --- src/TeamSpeak3QueryApi/Query/QueryClient.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/TeamSpeak3QueryApi/Query/QueryClient.cs b/src/TeamSpeak3QueryApi/Query/QueryClient.cs index db77262..620099c 100644 --- a/src/TeamSpeak3QueryApi/Query/QueryClient.cs +++ b/src/TeamSpeak3QueryApi/Query/QueryClient.cs @@ -433,6 +433,8 @@ private CancellationTokenSource ResponseProcessingLoop() continue; var s = line.Trim(); + Debug.WriteLine(line); + if (s.StartsWith("error", StringComparison.OrdinalIgnoreCase)) { Debug.Assert(_currentCommand != null); From 37e1a829a4cbabff55bbf12e44bc970525811065 Mon Sep 17 00:00:00 2001 From: First-Coder Date: Mon, 10 Aug 2020 01:32:21 +0200 Subject: [PATCH 07/14] Added create channel with properties & bugfix create channel cpid --- src/TeamSpeak3QueryApi/TeamSpeakClient.cs | 39 ++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/TeamSpeak3QueryApi/TeamSpeakClient.cs b/src/TeamSpeak3QueryApi/TeamSpeakClient.cs index 798a487..1c4f341 100644 --- a/src/TeamSpeak3QueryApi/TeamSpeakClient.cs +++ b/src/TeamSpeak3QueryApi/TeamSpeakClient.cs @@ -456,6 +456,43 @@ public async Task CreateChannelAsync(string name) return DataProxy.SerializeGeneric(res).FirstOrDefault(); } + public async Task CreateChannelAsync(string name, EditChannelInfo channel) + { + if (string.IsNullOrEmpty(name)) + throw new ArgumentNullException(nameof(name)); + + var addParameters = new List + { + new Parameter("channel_name", name), + }; + + if (channel.Topic != null) { addParameters.Add(new Parameter("channel_topic", channel.Topic)); } + if (channel.Description != null) { addParameters.Add(new Parameter("channel_description", channel.Description)); } + if (channel.Password != null) { addParameters.Add(new Parameter("channel_password", channel.Password)); } + if (channel.Codec != null) { addParameters.Add(new Parameter("channel_codec", (int)channel.Codec)); } + if (channel.CodecQuality != null) { addParameters.Add(new Parameter("channel_codec_quality", channel.CodecQuality)); } + if (channel.MaxClients != null) { addParameters.Add(new Parameter("channel_maxclients", channel.MaxClients)); } + if (channel.MaxFamilyClients != null) { addParameters.Add(new Parameter("channel_maxfamilyclients", channel.MaxFamilyClients)); } + if (channel.Order != null) { addParameters.Add(new Parameter("channel_order", channel.Order)); } + if (channel.IsPermanent != null) { addParameters.Add(new Parameter("channel_flag_permanent", channel.IsPermanent)); } + if (channel.IsSemiPermanent != null) { addParameters.Add(new Parameter("channel_flag_semi_permanent", channel.IsSemiPermanent)); } + if (channel.IsTemporary != null) { addParameters.Add(new Parameter("channel_flag_temporary", channel.IsTemporary)); } + if (channel.IsDefaultChannel != null) { addParameters.Add(new Parameter("channel_flag_default", channel.IsDefaultChannel)); } + if (channel.IsMaxClientsUnlimited != null) { addParameters.Add(new Parameter("channel_flag_maxclients_unlimited", channel.IsMaxClientsUnlimited)); } + if (channel.IsMaxFamilyClientsUnlimited != null) { addParameters.Add(new Parameter("channel_flag_maxfamilyclients_unlimited", channel.IsMaxFamilyClientsUnlimited)); } + if (channel.IsMaxFamilyClientsInherited != null) { addParameters.Add(new Parameter("channel_flag_maxfamilyclients_inherited", channel.IsMaxFamilyClientsInherited)); } + if (channel.NeededTalkPower != null) { addParameters.Add(new Parameter("channel_needed_talk_power", channel.NeededTalkPower)); } + if (channel.PhoneticName != null) { addParameters.Add(new Parameter("channel_name_phonetic", channel.PhoneticName)); } + if (channel.IconId != null) { addParameters.Add(new Parameter("channel_icon_id", (int)channel.IconId)); } + if (channel.IsCodecUnencrypted != null) { addParameters.Add(new Parameter("channel_codec_is_unencrypted", channel.IsCodecUnencrypted)); } + if (channel.ParentChannelId != null) { addParameters.Add(new Parameter("cpid", channel.ParentChannelId)); } + + var res = await Client + .SendAsync("channelcreate", addParameters.ToArray()) + .ConfigureAwait(false); + return DataProxy.SerializeGeneric(res).FirstOrDefault(); + } + #endregion #region DeleteChannel @@ -514,7 +551,7 @@ public Task EditChannelAsync(int channelId, EditChannelInfo channel) if (channel.PhoneticName != null) { updateParameters.Add(new Parameter("channel_name_phonetic", channel.PhoneticName)); } if (channel.IconId != null) { updateParameters.Add(new Parameter("channel_icon_id", (int)channel.IconId)); } if (channel.IsCodecUnencrypted != null) { updateParameters.Add(new Parameter("channel_codec_is_unencrypted", channel.IsCodecUnencrypted)); } - if (channel.ParentChannelId != null) { updateParameters.Add(new Parameter("channel_cpid", channel.ParentChannelId)); } + if (channel.ParentChannelId != null) { updateParameters.Add(new Parameter("cpid", channel.ParentChannelId)); } return Client.SendAsync("channeledit", updateParameters.ToArray()); } From 0537afd5903d701d2848e3f66bf9b03335a932de Mon Sep 17 00:00:00 2001 From: Lukas Gundermann Date: Tue, 25 Aug 2020 15:13:50 +0200 Subject: [PATCH 08/14] Updated fodlers & updated teamspeakconnectiontype --- src/TeamSpeak3QueryApi.Demo/Program.cs | 3 ++- src/TeamSpeak3QueryApi/DataProxy.cs | 1 + .../{TeamspeakConnectionType.cs => Protocol.cs} | 2 +- .../Notifications/ChannelCreated.cs | 2 +- .../Notifications/ChannelEdited.cs | 2 +- .../Notifications/ClientEnterView.cs | 2 +- .../Notifications/ClientLeftView.cs | 2 +- .../Notifications/InvokerInformation.cs | 2 +- .../Notifications/ServerEdited.cs | 2 +- .../Notifications/TextMessage.cs | 4 ++-- .../{ => Query}/Enums/ClientType.cs | 2 +- .../{ => Query}/Enums/GetChannelOptions.cs | 2 +- .../{ => Query}/Enums/GetClientOptions.cs | 2 +- .../{ => Query}/Enums/GetServerOptions.cs | 2 +- .../{ => Query}/Enums/KickOrigin.cs | 2 +- .../{ => Query}/Enums/ManualEnums.cs | 2 +- .../{ => Query}/Enums/MessageTarget.cs | 2 +- .../{ => Query}/Enums/ReasonId.cs | 2 +- .../{ => Query}/Enums/ServerGroupType.cs | 2 +- .../{ => Query}/Parameters/IParameterValue.cs | 2 +- .../{ => Query}/Parameters/Parameter.cs | 2 +- .../{ => Query}/Parameters/ParameterValue.cs | 2 +- .../Parameters/ParameterValueArray.cs | 2 +- src/TeamSpeak3QueryApi/Query/QueryClient.cs | 16 ++++++++-------- src/TeamSpeak3QueryApi/Query/QueryCommand.cs | 2 +- .../{ => Query}/Responses/ClientBan.cs | 2 +- .../{ => Query}/Responses/CreatedChannel.cs | 2 +- .../{ => Query}/Responses/EditChannelInfo.cs | 4 ++-- .../{ => Query}/Responses/FoundChannel.cs | 2 +- .../{ => Query}/Responses/GetChannelInfo.cs | 4 ++-- .../{ => Query}/Responses/GetChannelListInfo.cs | 4 ++-- .../Responses/GetClientDetailedInfo.cs | 4 ++-- .../{ => Query}/Responses/GetClientInfo.cs | 4 ++-- .../Responses/GetCurrentFileTransfer.cs | 2 +- .../{ => Query}/Responses/GetDbClientInfo.cs | 4 ++-- .../{ => Query}/Responses/GetFileInfo.cs | 2 +- .../{ => Query}/Responses/GetFiles.cs | 2 +- .../{ => Query}/Responses/GetServerGroup.cs | 2 +- .../Responses/GetServerGroupClientList.cs | 2 +- .../Responses/GetServerGroupListInfo.cs | 4 ++-- .../{ => Query}/Responses/GetServerListInfo.cs | 2 +- .../{ => Query}/Responses/InitDownload.cs | 2 +- .../{ => Query}/Responses/InitUpload.cs | 2 +- .../{ => Query}/Responses/Response.cs | 2 +- .../{ => Query}/Responses/WhoAmI.cs | 2 +- src/TeamSpeak3QueryApi/TeamSpeakClient.cs | 11 ++++++----- 46 files changed, 67 insertions(+), 64 deletions(-) rename src/TeamSpeak3QueryApi/Enums/{TeamspeakConnectionType.cs => Protocol.cs} (79%) rename src/TeamSpeak3QueryApi/{ => Query}/Enums/ClientType.cs (65%) rename src/TeamSpeak3QueryApi/{ => Query}/Enums/GetChannelOptions.cs (81%) rename src/TeamSpeak3QueryApi/{ => Query}/Enums/GetClientOptions.cs (85%) rename src/TeamSpeak3QueryApi/{ => Query}/Enums/GetServerOptions.cs (79%) rename src/TeamSpeak3QueryApi/{ => Query}/Enums/KickOrigin.cs (64%) rename src/TeamSpeak3QueryApi/{ => Query}/Enums/ManualEnums.cs (98%) rename src/TeamSpeak3QueryApi/{ => Query}/Enums/MessageTarget.cs (70%) rename src/TeamSpeak3QueryApi/{ => Query}/Enums/ReasonId.cs (86%) rename src/TeamSpeak3QueryApi/{ => Query}/Enums/ServerGroupType.cs (73%) rename src/TeamSpeak3QueryApi/{ => Query}/Parameters/IParameterValue.cs (88%) rename src/TeamSpeak3QueryApi/{ => Query}/Parameters/Parameter.cs (98%) rename src/TeamSpeak3QueryApi/{ => Query}/Parameters/ParameterValue.cs (98%) rename src/TeamSpeak3QueryApi/{ => Query}/Parameters/ParameterValueArray.cs (97%) rename src/TeamSpeak3QueryApi/{ => Query}/Responses/ClientBan.cs (69%) rename src/TeamSpeak3QueryApi/{ => Query}/Responses/CreatedChannel.cs (69%) rename src/TeamSpeak3QueryApi/{ => Query}/Responses/EditChannelInfo.cs (96%) rename src/TeamSpeak3QueryApi/{ => Query}/Responses/FoundChannel.cs (78%) rename src/TeamSpeak3QueryApi/{ => Query}/Responses/GetChannelInfo.cs (96%) rename src/TeamSpeak3QueryApi/{ => Query}/Responses/GetChannelListInfo.cs (94%) rename src/TeamSpeak3QueryApi/{ => Query}/Responses/GetClientDetailedInfo.cs (96%) rename src/TeamSpeak3QueryApi/{ => Query}/Responses/GetClientInfo.cs (94%) rename src/TeamSpeak3QueryApi/{ => Query}/Responses/GetCurrentFileTransfer.cs (94%) rename src/TeamSpeak3QueryApi/{ => Query}/Responses/GetDbClientInfo.cs (93%) rename src/TeamSpeak3QueryApi/{ => Query}/Responses/GetFileInfo.cs (86%) rename src/TeamSpeak3QueryApi/{ => Query}/Responses/GetFiles.cs (88%) rename src/TeamSpeak3QueryApi/{ => Query}/Responses/GetServerGroup.cs (83%) rename src/TeamSpeak3QueryApi/{ => Query}/Responses/GetServerGroupClientList.cs (74%) rename src/TeamSpeak3QueryApi/{ => Query}/Responses/GetServerGroupListInfo.cs (89%) rename src/TeamSpeak3QueryApi/{ => Query}/Responses/GetServerListInfo.cs (95%) rename src/TeamSpeak3QueryApi/{ => Query}/Responses/InitDownload.cs (90%) rename src/TeamSpeak3QueryApi/{ => Query}/Responses/InitUpload.cs (89%) rename src/TeamSpeak3QueryApi/{ => Query}/Responses/Response.cs (69%) rename src/TeamSpeak3QueryApi/{ => Query}/Responses/WhoAmI.cs (95%) diff --git a/src/TeamSpeak3QueryApi.Demo/Program.cs b/src/TeamSpeak3QueryApi.Demo/Program.cs index 7670c90..d994e56 100644 --- a/src/TeamSpeak3QueryApi.Demo/Program.cs +++ b/src/TeamSpeak3QueryApi.Demo/Program.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using TeamSpeak3QueryApi.Net.Enums; using TeamSpeak3QueryApi.Net.Notifications; +using TeamSpeak3QueryApi.Net.Query.Enums; namespace TeamSpeak3QueryApi.Net.Demo { @@ -20,7 +21,7 @@ static async Task Main(string[] args) var password = loginData[2].Trim(); // Ssh connection - var rc = new TeamSpeakClient(host, TeamspeakConnectionType.SSH); + var rc = new TeamSpeakClient(host, Protocol.SSH); rc.ConnectSsh(user, password); // Telnet connection diff --git a/src/TeamSpeak3QueryApi/DataProxy.cs b/src/TeamSpeak3QueryApi/DataProxy.cs index 63b1f45..926189e 100644 --- a/src/TeamSpeak3QueryApi/DataProxy.cs +++ b/src/TeamSpeak3QueryApi/DataProxy.cs @@ -7,6 +7,7 @@ using TeamSpeak3QueryApi.Net.Enums; using TeamSpeak3QueryApi.Net.Interfaces; using TeamSpeak3QueryApi.Net.Query; +using TeamSpeak3QueryApi.Net.Query.Enums; namespace TeamSpeak3QueryApi.Net { diff --git a/src/TeamSpeak3QueryApi/Enums/TeamspeakConnectionType.cs b/src/TeamSpeak3QueryApi/Enums/Protocol.cs similarity index 79% rename from src/TeamSpeak3QueryApi/Enums/TeamspeakConnectionType.cs rename to src/TeamSpeak3QueryApi/Enums/Protocol.cs index 89a1d0c..8177580 100644 --- a/src/TeamSpeak3QueryApi/Enums/TeamspeakConnectionType.cs +++ b/src/TeamSpeak3QueryApi/Enums/Protocol.cs @@ -4,7 +4,7 @@ namespace TeamSpeak3QueryApi.Net.Enums { - public enum TeamspeakConnectionType + public enum Protocol { Telnet = 0, SSH = 1 diff --git a/src/TeamSpeak3QueryApi/Notifications/ChannelCreated.cs b/src/TeamSpeak3QueryApi/Notifications/ChannelCreated.cs index f705f59..f7a6295 100644 --- a/src/TeamSpeak3QueryApi/Notifications/ChannelCreated.cs +++ b/src/TeamSpeak3QueryApi/Notifications/ChannelCreated.cs @@ -1,5 +1,5 @@ using System; -using TeamSpeak3QueryApi.Net.Enums; +using TeamSpeak3QueryApi.Net.Query.Enums; namespace TeamSpeak3QueryApi.Net.Notifications { diff --git a/src/TeamSpeak3QueryApi/Notifications/ChannelEdited.cs b/src/TeamSpeak3QueryApi/Notifications/ChannelEdited.cs index 8ea2824..d3eee7d 100644 --- a/src/TeamSpeak3QueryApi/Notifications/ChannelEdited.cs +++ b/src/TeamSpeak3QueryApi/Notifications/ChannelEdited.cs @@ -1,5 +1,5 @@ using System; -using TeamSpeak3QueryApi.Net.Enums; +using TeamSpeak3QueryApi.Net.Query.Enums; namespace TeamSpeak3QueryApi.Net.Notifications { diff --git a/src/TeamSpeak3QueryApi/Notifications/ClientEnterView.cs b/src/TeamSpeak3QueryApi/Notifications/ClientEnterView.cs index 10fee21..fc2f823 100644 --- a/src/TeamSpeak3QueryApi/Notifications/ClientEnterView.cs +++ b/src/TeamSpeak3QueryApi/Notifications/ClientEnterView.cs @@ -1,5 +1,5 @@ using System; -using TeamSpeak3QueryApi.Net.Enums; +using TeamSpeak3QueryApi.Net.Query.Enums; namespace TeamSpeak3QueryApi.Net.Notifications { diff --git a/src/TeamSpeak3QueryApi/Notifications/ClientLeftView.cs b/src/TeamSpeak3QueryApi/Notifications/ClientLeftView.cs index b1ccdd4..3623209 100644 --- a/src/TeamSpeak3QueryApi/Notifications/ClientLeftView.cs +++ b/src/TeamSpeak3QueryApi/Notifications/ClientLeftView.cs @@ -1,5 +1,5 @@ using System; -using TeamSpeak3QueryApi.Net.Enums; +using TeamSpeak3QueryApi.Net.Query.Enums; namespace TeamSpeak3QueryApi.Net.Notifications { diff --git a/src/TeamSpeak3QueryApi/Notifications/InvokerInformation.cs b/src/TeamSpeak3QueryApi/Notifications/InvokerInformation.cs index cce4c0f..2236a73 100644 --- a/src/TeamSpeak3QueryApi/Notifications/InvokerInformation.cs +++ b/src/TeamSpeak3QueryApi/Notifications/InvokerInformation.cs @@ -1,4 +1,4 @@ -using TeamSpeak3QueryApi.Net.Enums; +using TeamSpeak3QueryApi.Net.Query.Enums; namespace TeamSpeak3QueryApi.Net.Notifications { diff --git a/src/TeamSpeak3QueryApi/Notifications/ServerEdited.cs b/src/TeamSpeak3QueryApi/Notifications/ServerEdited.cs index 0371873..aad5e23 100644 --- a/src/TeamSpeak3QueryApi/Notifications/ServerEdited.cs +++ b/src/TeamSpeak3QueryApi/Notifications/ServerEdited.cs @@ -1,5 +1,5 @@ using System; -using TeamSpeak3QueryApi.Net.Enums; +using TeamSpeak3QueryApi.Net.Query.Enums; namespace TeamSpeak3QueryApi.Net.Notifications { diff --git a/src/TeamSpeak3QueryApi/Notifications/TextMessage.cs b/src/TeamSpeak3QueryApi/Notifications/TextMessage.cs index 4a9bd38..6c3102e 100644 --- a/src/TeamSpeak3QueryApi/Notifications/TextMessage.cs +++ b/src/TeamSpeak3QueryApi/Notifications/TextMessage.cs @@ -1,4 +1,4 @@ -using TeamSpeak3QueryApi.Net.Enums; +using TeamSpeak3QueryApi.Net.Query.Enums; namespace TeamSpeak3QueryApi.Net.Notifications { @@ -11,6 +11,6 @@ public class TextMessage : InvokerInformation public string Message; [QuerySerialize("target")] - public int TargetClientId; // (clid des Empfängers; Parameter nur bei textprivate vorhanden) + public int TargetClientId; // (clid des Empfängers; Parameter nur bei textprivate vorhanden) } } diff --git a/src/TeamSpeak3QueryApi/Enums/ClientType.cs b/src/TeamSpeak3QueryApi/Query/Enums/ClientType.cs similarity index 65% rename from src/TeamSpeak3QueryApi/Enums/ClientType.cs rename to src/TeamSpeak3QueryApi/Query/Enums/ClientType.cs index e51f039..aef817d 100644 --- a/src/TeamSpeak3QueryApi/Enums/ClientType.cs +++ b/src/TeamSpeak3QueryApi/Query/Enums/ClientType.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Enums +namespace TeamSpeak3QueryApi.Net.Query.Enums { public enum ClientType { diff --git a/src/TeamSpeak3QueryApi/Enums/GetChannelOptions.cs b/src/TeamSpeak3QueryApi/Query/Enums/GetChannelOptions.cs similarity index 81% rename from src/TeamSpeak3QueryApi/Enums/GetChannelOptions.cs rename to src/TeamSpeak3QueryApi/Query/Enums/GetChannelOptions.cs index 8468b90..169a5be 100644 --- a/src/TeamSpeak3QueryApi/Enums/GetChannelOptions.cs +++ b/src/TeamSpeak3QueryApi/Query/Enums/GetChannelOptions.cs @@ -1,6 +1,6 @@ using System; -namespace TeamSpeak3QueryApi.Net.Enums +namespace TeamSpeak3QueryApi.Net.Query.Enums { [Flags] public enum GetChannelOptions diff --git a/src/TeamSpeak3QueryApi/Enums/GetClientOptions.cs b/src/TeamSpeak3QueryApi/Query/Enums/GetClientOptions.cs similarity index 85% rename from src/TeamSpeak3QueryApi/Enums/GetClientOptions.cs rename to src/TeamSpeak3QueryApi/Query/Enums/GetClientOptions.cs index b500d0e..738b323 100644 --- a/src/TeamSpeak3QueryApi/Enums/GetClientOptions.cs +++ b/src/TeamSpeak3QueryApi/Query/Enums/GetClientOptions.cs @@ -1,6 +1,6 @@ using System; -namespace TeamSpeak3QueryApi.Net.Enums +namespace TeamSpeak3QueryApi.Net.Query.Enums { [Flags] public enum GetClientOptions diff --git a/src/TeamSpeak3QueryApi/Enums/GetServerOptions.cs b/src/TeamSpeak3QueryApi/Query/Enums/GetServerOptions.cs similarity index 79% rename from src/TeamSpeak3QueryApi/Enums/GetServerOptions.cs rename to src/TeamSpeak3QueryApi/Query/Enums/GetServerOptions.cs index c72cde8..6f320b7 100644 --- a/src/TeamSpeak3QueryApi/Enums/GetServerOptions.cs +++ b/src/TeamSpeak3QueryApi/Query/Enums/GetServerOptions.cs @@ -1,6 +1,6 @@ using System; -namespace TeamSpeak3QueryApi.Net.Enums +namespace TeamSpeak3QueryApi.Net.Query.Enums { [Flags] public enum GetServerOptions diff --git a/src/TeamSpeak3QueryApi/Enums/KickOrigin.cs b/src/TeamSpeak3QueryApi/Query/Enums/KickOrigin.cs similarity index 64% rename from src/TeamSpeak3QueryApi/Enums/KickOrigin.cs rename to src/TeamSpeak3QueryApi/Query/Enums/KickOrigin.cs index 4e626d4..95c5ac9 100644 --- a/src/TeamSpeak3QueryApi/Enums/KickOrigin.cs +++ b/src/TeamSpeak3QueryApi/Query/Enums/KickOrigin.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Enums +namespace TeamSpeak3QueryApi.Net.Query.Enums { public enum KickOrigin { diff --git a/src/TeamSpeak3QueryApi/Enums/ManualEnums.cs b/src/TeamSpeak3QueryApi/Query/Enums/ManualEnums.cs similarity index 98% rename from src/TeamSpeak3QueryApi/Enums/ManualEnums.cs rename to src/TeamSpeak3QueryApi/Query/Enums/ManualEnums.cs index 934038f..b3b54ae 100644 --- a/src/TeamSpeak3QueryApi/Enums/ManualEnums.cs +++ b/src/TeamSpeak3QueryApi/Query/Enums/ManualEnums.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Enums +namespace TeamSpeak3QueryApi.Net.Query.Enums { public enum HostMessageMode { diff --git a/src/TeamSpeak3QueryApi/Enums/MessageTarget.cs b/src/TeamSpeak3QueryApi/Query/Enums/MessageTarget.cs similarity index 70% rename from src/TeamSpeak3QueryApi/Enums/MessageTarget.cs rename to src/TeamSpeak3QueryApi/Query/Enums/MessageTarget.cs index 993d157..a584b65 100644 --- a/src/TeamSpeak3QueryApi/Enums/MessageTarget.cs +++ b/src/TeamSpeak3QueryApi/Query/Enums/MessageTarget.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Enums +namespace TeamSpeak3QueryApi.Net.Query.Enums { public enum MessageTarget { diff --git a/src/TeamSpeak3QueryApi/Enums/ReasonId.cs b/src/TeamSpeak3QueryApi/Query/Enums/ReasonId.cs similarity index 86% rename from src/TeamSpeak3QueryApi/Enums/ReasonId.cs rename to src/TeamSpeak3QueryApi/Query/Enums/ReasonId.cs index 7e37598..495eb92 100644 --- a/src/TeamSpeak3QueryApi/Enums/ReasonId.cs +++ b/src/TeamSpeak3QueryApi/Query/Enums/ReasonId.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Enums +namespace TeamSpeak3QueryApi.Net.Query.Enums { public enum ReasonId { diff --git a/src/TeamSpeak3QueryApi/Enums/ServerGroupType.cs b/src/TeamSpeak3QueryApi/Query/Enums/ServerGroupType.cs similarity index 73% rename from src/TeamSpeak3QueryApi/Enums/ServerGroupType.cs rename to src/TeamSpeak3QueryApi/Query/Enums/ServerGroupType.cs index 9c03c19..7d3052e 100644 --- a/src/TeamSpeak3QueryApi/Enums/ServerGroupType.cs +++ b/src/TeamSpeak3QueryApi/Query/Enums/ServerGroupType.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Enums +namespace TeamSpeak3QueryApi.Net.Query.Enums { public enum ServerGroupType { diff --git a/src/TeamSpeak3QueryApi/Parameters/IParameterValue.cs b/src/TeamSpeak3QueryApi/Query/Parameters/IParameterValue.cs similarity index 88% rename from src/TeamSpeak3QueryApi/Parameters/IParameterValue.cs rename to src/TeamSpeak3QueryApi/Query/Parameters/IParameterValue.cs index b774ea5..e613f50 100644 --- a/src/TeamSpeak3QueryApi/Parameters/IParameterValue.cs +++ b/src/TeamSpeak3QueryApi/Query/Parameters/IParameterValue.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Parameters +namespace TeamSpeak3QueryApi.Net.Query.Parameters { /// Represents an abstraction of a parameter value. public interface IParameterValue diff --git a/src/TeamSpeak3QueryApi/Parameters/Parameter.cs b/src/TeamSpeak3QueryApi/Query/Parameters/Parameter.cs similarity index 98% rename from src/TeamSpeak3QueryApi/Parameters/Parameter.cs rename to src/TeamSpeak3QueryApi/Query/Parameters/Parameter.cs index 24010f5..eac68fd 100644 --- a/src/TeamSpeak3QueryApi/Parameters/Parameter.cs +++ b/src/TeamSpeak3QueryApi/Query/Parameters/Parameter.cs @@ -1,7 +1,7 @@ using System; using System.Diagnostics; -namespace TeamSpeak3QueryApi.Net.Parameters +namespace TeamSpeak3QueryApi.Net.Query.Parameters { /// Represents a Query API parameter. public class Parameter diff --git a/src/TeamSpeak3QueryApi/Parameters/ParameterValue.cs b/src/TeamSpeak3QueryApi/Query/Parameters/ParameterValue.cs similarity index 98% rename from src/TeamSpeak3QueryApi/Parameters/ParameterValue.cs rename to src/TeamSpeak3QueryApi/Query/Parameters/ParameterValue.cs index 09f9c53..8782dbe 100644 --- a/src/TeamSpeak3QueryApi/Parameters/ParameterValue.cs +++ b/src/TeamSpeak3QueryApi/Query/Parameters/ParameterValue.cs @@ -1,7 +1,7 @@ using System.Globalization; using TeamSpeak3QueryApi.Net.Extensions; -namespace TeamSpeak3QueryApi.Net.Parameters +namespace TeamSpeak3QueryApi.Net.Query.Parameters { /// Represents the value of a parameter which consits of a single value. public class ParameterValue : IParameterValue diff --git a/src/TeamSpeak3QueryApi/Parameters/ParameterValueArray.cs b/src/TeamSpeak3QueryApi/Query/Parameters/ParameterValueArray.cs similarity index 97% rename from src/TeamSpeak3QueryApi/Parameters/ParameterValueArray.cs rename to src/TeamSpeak3QueryApi/Query/Parameters/ParameterValueArray.cs index 7b1f1df..625391b 100644 --- a/src/TeamSpeak3QueryApi/Parameters/ParameterValueArray.cs +++ b/src/TeamSpeak3QueryApi/Query/Parameters/ParameterValueArray.cs @@ -1,6 +1,6 @@ using System.Linq; -namespace TeamSpeak3QueryApi.Net.Parameters +namespace TeamSpeak3QueryApi.Net.Query.Parameters { /// Represents the value of a parameter which consits of a multiple values. public class ParameterValueArray : IParameterValue diff --git a/src/TeamSpeak3QueryApi/Query/QueryClient.cs b/src/TeamSpeak3QueryApi/Query/QueryClient.cs index 620099c..60c7c60 100644 --- a/src/TeamSpeak3QueryApi/Query/QueryClient.cs +++ b/src/TeamSpeak3QueryApi/Query/QueryClient.cs @@ -15,7 +15,7 @@ using TeamSpeak3QueryApi.Net.Enums; using TeamSpeak3QueryApi.Net.Extensions; using TeamSpeak3QueryApi.Net.Notifications; -using TeamSpeak3QueryApi.Net.Parameters; +using TeamSpeak3QueryApi.Net.Query.Parameters; namespace TeamSpeak3QueryApi.Net.Query { @@ -37,7 +37,7 @@ public class QueryClient : IDisposable /// The remote port of the Query API client. public int Port { get; } - public TeamspeakConnectionType ConnectionType { get; set; } + public Protocol ConnectionType { get; set; } public bool IsConnected { get; private set; } @@ -62,19 +62,19 @@ public class QueryClient : IDisposable #region Ctors /// Creates a new instance of using the and . - public QueryClient(TeamspeakConnectionType type) + public QueryClient(Protocol type) : this(DefaultHost, DefaultPort, type) { } /// Creates a new instance of using the provided host and the . /// The host name of the remote server. - public QueryClient(string hostName, TeamspeakConnectionType type) + public QueryClient(string hostName, Protocol type) : this(hostName, DefaultPort, type) { } /// Creates a new instance of using the provided host TCP port. /// The host name of the remote server. /// The TCP port of the Query API server. - public QueryClient(string hostName, int port, TeamspeakConnectionType type) + public QueryClient(string hostName, int port, Protocol type) { if (string.IsNullOrWhiteSpace(hostName)) throw new ArgumentNullException(nameof(hostName)); @@ -94,7 +94,7 @@ public QueryClient(string hostName, int port, TeamspeakConnectionType type) /// An awaitable . public async Task ConnectAsync() { - if(ConnectionType != TeamspeakConnectionType.Telnet) + if(ConnectionType != Protocol.Telnet) throw new InvalidOperationException("ConnectAsync Method without parameters can only be used with telnet Query. Please use ConnectSsh method."); await Client.ConnectAsync(Host, Port).ConfigureAwait(false); @@ -409,7 +409,7 @@ private CancellationTokenSource ResponseProcessingLoop() string line = null; try { - if(ConnectionType == TeamspeakConnectionType.SSH) + if(ConnectionType == Protocol.SSH) { line = _shell.ReadLine(); } @@ -472,7 +472,7 @@ private async Task CheckQueueAsync() { _currentCommand = _queue.Dequeue(); Debug.WriteLine($"{ConnectionType}: {_currentCommand.SentText}"); - await _writer.WriteLineAsync((ConnectionType == TeamspeakConnectionType.Telnet ? _currentCommand.SentText : _currentCommand.SentText + "\n")).ConfigureAwait(false); + await _writer.WriteLineAsync((ConnectionType == Protocol.Telnet ? _currentCommand.SentText : _currentCommand.SentText + "\n")).ConfigureAwait(false); await _writer.FlushAsync().ConfigureAwait(false); } } diff --git a/src/TeamSpeak3QueryApi/Query/QueryCommand.cs b/src/TeamSpeak3QueryApi/Query/QueryCommand.cs index 8e770fd..b957b9b 100644 --- a/src/TeamSpeak3QueryApi/Query/QueryCommand.cs +++ b/src/TeamSpeak3QueryApi/Query/QueryCommand.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; using System.Threading.Tasks; -using TeamSpeak3QueryApi.Net.Parameters; +using TeamSpeak3QueryApi.Net.Query.Parameters; namespace TeamSpeak3QueryApi.Net.Query { diff --git a/src/TeamSpeak3QueryApi/Responses/ClientBan.cs b/src/TeamSpeak3QueryApi/Query/Responses/ClientBan.cs similarity index 69% rename from src/TeamSpeak3QueryApi/Responses/ClientBan.cs rename to src/TeamSpeak3QueryApi/Query/Responses/ClientBan.cs index 71bb8d5..8528ceb 100644 --- a/src/TeamSpeak3QueryApi/Responses/ClientBan.cs +++ b/src/TeamSpeak3QueryApi/Query/Responses/ClientBan.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Responses +namespace TeamSpeak3QueryApi.Net.Query.Responses { public class ClientBan : Response { diff --git a/src/TeamSpeak3QueryApi/Responses/CreatedChannel.cs b/src/TeamSpeak3QueryApi/Query/Responses/CreatedChannel.cs similarity index 69% rename from src/TeamSpeak3QueryApi/Responses/CreatedChannel.cs rename to src/TeamSpeak3QueryApi/Query/Responses/CreatedChannel.cs index a8bb4de..7ebdc36 100644 --- a/src/TeamSpeak3QueryApi/Responses/CreatedChannel.cs +++ b/src/TeamSpeak3QueryApi/Query/Responses/CreatedChannel.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Responses +namespace TeamSpeak3QueryApi.Net.Query.Responses { public class CreatedChannel : Response { diff --git a/src/TeamSpeak3QueryApi/Responses/EditChannelInfo.cs b/src/TeamSpeak3QueryApi/Query/Responses/EditChannelInfo.cs similarity index 96% rename from src/TeamSpeak3QueryApi/Responses/EditChannelInfo.cs rename to src/TeamSpeak3QueryApi/Query/Responses/EditChannelInfo.cs index 7b254f1..3812515 100644 --- a/src/TeamSpeak3QueryApi/Responses/EditChannelInfo.cs +++ b/src/TeamSpeak3QueryApi/Query/Responses/EditChannelInfo.cs @@ -1,7 +1,7 @@ using System; -using TeamSpeak3QueryApi.Net.Enums; +using TeamSpeak3QueryApi.Net.Query.Enums; -namespace TeamSpeak3QueryApi.Net.Responses +namespace TeamSpeak3QueryApi.Net.Query.Responses { public class EditChannelInfo : Response { diff --git a/src/TeamSpeak3QueryApi/Responses/FoundChannel.cs b/src/TeamSpeak3QueryApi/Query/Responses/FoundChannel.cs similarity index 78% rename from src/TeamSpeak3QueryApi/Responses/FoundChannel.cs rename to src/TeamSpeak3QueryApi/Query/Responses/FoundChannel.cs index b4ad866..7e6f9f3 100644 --- a/src/TeamSpeak3QueryApi/Responses/FoundChannel.cs +++ b/src/TeamSpeak3QueryApi/Query/Responses/FoundChannel.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Responses +namespace TeamSpeak3QueryApi.Net.Query.Responses { public class FoundChannel : Response { diff --git a/src/TeamSpeak3QueryApi/Responses/GetChannelInfo.cs b/src/TeamSpeak3QueryApi/Query/Responses/GetChannelInfo.cs similarity index 96% rename from src/TeamSpeak3QueryApi/Responses/GetChannelInfo.cs rename to src/TeamSpeak3QueryApi/Query/Responses/GetChannelInfo.cs index 5fe4ace..8e9979c 100644 --- a/src/TeamSpeak3QueryApi/Responses/GetChannelInfo.cs +++ b/src/TeamSpeak3QueryApi/Query/Responses/GetChannelInfo.cs @@ -1,7 +1,7 @@ using System; -using TeamSpeak3QueryApi.Net.Enums; +using TeamSpeak3QueryApi.Net.Query.Enums; -namespace TeamSpeak3QueryApi.Net.Responses +namespace TeamSpeak3QueryApi.Net.Query.Responses { public class GetChannelInfo : Response { diff --git a/src/TeamSpeak3QueryApi/Responses/GetChannelListInfo.cs b/src/TeamSpeak3QueryApi/Query/Responses/GetChannelListInfo.cs similarity index 94% rename from src/TeamSpeak3QueryApi/Responses/GetChannelListInfo.cs rename to src/TeamSpeak3QueryApi/Query/Responses/GetChannelListInfo.cs index 06a921f..621028f 100644 --- a/src/TeamSpeak3QueryApi/Responses/GetChannelListInfo.cs +++ b/src/TeamSpeak3QueryApi/Query/Responses/GetChannelListInfo.cs @@ -1,7 +1,7 @@ using System; -using TeamSpeak3QueryApi.Net.Enums; +using TeamSpeak3QueryApi.Net.Query.Enums; -namespace TeamSpeak3QueryApi.Net.Responses +namespace TeamSpeak3QueryApi.Net.Query.Responses { public class GetChannelListInfo : Response { diff --git a/src/TeamSpeak3QueryApi/Responses/GetClientDetailedInfo.cs b/src/TeamSpeak3QueryApi/Query/Responses/GetClientDetailedInfo.cs similarity index 96% rename from src/TeamSpeak3QueryApi/Responses/GetClientDetailedInfo.cs rename to src/TeamSpeak3QueryApi/Query/Responses/GetClientDetailedInfo.cs index 29c14fe..b91ef70 100644 --- a/src/TeamSpeak3QueryApi/Responses/GetClientDetailedInfo.cs +++ b/src/TeamSpeak3QueryApi/Query/Responses/GetClientDetailedInfo.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; using System.Linq; -using TeamSpeak3QueryApi.Net.Enums; +using TeamSpeak3QueryApi.Net.Query.Enums; -namespace TeamSpeak3QueryApi.Net.Responses +namespace TeamSpeak3QueryApi.Net.Query.Responses { public class GetClientDetailedInfo : Response { diff --git a/src/TeamSpeak3QueryApi/Responses/GetClientInfo.cs b/src/TeamSpeak3QueryApi/Query/Responses/GetClientInfo.cs similarity index 94% rename from src/TeamSpeak3QueryApi/Responses/GetClientInfo.cs rename to src/TeamSpeak3QueryApi/Query/Responses/GetClientInfo.cs index 9afef25..2407de8 100644 --- a/src/TeamSpeak3QueryApi/Responses/GetClientInfo.cs +++ b/src/TeamSpeak3QueryApi/Query/Responses/GetClientInfo.cs @@ -1,8 +1,8 @@ using System; using System.Collections.Generic; -using TeamSpeak3QueryApi.Net.Enums; +using TeamSpeak3QueryApi.Net.Query.Enums; -namespace TeamSpeak3QueryApi.Net.Responses +namespace TeamSpeak3QueryApi.Net.Query.Responses { public class GetClientInfo : Response { diff --git a/src/TeamSpeak3QueryApi/Responses/GetCurrentFileTransfer.cs b/src/TeamSpeak3QueryApi/Query/Responses/GetCurrentFileTransfer.cs similarity index 94% rename from src/TeamSpeak3QueryApi/Responses/GetCurrentFileTransfer.cs rename to src/TeamSpeak3QueryApi/Query/Responses/GetCurrentFileTransfer.cs index b1e3aad..877cce4 100644 --- a/src/TeamSpeak3QueryApi/Responses/GetCurrentFileTransfer.cs +++ b/src/TeamSpeak3QueryApi/Query/Responses/GetCurrentFileTransfer.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text; -namespace TeamSpeak3QueryApi.Net.Responses +namespace TeamSpeak3QueryApi.Net.Query.Responses { public class GetCurrentFileTransfer : Response { diff --git a/src/TeamSpeak3QueryApi/Responses/GetDbClientInfo.cs b/src/TeamSpeak3QueryApi/Query/Responses/GetDbClientInfo.cs similarity index 93% rename from src/TeamSpeak3QueryApi/Responses/GetDbClientInfo.cs rename to src/TeamSpeak3QueryApi/Query/Responses/GetDbClientInfo.cs index 94c6596..a6df532 100644 --- a/src/TeamSpeak3QueryApi/Responses/GetDbClientInfo.cs +++ b/src/TeamSpeak3QueryApi/Query/Responses/GetDbClientInfo.cs @@ -1,7 +1,7 @@ -using System; +using System; using System.Collections.Generic; -namespace TeamSpeak3QueryApi.Net.Responses +namespace TeamSpeak3QueryApi.Net.Query.Responses { public class GetDbClientInfo : Response { diff --git a/src/TeamSpeak3QueryApi/Responses/GetFileInfo.cs b/src/TeamSpeak3QueryApi/Query/Responses/GetFileInfo.cs similarity index 86% rename from src/TeamSpeak3QueryApi/Responses/GetFileInfo.cs rename to src/TeamSpeak3QueryApi/Query/Responses/GetFileInfo.cs index 216f182..abb12dc 100644 --- a/src/TeamSpeak3QueryApi/Responses/GetFileInfo.cs +++ b/src/TeamSpeak3QueryApi/Query/Responses/GetFileInfo.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text; -namespace TeamSpeak3QueryApi.Net.Responses +namespace TeamSpeak3QueryApi.Net.Query.Responses { public class GetFileInfo : Response { diff --git a/src/TeamSpeak3QueryApi/Responses/GetFiles.cs b/src/TeamSpeak3QueryApi/Query/Responses/GetFiles.cs similarity index 88% rename from src/TeamSpeak3QueryApi/Responses/GetFiles.cs rename to src/TeamSpeak3QueryApi/Query/Responses/GetFiles.cs index 83674ea..168e322 100644 --- a/src/TeamSpeak3QueryApi/Responses/GetFiles.cs +++ b/src/TeamSpeak3QueryApi/Query/Responses/GetFiles.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text; -namespace TeamSpeak3QueryApi.Net.Responses +namespace TeamSpeak3QueryApi.Net.Query.Responses { public class GetFiles : Response { diff --git a/src/TeamSpeak3QueryApi/Responses/GetServerGroup.cs b/src/TeamSpeak3QueryApi/Query/Responses/GetServerGroup.cs similarity index 83% rename from src/TeamSpeak3QueryApi/Responses/GetServerGroup.cs rename to src/TeamSpeak3QueryApi/Query/Responses/GetServerGroup.cs index 6938475..757fe07 100644 --- a/src/TeamSpeak3QueryApi/Responses/GetServerGroup.cs +++ b/src/TeamSpeak3QueryApi/Query/Responses/GetServerGroup.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Responses +namespace TeamSpeak3QueryApi.Net.Query.Responses { public class GetServerGroup : Response { diff --git a/src/TeamSpeak3QueryApi/Responses/GetServerGroupClientList.cs b/src/TeamSpeak3QueryApi/Query/Responses/GetServerGroupClientList.cs similarity index 74% rename from src/TeamSpeak3QueryApi/Responses/GetServerGroupClientList.cs rename to src/TeamSpeak3QueryApi/Query/Responses/GetServerGroupClientList.cs index 4bc1f4f..add70b4 100644 --- a/src/TeamSpeak3QueryApi/Responses/GetServerGroupClientList.cs +++ b/src/TeamSpeak3QueryApi/Query/Responses/GetServerGroupClientList.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Responses +namespace TeamSpeak3QueryApi.Net.Query.Responses { public class GetServerGroupClientList : Response { diff --git a/src/TeamSpeak3QueryApi/Responses/GetServerGroupListInfo.cs b/src/TeamSpeak3QueryApi/Query/Responses/GetServerGroupListInfo.cs similarity index 89% rename from src/TeamSpeak3QueryApi/Responses/GetServerGroupListInfo.cs rename to src/TeamSpeak3QueryApi/Query/Responses/GetServerGroupListInfo.cs index 17151bc..39b2880 100644 --- a/src/TeamSpeak3QueryApi/Responses/GetServerGroupListInfo.cs +++ b/src/TeamSpeak3QueryApi/Query/Responses/GetServerGroupListInfo.cs @@ -1,6 +1,6 @@ -using TeamSpeak3QueryApi.Net.Enums; +using TeamSpeak3QueryApi.Net.Query.Enums; -namespace TeamSpeak3QueryApi.Net.Responses +namespace TeamSpeak3QueryApi.Net.Query.Responses { public class GetServerGroupListInfo : Response { diff --git a/src/TeamSpeak3QueryApi/Responses/GetServerListInfo.cs b/src/TeamSpeak3QueryApi/Query/Responses/GetServerListInfo.cs similarity index 95% rename from src/TeamSpeak3QueryApi/Responses/GetServerListInfo.cs rename to src/TeamSpeak3QueryApi/Query/Responses/GetServerListInfo.cs index 7cb3998..efc8756 100644 --- a/src/TeamSpeak3QueryApi/Responses/GetServerListInfo.cs +++ b/src/TeamSpeak3QueryApi/Query/Responses/GetServerListInfo.cs @@ -1,6 +1,6 @@ using System; -namespace TeamSpeak3QueryApi.Net.Responses +namespace TeamSpeak3QueryApi.Net.Query.Responses { public class GetServerListInfo : Response { diff --git a/src/TeamSpeak3QueryApi/Responses/InitDownload.cs b/src/TeamSpeak3QueryApi/Query/Responses/InitDownload.cs similarity index 90% rename from src/TeamSpeak3QueryApi/Responses/InitDownload.cs rename to src/TeamSpeak3QueryApi/Query/Responses/InitDownload.cs index dd80c92..b1ff8ce 100644 --- a/src/TeamSpeak3QueryApi/Responses/InitDownload.cs +++ b/src/TeamSpeak3QueryApi/Query/Responses/InitDownload.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text; -namespace TeamSpeak3QueryApi.Net.Responses +namespace TeamSpeak3QueryApi.Net.Query.Responses { public class InitDownload : Response { diff --git a/src/TeamSpeak3QueryApi/Responses/InitUpload.cs b/src/TeamSpeak3QueryApi/Query/Responses/InitUpload.cs similarity index 89% rename from src/TeamSpeak3QueryApi/Responses/InitUpload.cs rename to src/TeamSpeak3QueryApi/Query/Responses/InitUpload.cs index 7dcaed6..b057f3f 100644 --- a/src/TeamSpeak3QueryApi/Responses/InitUpload.cs +++ b/src/TeamSpeak3QueryApi/Query/Responses/InitUpload.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text; -namespace TeamSpeak3QueryApi.Net.Responses +namespace TeamSpeak3QueryApi.Net.Query.Responses { public class InitUpload : Response { diff --git a/src/TeamSpeak3QueryApi/Responses/Response.cs b/src/TeamSpeak3QueryApi/Query/Responses/Response.cs similarity index 69% rename from src/TeamSpeak3QueryApi/Responses/Response.cs rename to src/TeamSpeak3QueryApi/Query/Responses/Response.cs index eb0354a..bc34bd9 100644 --- a/src/TeamSpeak3QueryApi/Responses/Response.cs +++ b/src/TeamSpeak3QueryApi/Query/Responses/Response.cs @@ -1,6 +1,6 @@ using TeamSpeak3QueryApi.Net.Interfaces; -namespace TeamSpeak3QueryApi.Net.Responses +namespace TeamSpeak3QueryApi.Net.Query.Responses { public abstract class Response : ITeamSpeakSerializable { } diff --git a/src/TeamSpeak3QueryApi/Responses/WhoAmI.cs b/src/TeamSpeak3QueryApi/Query/Responses/WhoAmI.cs similarity index 95% rename from src/TeamSpeak3QueryApi/Responses/WhoAmI.cs rename to src/TeamSpeak3QueryApi/Query/Responses/WhoAmI.cs index 64804ba..5d54ac1 100644 --- a/src/TeamSpeak3QueryApi/Responses/WhoAmI.cs +++ b/src/TeamSpeak3QueryApi/Query/Responses/WhoAmI.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Responses +namespace TeamSpeak3QueryApi.Net.Query.Responses { public class WhoAmI : Response { diff --git a/src/TeamSpeak3QueryApi/TeamSpeakClient.cs b/src/TeamSpeak3QueryApi/TeamSpeakClient.cs index 1c4f341..2e6764a 100644 --- a/src/TeamSpeak3QueryApi/TeamSpeakClient.cs +++ b/src/TeamSpeak3QueryApi/TeamSpeakClient.cs @@ -7,13 +7,14 @@ using System.Text.RegularExpressions; using System.Threading.Tasks; using TeamSpeak3QueryApi.Net.FileTransfer; -using TeamSpeak3QueryApi.Net.Parameters; using TeamSpeak3QueryApi.Net.Query; -using TeamSpeak3QueryApi.Net.Responses; using TeamSpeak3QueryApi.Net.Enums; using TeamSpeak3QueryApi.Net.Notifications; using TeamSpeak3QueryApi.Net.Extensions; using System.Diagnostics; +using TeamSpeak3QueryApi.Net.Query.Parameters; +using TeamSpeak3QueryApi.Net.Query.Responses; +using TeamSpeak3QueryApi.Net.Query.Enums; namespace TeamSpeak3QueryApi.Net { @@ -30,19 +31,19 @@ public class TeamSpeakClient : IDisposable /// Creates a new instance of using the and . public TeamSpeakClient() - : this(QueryClient.DefaultHost, QueryClient.DefaultPort, TeamspeakConnectionType.Telnet) + : this(QueryClient.DefaultHost, QueryClient.DefaultPort, Protocol.Telnet) { } /// Creates a new instance of using the provided host and the . /// The host name of the remote server. - public TeamSpeakClient(string hostName, TeamspeakConnectionType type = TeamspeakConnectionType.Telnet) + public TeamSpeakClient(string hostName, Protocol type = Protocol.Telnet) : this(hostName, QueryClient.DefaultPort, type) { } /// Creates a new instance of using the provided host TCP port. /// The host name of the remote server. /// The TCP port of the Query API server. - public TeamSpeakClient(string hostName, int port, TeamspeakConnectionType type) + public TeamSpeakClient(string hostName, int port, Protocol type) { Client = new QueryClient(hostName, port, type); _fileTransferClient = new FileTransferClient(hostName); From e5a1b98128d4a01d021e13c771115cb5f649b530 Mon Sep 17 00:00:00 2001 From: Lukas Gundermann Date: Wed, 26 Aug 2020 13:19:45 +0200 Subject: [PATCH 09/14] added sub class for telnet and ssh --- src/TeamSpeak3QueryApi.Demo/Program.cs | 10 +- .../Query/Protocols/IProtocol.cs | 14 ++ .../Query/Protocols/SshProtocol.cs | 142 ++++++++++++ .../Query/Protocols/TelnetProtocol.cs | 142 ++++++++++++ src/TeamSpeak3QueryApi/Query/QueryClient.cs | 210 +++--------------- src/TeamSpeak3QueryApi/Query/QueryCommand.cs | 2 +- .../Query/QueryNotification.cs | 2 +- src/TeamSpeak3QueryApi/TeamSpeakClient.cs | 28 ++- 8 files changed, 355 insertions(+), 195 deletions(-) create mode 100644 src/TeamSpeak3QueryApi/Query/Protocols/IProtocol.cs create mode 100644 src/TeamSpeak3QueryApi/Query/Protocols/SshProtocol.cs create mode 100644 src/TeamSpeak3QueryApi/Query/Protocols/TelnetProtocol.cs diff --git a/src/TeamSpeak3QueryApi.Demo/Program.cs b/src/TeamSpeak3QueryApi.Demo/Program.cs index d994e56..35c31ab 100644 --- a/src/TeamSpeak3QueryApi.Demo/Program.cs +++ b/src/TeamSpeak3QueryApi.Demo/Program.cs @@ -21,13 +21,13 @@ static async Task Main(string[] args) var password = loginData[2].Trim(); // Ssh connection - var rc = new TeamSpeakClient(host, Protocol.SSH); - rc.ConnectSsh(user, password); + //var rc = new TeamSpeakClient(host, 10022, Protocol.SSH); + //rc.Connect(user, password); // Telnet connection - //var rc = new TeamSpeakClient(host); - //await rc.ConnectTelnetAsync(); - //await rc.LoginAsync(user, password); + var rc = new TeamSpeakClient(host); + await rc.ConnectAsync(); + await rc.LoginAsync(user, password); await rc.LoginAsync(user, password); await rc.UseServerAsync(1); diff --git a/src/TeamSpeak3QueryApi/Query/Protocols/IProtocol.cs b/src/TeamSpeak3QueryApi/Query/Protocols/IProtocol.cs new file mode 100644 index 0000000..51c701c --- /dev/null +++ b/src/TeamSpeak3QueryApi/Query/Protocols/IProtocol.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace TeamSpeak3QueryApi.Net.Query.Protocols +{ + public interface IProtocol + { + Task ConnectAsync(); + CancellationTokenSource Connect(string username, string password); + } +} diff --git a/src/TeamSpeak3QueryApi/Query/Protocols/SshProtocol.cs b/src/TeamSpeak3QueryApi/Query/Protocols/SshProtocol.cs new file mode 100644 index 0000000..dc4ec21 --- /dev/null +++ b/src/TeamSpeak3QueryApi/Query/Protocols/SshProtocol.cs @@ -0,0 +1,142 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Net.Sockets; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Renci.SshNet; +using Renci.SshNet.Common; +using TeamSpeak3QueryApi.Net.Enums; +using TeamSpeak3QueryApi.Net.Extensions; + +namespace TeamSpeak3QueryApi.Net.Query.Protocols +{ + public class SshProtocol : QueryClient, IProtocol + { + /// The default port which is used when no port is provided. + public const short DefaultPort = 10022; + + /// Creates a new instance of using the and . + public SshProtocol() + : this(DefaultHost, DefaultPort) + { } + + /// Creates a new instance of using the provided host and the . + /// The host name of the remote server. + public SshProtocol(string hostName) + : this(hostName, DefaultPort) + { } + /// Creates a new instance of using the provided host TCP port. + /// The host name of the remote server. + /// The TCP port of the Query API server. + public SshProtocol(string hostName, int port) + { + if (string.IsNullOrWhiteSpace(hostName)) + throw new ArgumentNullException(nameof(hostName)); + if (!ValidationHelper.ValidateTcpPort(port)) + throw new ArgumentOutOfRangeException(nameof(port)); + + Host = hostName; + Port = port; + ConnectionType = Protocol.SSH; + IsConnected = false; + Client = new TcpClient(); + } + + /// Connects to the Query API server. + /// An awaitable . + public override CancellationTokenSource Connect(string username, string password) + { + this.username = username; + + _sshClient = new SshClient(Host, Port, username, password); + _sshClient.Connect(); + + var terminalMode = new Dictionary(); + terminalMode.Add(TerminalModes.ECHO, 53); + + _shell = _sshClient.CreateShellStream("", 0, 0, 0, 0, 4096); + + _reader = new StreamReader(_shell, Encoding.UTF8, true, 1024, true); + _writer = new StreamWriter(_shell) { NewLine = "\n", AutoFlush = true }; + + var headline = _shell.Expect("\r\n", new TimeSpan(0, 0, 3)); + if (!headline.Contains("TS3")) + { + throw new QueryProtocolException("Telnet Query isn't a valid Teamspeak Query"); + } + _shell.Expect("\n", new TimeSpan(0, 0, 3)); // Ignore welcome message + _shell.Expect("\n", new TimeSpan(0, 0, 3)); // Ignore welcome message + + return ResponseProcessingLoop(); + } + + /// Connects to the Query API server. + /// An awaitable . + public override Task ConnectAsync() + { + throw new InvalidOperationException("ConnectAsync Method is not supported in ssh query. Please use the telnet query."); + } + + private CancellationTokenSource ResponseProcessingLoop() + { + var cts = _cts = new CancellationTokenSource(); + Task.Run(async () => + { + while (!cts.Token.IsCancellationRequested) + { + string line = null; + try + { + line = _shell.ReadLine(); + } + catch (OperationCanceledException) + { + break; + } + + if (line == null) + { + cts.Cancel(); + continue; + } + + if (string.IsNullOrWhiteSpace(line) || string.IsNullOrEmpty(line) || line.StartsWith(username)) + continue; + + var s = line.Trim(); + Debug.WriteLine(line); + + if (s.StartsWith("error", StringComparison.OrdinalIgnoreCase)) + { + Debug.Assert(_currentCommand != null); + + var error = ParseError(s); + _currentCommand.Error = error; + InvokeResponse(_currentCommand); + } + else if (s.StartsWith("notify", StringComparison.OrdinalIgnoreCase)) + { + s = s.Remove(0, "notify".Length); + var not = ParseNotification(s); + InvokeNotification(not); + } + else + { + Debug.Assert(_currentCommand != null); + _currentCommand.RawResponse = s; + _currentCommand.ResponseDictionary = ParseResponse(s); + } + } + + IsConnected = false; + OnConnectionLost?.Invoke(this, EventArgs.Empty); + OnDisconnected?.Invoke(this, EventArgs.Empty); + + }); + return cts; + } + } +} diff --git a/src/TeamSpeak3QueryApi/Query/Protocols/TelnetProtocol.cs b/src/TeamSpeak3QueryApi/Query/Protocols/TelnetProtocol.cs new file mode 100644 index 0000000..d3b26bb --- /dev/null +++ b/src/TeamSpeak3QueryApi/Query/Protocols/TelnetProtocol.cs @@ -0,0 +1,142 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Net.Sockets; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using TeamSpeak3QueryApi.Net.Enums; +using TeamSpeak3QueryApi.Net.Extensions; + +namespace TeamSpeak3QueryApi.Net.Query.Protocols +{ + public class TelnetProtocol : QueryClient, IProtocol + { + /// The default port which is used when no port is provided. + public const short DefaultPort = 10011; + + /// Creates a new instance of using the and . + public TelnetProtocol() + : this(DefaultHost, DefaultPort) + { } + + /// Creates a new instance of using the provided host and the . + /// The host name of the remote server. + public TelnetProtocol(string hostName) + : this(hostName, DefaultPort) + { } + /// Creates a new instance of using the provided host TCP port. + /// The host name of the remote server. + /// The TCP port of the Query API server. + public TelnetProtocol(string hostName, int port) + { + if (string.IsNullOrWhiteSpace(hostName)) + throw new ArgumentNullException(nameof(hostName)); + if (!ValidationHelper.ValidateTcpPort(port)) + throw new ArgumentOutOfRangeException(nameof(port)); + + Host = hostName; + Port = port; + ConnectionType = Protocol.Telnet; + IsConnected = false; + Client = new TcpClient(); + } + + /// Connects to the Query API server. + /// An awaitable . + public override CancellationTokenSource Connect(string username, string password) + { + throw new InvalidOperationException("Connect Method is not supported in telnet query. Please use the ssh query."); + } + + /// Connects to the Query API server. + /// An awaitable . + public override async Task ConnectAsync() + { + if (ConnectionType != Protocol.Telnet) + throw new InvalidOperationException("ConnectAsync Method without parameters can only be used with telnet Query. Please use Connect method."); + + await Client.ConnectAsync(Host, Port).ConfigureAwait(false); + if (!Client.Connected) + throw new InvalidOperationException("Could not connect."); + + _ns = Client.GetStream(); + _reader = new StreamReader(_ns); + _writer = new StreamWriter(_ns) { NewLine = "\n" }; + + IsConnected = true; + OnConnected?.Invoke(this, EventArgs.Empty); + + + var headline = await _reader.ReadLineAsync().ConfigureAwait(false); + if (headline != "TS3") + { + throw new QueryProtocolException("Telnet Query isn't a valid Teamspeak Query"); + } + await _reader.ReadLineAsync().ConfigureAwait(false); // Ignore welcome message + await _reader.ReadLineAsync().ConfigureAwait(false); + + return ResponseProcessingLoop(); + } + + private CancellationTokenSource ResponseProcessingLoop() + { + var cts = _cts = new CancellationTokenSource(); + Task.Run(async () => + { + while (!cts.Token.IsCancellationRequested) + { + string line = null; + try + { + line = await _reader.ReadLineAsync().WithCancellation(cts.Token).ConfigureAwait(false); + } + catch (OperationCanceledException) + { + break; + } + + if (line == null) + { + cts.Cancel(); + continue; + } + + if (string.IsNullOrWhiteSpace(line) || string.IsNullOrEmpty(line)) + continue; + + var s = line.Trim(); + Debug.WriteLine(line); + + if (s.StartsWith("error", StringComparison.OrdinalIgnoreCase)) + { + Debug.Assert(_currentCommand != null); + + var error = ParseError(s); + _currentCommand.Error = error; + InvokeResponse(_currentCommand); + } + else if (s.StartsWith("notify", StringComparison.OrdinalIgnoreCase)) + { + s = s.Remove(0, "notify".Length); + var not = ParseNotification(s); + InvokeNotification(not); + } + else + { + Debug.Assert(_currentCommand != null); + _currentCommand.RawResponse = s; + _currentCommand.ResponseDictionary = ParseResponse(s); + } + } + + IsConnected = false; + OnConnectionLost?.Invoke(this, EventArgs.Empty); + OnDisconnected?.Invoke(this, EventArgs.Empty); + + }); + return cts; + } + } +} diff --git a/src/TeamSpeak3QueryApi/Query/QueryClient.cs b/src/TeamSpeak3QueryApi/Query/QueryClient.cs index 60c7c60..4dfe13b 100644 --- a/src/TeamSpeak3QueryApi/Query/QueryClient.cs +++ b/src/TeamSpeak3QueryApi/Query/QueryClient.cs @@ -7,20 +7,19 @@ using System.Linq; using System.Net.Sockets; using System.Text; -using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using Renci.SshNet; -using Renci.SshNet.Common; using TeamSpeak3QueryApi.Net.Enums; using TeamSpeak3QueryApi.Net.Extensions; using TeamSpeak3QueryApi.Net.Notifications; using TeamSpeak3QueryApi.Net.Query.Parameters; +using TeamSpeak3QueryApi.Net.Query.Protocols; namespace TeamSpeak3QueryApi.Net.Query { /// Represents a client that can be used to access the TeamSpeak Query API on a remote server. - public class QueryClient : IDisposable + public class QueryClient : IDisposable, IProtocol { /// /// Events for handling in the correct moment @@ -31,128 +30,52 @@ public class QueryClient : IDisposable /// Gets the remote host of the Query API client. /// The remote host of the Query API client. - public string Host { get; } + public string Host { get; internal set; } /// Gets the remote port of the Query API client. /// The remote port of the Query API client. - public int Port { get; } + public int Port { get; internal set; } - public Protocol ConnectionType { get; set; } + public Protocol ConnectionType { get; internal set; } - public bool IsConnected { get; private set; } + public bool IsConnected { get; internal set; } /// The default host which is used when no host is provided. public const string DefaultHost = "localhost"; - /// The default port which is used when no port is provided. - public const short DefaultPort = 10022; - - public TcpClient Client { get; } - private StreamReader _reader; - private StreamWriter _writer; - private NetworkStream _ns; - private CancellationTokenSource _cts; + public TcpClient Client { get; internal set; } + protected StreamReader _reader; + protected StreamWriter _writer; + protected NetworkStream _ns; + protected CancellationTokenSource _cts; private readonly Queue _queue = new Queue(); private readonly ConcurrentDictionary>> _subscriptions = new ConcurrentDictionary>>(); - SshClient _sshClient; - ShellStream _shell; - string username; - - #region Ctors - - /// Creates a new instance of using the and . - public QueryClient(Protocol type) - : this(DefaultHost, DefaultPort, type) - { } - - /// Creates a new instance of using the provided host and the . - /// The host name of the remote server. - public QueryClient(string hostName, Protocol type) - : this(hostName, DefaultPort, type) - { } - /// Creates a new instance of using the provided host TCP port. - /// The host name of the remote server. - /// The TCP port of the Query API server. - public QueryClient(string hostName, int port, Protocol type) - { - if (string.IsNullOrWhiteSpace(hostName)) - throw new ArgumentNullException(nameof(hostName)); - if (!ValidationHelper.ValidateTcpPort(port)) - throw new ArgumentOutOfRangeException(nameof(port)); - - Host = hostName; - Port = port; - ConnectionType = type; - IsConnected = false; - Client = new TcpClient(); - } - - #endregion + protected SshClient _sshClient; + protected ShellStream _shell; + protected string username; - /// Connects to the Query API server. - /// An awaitable . - public async Task ConnectAsync() + public void Disconnect() { - if(ConnectionType != Protocol.Telnet) - throw new InvalidOperationException("ConnectAsync Method without parameters can only be used with telnet Query. Please use ConnectSsh method."); - - await Client.ConnectAsync(Host, Port).ConfigureAwait(false); - if (!Client.Connected) - throw new InvalidOperationException("Could not connect."); - - _ns = Client.GetStream(); - _reader = new StreamReader(_ns); - _writer = new StreamWriter(_ns) { NewLine = "\n" }; - - IsConnected = true; - OnConnected?.Invoke(this, EventArgs.Empty); - - - var headline = await _reader.ReadLineAsync().ConfigureAwait(false); - if (headline != "TS3") - { - throw new QueryProtocolException("Telnet Query isn't a valid Teamspeak Query"); - } - await _reader.ReadLineAsync().ConfigureAwait(false); // Ignore welcome message - await _reader.ReadLineAsync().ConfigureAwait(false); + if (_cts == null) + return; - return ResponseProcessingLoop(); + OnDisconnected?.Invoke(this, EventArgs.Empty); + _cts.Cancel(); } - public CancellationTokenSource ConnectSsh(string username, string password) + /// Connects to the Query API server. + /// An awaitable . + public virtual Task ConnectAsync() { - this.username = username; - - _sshClient = new SshClient(Host, Port, username, password); - _sshClient.Connect(); - - var terminalMode = new Dictionary(); - terminalMode.Add(TerminalModes.ECHO, 53); - - _shell = _sshClient.CreateShellStream("", 0, 0, 0, 0, 4096); - - _reader = new StreamReader(_shell, Encoding.UTF8, true, 1024, true); - _writer = new StreamWriter(_shell) { NewLine = "\n", AutoFlush = true }; - - var headline = _shell.Expect("\r\n", new TimeSpan(0, 0, 3)); - if (!headline.Contains("TS3")) - { - throw new QueryProtocolException("Telnet Query isn't a valid Teamspeak Query"); - } - _shell.Expect("\n", new TimeSpan(0, 0, 3)); // Ignore welcome message - _shell.Expect("\n", new TimeSpan(0, 0, 3)); // Ignore welcome message - - return ResponseProcessingLoop(); + throw new NotImplementedException(); } - public void Disconnect() + /// Connects to the Query API server. + /// An awaitable . + public virtual CancellationTokenSource Connect(string username, string password) { - if (_cts == null) - return; - - OnDisconnected?.Invoke(this, EventArgs.Empty); - _cts.Cancel(); + throw new NotImplementedException(); } #region Send @@ -266,7 +189,7 @@ public void Unsubscribe(string notificationName, Action callba #endregion #region Parsing - private static QueryResponseDictionary[] ParseResponse(string rawResponse) + protected static QueryResponseDictionary[] ParseResponse(string rawResponse) { var records = rawResponse.Split('|'); var response = records.Select(s => @@ -298,7 +221,7 @@ private static QueryResponseDictionary[] ParseResponse(string rawResponse) return response.ToArray(); } - private static QueryError ParseError(string errorString) + protected static QueryError ParseError(string errorString) { // Ex: // error id=2568 msg=insufficient\sclient\spermissions failed_permid=27 @@ -342,7 +265,7 @@ private static QueryError ParseError(string errorString) return parsedError; } - private static QueryNotification ParseNotification(string notificationString) + protected static QueryNotification ParseNotification(string notificationString) { Debug.Assert(!string.IsNullOrWhiteSpace(notificationString)); @@ -360,7 +283,7 @@ private static QueryNotification ParseNotification(string notificationString) return new QueryNotification(notificationName, notData); } - private static void InvokeResponse(QueryCommand forCommand) + protected static void InvokeResponse(QueryCommand forCommand) { Debug.Assert(forCommand != null); Debug.Assert(forCommand.Defer != null); @@ -379,7 +302,7 @@ private static void InvokeResponse(QueryCommand forCommand) #endregion #region Invocation - private void InvokeNotification(QueryNotification notification) + protected void InvokeNotification(QueryNotification notification) { Debug.Assert(notification != null); Debug.Assert(notification.Name != null); @@ -399,73 +322,7 @@ private void InvokeNotification(QueryNotification notification) } } - private CancellationTokenSource ResponseProcessingLoop() - { - var cts = _cts = new CancellationTokenSource(); - Task.Run(async () => - { - while (!cts.Token.IsCancellationRequested) - { - string line = null; - try - { - if(ConnectionType == Protocol.SSH) - { - line = _shell.ReadLine(); - } - else - { - line = await _reader.ReadLineAsync().WithCancellation(cts.Token).ConfigureAwait(false); - } - } - catch (OperationCanceledException) - { - break; - } - - if (line == null) - { - cts.Cancel(); - continue; - } - - if (string.IsNullOrWhiteSpace(line) || string.IsNullOrEmpty(line) || line.StartsWith(username)) - continue; - - var s = line.Trim(); - Debug.WriteLine(line); - - if (s.StartsWith("error", StringComparison.OrdinalIgnoreCase)) - { - Debug.Assert(_currentCommand != null); - - var error = ParseError(s); - _currentCommand.Error = error; - InvokeResponse(_currentCommand); - } - else if (s.StartsWith("notify", StringComparison.OrdinalIgnoreCase)) - { - s = s.Remove(0, "notify".Length); - var not = ParseNotification(s); - InvokeNotification(not); - } - else - { - Debug.Assert(_currentCommand != null); - _currentCommand.RawResponse = s; - _currentCommand.ResponseDictionary = ParseResponse(s); - } - } - - IsConnected = false; - OnConnectionLost?.Invoke(this, EventArgs.Empty); - OnDisconnected?.Invoke(this, EventArgs.Empty); - - }); - return cts; - } - - private QueryCommand _currentCommand; + protected QueryCommand _currentCommand; private async Task CheckQueueAsync() { if (_queue.Count > 0) @@ -509,7 +366,6 @@ protected virtual void Dispose(bool disposing) _sshClient?.Dispose(); } } - #endregion } } diff --git a/src/TeamSpeak3QueryApi/Query/QueryCommand.cs b/src/TeamSpeak3QueryApi/Query/QueryCommand.cs index b957b9b..ea8042c 100644 --- a/src/TeamSpeak3QueryApi/Query/QueryCommand.cs +++ b/src/TeamSpeak3QueryApi/Query/QueryCommand.cs @@ -4,7 +4,7 @@ namespace TeamSpeak3QueryApi.Net.Query { - internal class QueryCommand + public class QueryCommand { public string Command { get; } public string[] Options { get; } diff --git a/src/TeamSpeak3QueryApi/Query/QueryNotification.cs b/src/TeamSpeak3QueryApi/Query/QueryNotification.cs index 7d641dd..baad23d 100644 --- a/src/TeamSpeak3QueryApi/Query/QueryNotification.cs +++ b/src/TeamSpeak3QueryApi/Query/QueryNotification.cs @@ -3,7 +3,7 @@ namespace TeamSpeak3QueryApi.Net.Query { - internal class QueryNotification + public class QueryNotification { public string Name { get; set; } public NotificationData Data { get; set; } diff --git a/src/TeamSpeak3QueryApi/TeamSpeakClient.cs b/src/TeamSpeak3QueryApi/TeamSpeakClient.cs index 2e6764a..3d75476 100644 --- a/src/TeamSpeak3QueryApi/TeamSpeakClient.cs +++ b/src/TeamSpeak3QueryApi/TeamSpeakClient.cs @@ -15,6 +15,7 @@ using TeamSpeak3QueryApi.Net.Query.Parameters; using TeamSpeak3QueryApi.Net.Query.Responses; using TeamSpeak3QueryApi.Net.Query.Enums; +using TeamSpeak3QueryApi.Net.Query.Protocols; namespace TeamSpeak3QueryApi.Net { @@ -31,28 +32,30 @@ public class TeamSpeakClient : IDisposable /// Creates a new instance of using the and . public TeamSpeakClient() - : this(QueryClient.DefaultHost, QueryClient.DefaultPort, Protocol.Telnet) - { } - - /// Creates a new instance of using the provided host and the . - /// The host name of the remote server. - public TeamSpeakClient(string hostName, Protocol type = Protocol.Telnet) - : this(hostName, QueryClient.DefaultPort, type) + : this(QueryClient.DefaultHost, TelnetProtocol.DefaultPort, Protocol.Telnet) { } /// Creates a new instance of using the provided host TCP port. /// The host name of the remote server. /// The TCP port of the Query API server. - public TeamSpeakClient(string hostName, int port, Protocol type) + public TeamSpeakClient(string hostName, int port = TelnetProtocol.DefaultPort, Protocol type = Protocol.Telnet) { - Client = new QueryClient(hostName, port, type); + switch (type) + { + case Protocol.Telnet: + Client = new TelnetProtocol(hostName, port); + break; + case Protocol.SSH: + Client = new SshProtocol(hostName, port); + break; + } _fileTransferClient = new FileTransferClient(hostName); } #endregion - public Task ConnectTelnetAsync() => Client.ConnectAsync(); - public void ConnectSsh(string username, string password) => Client.ConnectSsh(username, password); + public Task ConnectAsync() => Client.ConnectAsync(); + public void Connect(string username, string password) => Client.Connect(username, password); #region Subscriptions @@ -96,6 +99,9 @@ private static NotificationType GetNotificationType() public Task LoginAsync(string userName, string password) { + if (Client.ConnectionType == Protocol.SSH) + throw new InvalidOperationException("Login is not needed in ssh protocol"); + return Client.SendAsync("login", new Parameter("client_login_name", userName), new Parameter("client_login_password", password)); } From b256afbc2c306f74812b09e1b40f227839a84d14 Mon Sep 17 00:00:00 2001 From: Lukas Gundermann Date: Wed, 26 Aug 2020 13:28:03 +0200 Subject: [PATCH 10/14] Updated readme file --- README.md | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index c2992e4..009ed47 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,13 @@ # C# TeamSpeak3Query API [![Travis Build Status](https://travis-ci.org/nikeee/TeamSpeak3QueryAPI.svg?branch=master)](https://travis-ci.org/nikeee/TeamSpeak3QueryAPI) ![NuGet Downloads](https://img.shields.io/nuget/dt/TeamSpeak3QueryApi.svg) -An API wrapper for the TeamSpeak 3 Query API written in C#. Still work in progress. +An API wrapper for the TeamSpeak 3 Query API written in C#. **Still work in progress**. Key features of this library: - Built entirely with the .NET TAP pattern for perfect async/await usage opportunities - Robust library architecture - Query responses are fully mapped to .NET objects, including the naming style - Usable via Middleware/Rich Client +- SSH and Telnet protocol will be supported ## Contents 1. [Documentation](#documentation) @@ -26,9 +27,10 @@ The TeamSpeak 3 Query API is documented [here](http://media.teamspeak.com/ts3_li This library has an online documentation which was created using [sharpDox](http://sharpdox.de). You can find the documentation on the [GitHub Page of this repository](https://nikeee.github.io/TeamSpeak3QueryAPI). ## Compatibility -This library requires .NET Standard `1.3`. You can look at [this table](https://docs.microsoft.com/en-us/dotnet/standard/net-standard#net-implementation-support) to see whether your platform is supported. If you find something that is missing (espacially in the `TeamSpeakClient` class), just submit a PR or an issue! +This library requires .NET Core `3.0`. You can look at [this table](https://docs.microsoft.com/en-us/dotnet/standard/net-standard#net-implementation-support) to see whether your platform is supported. If you find something that is missing (espacially in the `TeamSpeakClient` class), just submit a PR or an issue! ### NuGet +*This is currently not possible.* ```Shell Install-Package TeamSpeak3QueryApi # or @@ -39,10 +41,17 @@ dotnet add package TeamSpeak3QueryApi Using the rich client, you can connect to a TeamSpeak Query server like this: ### Connect and Login -```C# +```C# Telnet query var rc = new TeamSpeakClient(host, port); // Create rich client instance -await rc.Connect(); // connect to the server -await rc.Login(user, password); // login to do some stuff that requires permission +await rc.ConnectAsync(); // connect to the server +await rc.LoginAsync(user, password); // login to do some stuff that requires permission +await rc.UseServer(1); // Use the server with id '1' +var me = await rc.WhoAmI(); // Get information about yourself! +``` + +```C# SSH query +var rc = new TeamSpeakClient(host, 10022, Protocol.SSH); // Create rich client instance +await rc.Connect(user, password); // connect to the server with login data await rc.UseServer(1); // Use the server with id '1' var me = await rc.WhoAmI(); // Get information about yourself! ``` @@ -70,7 +79,7 @@ rc.Subscribe(data => { Getting all clients and moving them to a specific channel is as simple as: ```C# -var currentClients = await rc.GetClients(); +var currentClients = await rc.GetClientsAsync(); await rc.MoveClient(currentClients, 30); // Where 30 is the channel id ``` ...and kick someone whose name is "Foobar". @@ -78,7 +87,7 @@ await rc.MoveClient(currentClients, 30); // Where 30 is the channel id ```C# var fooBar = currentClients.SingleOrDefault(c => c.NickName == "Foobar"); // Using linq to find our dude if(fooBar != null) // Make sure we pass a valid reference - await rc.KickClient(fooBar, 30); + await rc.KickClientAsync(fooBar, 30); ``` ### Exceptions @@ -100,16 +109,16 @@ If you want to work more loose-typed, you can do this. This is possible using th ```C# var qc = new QueryClient(host, port); -await qc.Connect(); +await qc.ConnectAsync(); -await qc.Send("login", new Parameter("client_login_name", userName), new Parameter("client_login_password", password)); +await qc.SendAsync("login", new Parameter("client_login_name", userName), new Parameter("client_login_password", password)); -await qc.Send("use", new Parameter("sid", "1")); +await qc.SendAsync("use", new Parameter("sid", "1")); -var me = await qc.Send("whoami"); +var me = await qc.SendAsync("whoami"); -await qc.Send("servernotifyregister", new Parameter("event", "server")); -await qc.Send("servernotifyregister", new Parameter("event", "channel"), new Parameter("id", channelId)); +await qc.SendAsync("servernotifyregister", new Parameter("event", "server")); +await qc.SendAsync("servernotifyregister", new Parameter("event", "channel"), new Parameter("id", channelId)); // and so on. ``` From cf9c54b25268818b475c5765e81a329d01fd077f Mon Sep 17 00:00:00 2001 From: Lukas Gundermann Date: Thu, 27 Aug 2020 10:16:20 +0200 Subject: [PATCH 11/14] Moved Notifications to Query.Notifications --- src/TeamSpeak3QueryApi.Demo/Program.cs | 3 +-- .../{ => Query}/Notifications/ChannelCreated.cs | 2 +- .../{ => Query}/Notifications/ChannelDeleted.cs | 2 +- .../{ => Query}/Notifications/ChannelDescriptionChanged.cs | 2 +- .../{ => Query}/Notifications/ChannelEdited.cs | 2 +- .../{ => Query}/Notifications/ChannelMoved.cs | 2 +- .../{ => Query}/Notifications/ChannelPasswordChanged.cs | 2 +- .../{ => Query}/Notifications/ClientEnterView.cs | 2 +- .../{ => Query}/Notifications/ClientLeftView.cs | 2 +- .../{ => Query}/Notifications/ClientMoved.cs | 2 +- .../{ => Query}/Notifications/InvokerInformation.cs | 2 +- .../{ => Query}/Notifications/Notification.cs | 2 +- .../{ => Query}/Notifications/NotificationData.cs | 2 +- .../{ => Query}/Notifications/ServerEdited.cs | 2 +- .../{ => Query}/Notifications/TextMessage.cs | 2 +- src/TeamSpeak3QueryApi/{ => Query}/Notifications/TokenUsed.cs | 2 +- src/TeamSpeak3QueryApi/Query/QueryClient.cs | 2 +- src/TeamSpeak3QueryApi/Query/QueryNotification.cs | 2 +- src/TeamSpeak3QueryApi/TeamSpeakClient.cs | 2 +- 19 files changed, 19 insertions(+), 20 deletions(-) rename src/TeamSpeak3QueryApi/{ => Query}/Notifications/ChannelCreated.cs (97%) rename src/TeamSpeak3QueryApi/{ => Query}/Notifications/ChannelDeleted.cs (80%) rename src/TeamSpeak3QueryApi/{ => Query}/Notifications/ChannelDescriptionChanged.cs (71%) rename src/TeamSpeak3QueryApi/{ => Query}/Notifications/ChannelEdited.cs (97%) rename src/TeamSpeak3QueryApi/{ => Query}/Notifications/ChannelMoved.cs (83%) rename src/TeamSpeak3QueryApi/{ => Query}/Notifications/ChannelPasswordChanged.cs (71%) rename src/TeamSpeak3QueryApi/{ => Query}/Notifications/ClientEnterView.cs (98%) rename src/TeamSpeak3QueryApi/{ => Query}/Notifications/ClientLeftView.cs (93%) rename src/TeamSpeak3QueryApi/{ => Query}/Notifications/ClientMoved.cs (78%) rename src/TeamSpeak3QueryApi/{ => Query}/Notifications/InvokerInformation.cs (88%) rename src/TeamSpeak3QueryApi/{ => Query}/Notifications/Notification.cs (69%) rename src/TeamSpeak3QueryApi/{ => Query}/Notifications/NotificationData.cs (93%) rename src/TeamSpeak3QueryApi/{ => Query}/Notifications/ServerEdited.cs (97%) rename src/TeamSpeak3QueryApi/{ => Query}/Notifications/TextMessage.cs (88%) rename src/TeamSpeak3QueryApi/{ => Query}/Notifications/TokenUsed.cs (91%) diff --git a/src/TeamSpeak3QueryApi.Demo/Program.cs b/src/TeamSpeak3QueryApi.Demo/Program.cs index 35c31ab..0399ec8 100644 --- a/src/TeamSpeak3QueryApi.Demo/Program.cs +++ b/src/TeamSpeak3QueryApi.Demo/Program.cs @@ -4,9 +4,8 @@ using System.IO; using System.Linq; using System.Threading.Tasks; -using TeamSpeak3QueryApi.Net.Enums; -using TeamSpeak3QueryApi.Net.Notifications; using TeamSpeak3QueryApi.Net.Query.Enums; +using TeamSpeak3QueryApi.Net.Query.Notifications; namespace TeamSpeak3QueryApi.Net.Demo { diff --git a/src/TeamSpeak3QueryApi/Notifications/ChannelCreated.cs b/src/TeamSpeak3QueryApi/Query/Notifications/ChannelCreated.cs similarity index 97% rename from src/TeamSpeak3QueryApi/Notifications/ChannelCreated.cs rename to src/TeamSpeak3QueryApi/Query/Notifications/ChannelCreated.cs index f7a6295..272bdf3 100644 --- a/src/TeamSpeak3QueryApi/Notifications/ChannelCreated.cs +++ b/src/TeamSpeak3QueryApi/Query/Notifications/ChannelCreated.cs @@ -1,7 +1,7 @@ using System; using TeamSpeak3QueryApi.Net.Query.Enums; -namespace TeamSpeak3QueryApi.Net.Notifications +namespace TeamSpeak3QueryApi.Net.Query.Notifications { public class ChannelCreated : InvokerInformation { diff --git a/src/TeamSpeak3QueryApi/Notifications/ChannelDeleted.cs b/src/TeamSpeak3QueryApi/Query/Notifications/ChannelDeleted.cs similarity index 80% rename from src/TeamSpeak3QueryApi/Notifications/ChannelDeleted.cs rename to src/TeamSpeak3QueryApi/Query/Notifications/ChannelDeleted.cs index dadc3f7..32d72d4 100644 --- a/src/TeamSpeak3QueryApi/Notifications/ChannelDeleted.cs +++ b/src/TeamSpeak3QueryApi/Query/Notifications/ChannelDeleted.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Notifications +namespace TeamSpeak3QueryApi.Net.Query.Notifications { public class ChannelDeleted : InvokerInformation { diff --git a/src/TeamSpeak3QueryApi/Notifications/ChannelDescriptionChanged.cs b/src/TeamSpeak3QueryApi/Query/Notifications/ChannelDescriptionChanged.cs similarity index 71% rename from src/TeamSpeak3QueryApi/Notifications/ChannelDescriptionChanged.cs rename to src/TeamSpeak3QueryApi/Query/Notifications/ChannelDescriptionChanged.cs index f127ed6..4e64e89 100644 --- a/src/TeamSpeak3QueryApi/Notifications/ChannelDescriptionChanged.cs +++ b/src/TeamSpeak3QueryApi/Query/Notifications/ChannelDescriptionChanged.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Notifications +namespace TeamSpeak3QueryApi.Net.Query.Notifications { public class ChannelDescriptionChanged : Notification { diff --git a/src/TeamSpeak3QueryApi/Notifications/ChannelEdited.cs b/src/TeamSpeak3QueryApi/Query/Notifications/ChannelEdited.cs similarity index 97% rename from src/TeamSpeak3QueryApi/Notifications/ChannelEdited.cs rename to src/TeamSpeak3QueryApi/Query/Notifications/ChannelEdited.cs index d3eee7d..ae281de 100644 --- a/src/TeamSpeak3QueryApi/Notifications/ChannelEdited.cs +++ b/src/TeamSpeak3QueryApi/Query/Notifications/ChannelEdited.cs @@ -1,7 +1,7 @@ using System; using TeamSpeak3QueryApi.Net.Query.Enums; -namespace TeamSpeak3QueryApi.Net.Notifications +namespace TeamSpeak3QueryApi.Net.Query.Notifications { public class ChannelEdited : InvokerInformation { diff --git a/src/TeamSpeak3QueryApi/Notifications/ChannelMoved.cs b/src/TeamSpeak3QueryApi/Query/Notifications/ChannelMoved.cs similarity index 83% rename from src/TeamSpeak3QueryApi/Notifications/ChannelMoved.cs rename to src/TeamSpeak3QueryApi/Query/Notifications/ChannelMoved.cs index ef3b4bd..751ebf8 100644 --- a/src/TeamSpeak3QueryApi/Notifications/ChannelMoved.cs +++ b/src/TeamSpeak3QueryApi/Query/Notifications/ChannelMoved.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Notifications +namespace TeamSpeak3QueryApi.Net.Query.Notifications { public class ChannelMoved : InvokerInformation { diff --git a/src/TeamSpeak3QueryApi/Notifications/ChannelPasswordChanged.cs b/src/TeamSpeak3QueryApi/Query/Notifications/ChannelPasswordChanged.cs similarity index 71% rename from src/TeamSpeak3QueryApi/Notifications/ChannelPasswordChanged.cs rename to src/TeamSpeak3QueryApi/Query/Notifications/ChannelPasswordChanged.cs index a1a0abf..098c1c0 100644 --- a/src/TeamSpeak3QueryApi/Notifications/ChannelPasswordChanged.cs +++ b/src/TeamSpeak3QueryApi/Query/Notifications/ChannelPasswordChanged.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Notifications +namespace TeamSpeak3QueryApi.Net.Query.Notifications { public class ChannelPasswordChanged : Notification { diff --git a/src/TeamSpeak3QueryApi/Notifications/ClientEnterView.cs b/src/TeamSpeak3QueryApi/Query/Notifications/ClientEnterView.cs similarity index 98% rename from src/TeamSpeak3QueryApi/Notifications/ClientEnterView.cs rename to src/TeamSpeak3QueryApi/Query/Notifications/ClientEnterView.cs index fc2f823..11fde38 100644 --- a/src/TeamSpeak3QueryApi/Notifications/ClientEnterView.cs +++ b/src/TeamSpeak3QueryApi/Query/Notifications/ClientEnterView.cs @@ -1,7 +1,7 @@ using System; using TeamSpeak3QueryApi.Net.Query.Enums; -namespace TeamSpeak3QueryApi.Net.Notifications +namespace TeamSpeak3QueryApi.Net.Query.Notifications { public class ClientEnterView : Notification { diff --git a/src/TeamSpeak3QueryApi/Notifications/ClientLeftView.cs b/src/TeamSpeak3QueryApi/Query/Notifications/ClientLeftView.cs similarity index 93% rename from src/TeamSpeak3QueryApi/Notifications/ClientLeftView.cs rename to src/TeamSpeak3QueryApi/Query/Notifications/ClientLeftView.cs index 3623209..788f1b0 100644 --- a/src/TeamSpeak3QueryApi/Notifications/ClientLeftView.cs +++ b/src/TeamSpeak3QueryApi/Query/Notifications/ClientLeftView.cs @@ -1,7 +1,7 @@ using System; using TeamSpeak3QueryApi.Net.Query.Enums; -namespace TeamSpeak3QueryApi.Net.Notifications +namespace TeamSpeak3QueryApi.Net.Query.Notifications { public class ClientLeftView : Notification { diff --git a/src/TeamSpeak3QueryApi/Notifications/ClientMoved.cs b/src/TeamSpeak3QueryApi/Query/Notifications/ClientMoved.cs similarity index 78% rename from src/TeamSpeak3QueryApi/Notifications/ClientMoved.cs rename to src/TeamSpeak3QueryApi/Query/Notifications/ClientMoved.cs index 0ea7812..612829b 100644 --- a/src/TeamSpeak3QueryApi/Notifications/ClientMoved.cs +++ b/src/TeamSpeak3QueryApi/Query/Notifications/ClientMoved.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Notifications +namespace TeamSpeak3QueryApi.Net.Query.Notifications { public class ClientMoved : InvokerInformation { diff --git a/src/TeamSpeak3QueryApi/Notifications/InvokerInformation.cs b/src/TeamSpeak3QueryApi/Query/Notifications/InvokerInformation.cs similarity index 88% rename from src/TeamSpeak3QueryApi/Notifications/InvokerInformation.cs rename to src/TeamSpeak3QueryApi/Query/Notifications/InvokerInformation.cs index 2236a73..cd06b3b 100644 --- a/src/TeamSpeak3QueryApi/Notifications/InvokerInformation.cs +++ b/src/TeamSpeak3QueryApi/Query/Notifications/InvokerInformation.cs @@ -1,6 +1,6 @@ using TeamSpeak3QueryApi.Net.Query.Enums; -namespace TeamSpeak3QueryApi.Net.Notifications +namespace TeamSpeak3QueryApi.Net.Query.Notifications { public abstract class InvokerInformation : Notification { diff --git a/src/TeamSpeak3QueryApi/Notifications/Notification.cs b/src/TeamSpeak3QueryApi/Query/Notifications/Notification.cs similarity index 69% rename from src/TeamSpeak3QueryApi/Notifications/Notification.cs rename to src/TeamSpeak3QueryApi/Query/Notifications/Notification.cs index d9fddf5..eb2c631 100644 --- a/src/TeamSpeak3QueryApi/Notifications/Notification.cs +++ b/src/TeamSpeak3QueryApi/Query/Notifications/Notification.cs @@ -1,6 +1,6 @@ using TeamSpeak3QueryApi.Net.Interfaces; -namespace TeamSpeak3QueryApi.Net.Notifications +namespace TeamSpeak3QueryApi.Net.Query.Notifications { public abstract class Notification : ITeamSpeakSerializable { } diff --git a/src/TeamSpeak3QueryApi/Notifications/NotificationData.cs b/src/TeamSpeak3QueryApi/Query/Notifications/NotificationData.cs similarity index 93% rename from src/TeamSpeak3QueryApi/Notifications/NotificationData.cs rename to src/TeamSpeak3QueryApi/Query/Notifications/NotificationData.cs index d05bd22..629dd4c 100644 --- a/src/TeamSpeak3QueryApi/Notifications/NotificationData.cs +++ b/src/TeamSpeak3QueryApi/Query/Notifications/NotificationData.cs @@ -3,7 +3,7 @@ using System.Diagnostics; using TeamSpeak3QueryApi.Net.Query; -namespace TeamSpeak3QueryApi.Net.Notifications +namespace TeamSpeak3QueryApi.Net.Query.Notifications { /// Provides data that was retrieved by a notification. public class NotificationData diff --git a/src/TeamSpeak3QueryApi/Notifications/ServerEdited.cs b/src/TeamSpeak3QueryApi/Query/Notifications/ServerEdited.cs similarity index 97% rename from src/TeamSpeak3QueryApi/Notifications/ServerEdited.cs rename to src/TeamSpeak3QueryApi/Query/Notifications/ServerEdited.cs index aad5e23..b5b8375 100644 --- a/src/TeamSpeak3QueryApi/Notifications/ServerEdited.cs +++ b/src/TeamSpeak3QueryApi/Query/Notifications/ServerEdited.cs @@ -1,7 +1,7 @@ using System; using TeamSpeak3QueryApi.Net.Query.Enums; -namespace TeamSpeak3QueryApi.Net.Notifications +namespace TeamSpeak3QueryApi.Net.Query.Notifications { public class ServerEdited : Notification { diff --git a/src/TeamSpeak3QueryApi/Notifications/TextMessage.cs b/src/TeamSpeak3QueryApi/Query/Notifications/TextMessage.cs similarity index 88% rename from src/TeamSpeak3QueryApi/Notifications/TextMessage.cs rename to src/TeamSpeak3QueryApi/Query/Notifications/TextMessage.cs index 6c3102e..c61d67d 100644 --- a/src/TeamSpeak3QueryApi/Notifications/TextMessage.cs +++ b/src/TeamSpeak3QueryApi/Query/Notifications/TextMessage.cs @@ -1,6 +1,6 @@ using TeamSpeak3QueryApi.Net.Query.Enums; -namespace TeamSpeak3QueryApi.Net.Notifications +namespace TeamSpeak3QueryApi.Net.Query.Notifications { public class TextMessage : InvokerInformation { diff --git a/src/TeamSpeak3QueryApi/Notifications/TokenUsed.cs b/src/TeamSpeak3QueryApi/Query/Notifications/TokenUsed.cs similarity index 91% rename from src/TeamSpeak3QueryApi/Notifications/TokenUsed.cs rename to src/TeamSpeak3QueryApi/Query/Notifications/TokenUsed.cs index 26d6d8b..b269f21 100644 --- a/src/TeamSpeak3QueryApi/Notifications/TokenUsed.cs +++ b/src/TeamSpeak3QueryApi/Query/Notifications/TokenUsed.cs @@ -1,4 +1,4 @@ -namespace TeamSpeak3QueryApi.Net.Notifications +namespace TeamSpeak3QueryApi.Net.Query.Notifications { public class TokenUsed : InvokerInformation { diff --git a/src/TeamSpeak3QueryApi/Query/QueryClient.cs b/src/TeamSpeak3QueryApi/Query/QueryClient.cs index 4dfe13b..673e777 100644 --- a/src/TeamSpeak3QueryApi/Query/QueryClient.cs +++ b/src/TeamSpeak3QueryApi/Query/QueryClient.cs @@ -12,7 +12,7 @@ using Renci.SshNet; using TeamSpeak3QueryApi.Net.Enums; using TeamSpeak3QueryApi.Net.Extensions; -using TeamSpeak3QueryApi.Net.Notifications; +using TeamSpeak3QueryApi.Net.Query.Notifications; using TeamSpeak3QueryApi.Net.Query.Parameters; using TeamSpeak3QueryApi.Net.Query.Protocols; diff --git a/src/TeamSpeak3QueryApi/Query/QueryNotification.cs b/src/TeamSpeak3QueryApi/Query/QueryNotification.cs index baad23d..ceb69ea 100644 --- a/src/TeamSpeak3QueryApi/Query/QueryNotification.cs +++ b/src/TeamSpeak3QueryApi/Query/QueryNotification.cs @@ -1,5 +1,5 @@ using System.Diagnostics; -using TeamSpeak3QueryApi.Net.Notifications; +using TeamSpeak3QueryApi.Net.Query.Notifications; namespace TeamSpeak3QueryApi.Net.Query { diff --git a/src/TeamSpeak3QueryApi/TeamSpeakClient.cs b/src/TeamSpeak3QueryApi/TeamSpeakClient.cs index 3d75476..dd4b175 100644 --- a/src/TeamSpeak3QueryApi/TeamSpeakClient.cs +++ b/src/TeamSpeak3QueryApi/TeamSpeakClient.cs @@ -9,13 +9,13 @@ using TeamSpeak3QueryApi.Net.FileTransfer; using TeamSpeak3QueryApi.Net.Query; using TeamSpeak3QueryApi.Net.Enums; -using TeamSpeak3QueryApi.Net.Notifications; using TeamSpeak3QueryApi.Net.Extensions; using System.Diagnostics; using TeamSpeak3QueryApi.Net.Query.Parameters; using TeamSpeak3QueryApi.Net.Query.Responses; using TeamSpeak3QueryApi.Net.Query.Enums; using TeamSpeak3QueryApi.Net.Query.Protocols; +using TeamSpeak3QueryApi.Net.Query.Notifications; namespace TeamSpeak3QueryApi.Net { From bb1a39f457d00cc6879247ef6b2c627e2c501fcb Mon Sep 17 00:00:00 2001 From: Lukas Gundermann Date: Thu, 27 Aug 2020 10:33:33 +0200 Subject: [PATCH 12/14] Removed IProtocol interface; Changed virtual method to abstract method --- .../Query/Protocols/IProtocol.cs | 14 -------------- .../Query/Protocols/SshProtocol.cs | 2 +- .../Query/Protocols/TelnetProtocol.cs | 2 +- src/TeamSpeak3QueryApi/Query/QueryClient.cs | 12 +++--------- 4 files changed, 5 insertions(+), 25 deletions(-) delete mode 100644 src/TeamSpeak3QueryApi/Query/Protocols/IProtocol.cs diff --git a/src/TeamSpeak3QueryApi/Query/Protocols/IProtocol.cs b/src/TeamSpeak3QueryApi/Query/Protocols/IProtocol.cs deleted file mode 100644 index 51c701c..0000000 --- a/src/TeamSpeak3QueryApi/Query/Protocols/IProtocol.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading; -using System.Threading.Tasks; - -namespace TeamSpeak3QueryApi.Net.Query.Protocols -{ - public interface IProtocol - { - Task ConnectAsync(); - CancellationTokenSource Connect(string username, string password); - } -} diff --git a/src/TeamSpeak3QueryApi/Query/Protocols/SshProtocol.cs b/src/TeamSpeak3QueryApi/Query/Protocols/SshProtocol.cs index dc4ec21..87d771b 100644 --- a/src/TeamSpeak3QueryApi/Query/Protocols/SshProtocol.cs +++ b/src/TeamSpeak3QueryApi/Query/Protocols/SshProtocol.cs @@ -13,7 +13,7 @@ namespace TeamSpeak3QueryApi.Net.Query.Protocols { - public class SshProtocol : QueryClient, IProtocol + public class SshProtocol : QueryClient { /// The default port which is used when no port is provided. public const short DefaultPort = 10022; diff --git a/src/TeamSpeak3QueryApi/Query/Protocols/TelnetProtocol.cs b/src/TeamSpeak3QueryApi/Query/Protocols/TelnetProtocol.cs index d3b26bb..712f3f9 100644 --- a/src/TeamSpeak3QueryApi/Query/Protocols/TelnetProtocol.cs +++ b/src/TeamSpeak3QueryApi/Query/Protocols/TelnetProtocol.cs @@ -11,7 +11,7 @@ namespace TeamSpeak3QueryApi.Net.Query.Protocols { - public class TelnetProtocol : QueryClient, IProtocol + public class TelnetProtocol : QueryClient { /// The default port which is used when no port is provided. public const short DefaultPort = 10011; diff --git a/src/TeamSpeak3QueryApi/Query/QueryClient.cs b/src/TeamSpeak3QueryApi/Query/QueryClient.cs index 673e777..6933dfb 100644 --- a/src/TeamSpeak3QueryApi/Query/QueryClient.cs +++ b/src/TeamSpeak3QueryApi/Query/QueryClient.cs @@ -19,7 +19,7 @@ namespace TeamSpeak3QueryApi.Net.Query { /// Represents a client that can be used to access the TeamSpeak Query API on a remote server. - public class QueryClient : IDisposable, IProtocol + public abstract class QueryClient : IDisposable { /// /// Events for handling in the correct moment @@ -66,17 +66,11 @@ public void Disconnect() /// Connects to the Query API server. /// An awaitable . - public virtual Task ConnectAsync() - { - throw new NotImplementedException(); - } + public abstract Task ConnectAsync(); /// Connects to the Query API server. /// An awaitable . - public virtual CancellationTokenSource Connect(string username, string password) - { - throw new NotImplementedException(); - } + public abstract CancellationTokenSource Connect(string username, string password); #region Send From bc38581a57b3636425c34f72f96ed4af7b2774fb Mon Sep 17 00:00:00 2001 From: Lukas Gundermann Date: Thu, 27 Aug 2020 10:43:43 +0200 Subject: [PATCH 13/14] Renamed Protocols to QueryClients --- src/TeamSpeak3QueryApi/Query/QueryClient.cs | 1 - .../{Protocols/SshProtocol.cs => SshQueryClient.cs} | 10 +++++----- .../TelnetProtocol.cs => TelnetQueryClient.cs} | 12 +++++------- src/TeamSpeak3QueryApi/TeamSpeakClient.cs | 10 ++++------ 4 files changed, 14 insertions(+), 19 deletions(-) rename src/TeamSpeak3QueryApi/Query/{Protocols/SshProtocol.cs => SshQueryClient.cs} (96%) rename src/TeamSpeak3QueryApi/Query/{Protocols/TelnetProtocol.cs => TelnetQueryClient.cs} (95%) diff --git a/src/TeamSpeak3QueryApi/Query/QueryClient.cs b/src/TeamSpeak3QueryApi/Query/QueryClient.cs index 6933dfb..3a203b2 100644 --- a/src/TeamSpeak3QueryApi/Query/QueryClient.cs +++ b/src/TeamSpeak3QueryApi/Query/QueryClient.cs @@ -14,7 +14,6 @@ using TeamSpeak3QueryApi.Net.Extensions; using TeamSpeak3QueryApi.Net.Query.Notifications; using TeamSpeak3QueryApi.Net.Query.Parameters; -using TeamSpeak3QueryApi.Net.Query.Protocols; namespace TeamSpeak3QueryApi.Net.Query { diff --git a/src/TeamSpeak3QueryApi/Query/Protocols/SshProtocol.cs b/src/TeamSpeak3QueryApi/Query/SshQueryClient.cs similarity index 96% rename from src/TeamSpeak3QueryApi/Query/Protocols/SshProtocol.cs rename to src/TeamSpeak3QueryApi/Query/SshQueryClient.cs index 87d771b..4c82393 100644 --- a/src/TeamSpeak3QueryApi/Query/Protocols/SshProtocol.cs +++ b/src/TeamSpeak3QueryApi/Query/SshQueryClient.cs @@ -11,27 +11,27 @@ using TeamSpeak3QueryApi.Net.Enums; using TeamSpeak3QueryApi.Net.Extensions; -namespace TeamSpeak3QueryApi.Net.Query.Protocols +namespace TeamSpeak3QueryApi.Net.Query { - public class SshProtocol : QueryClient + public class SshQueryClient : QueryClient { /// The default port which is used when no port is provided. public const short DefaultPort = 10022; /// Creates a new instance of using the and . - public SshProtocol() + public SshQueryClient() : this(DefaultHost, DefaultPort) { } /// Creates a new instance of using the provided host and the . /// The host name of the remote server. - public SshProtocol(string hostName) + public SshQueryClient(string hostName) : this(hostName, DefaultPort) { } /// Creates a new instance of using the provided host TCP port. /// The host name of the remote server. /// The TCP port of the Query API server. - public SshProtocol(string hostName, int port) + public SshQueryClient(string hostName, int port) { if (string.IsNullOrWhiteSpace(hostName)) throw new ArgumentNullException(nameof(hostName)); diff --git a/src/TeamSpeak3QueryApi/Query/Protocols/TelnetProtocol.cs b/src/TeamSpeak3QueryApi/Query/TelnetQueryClient.cs similarity index 95% rename from src/TeamSpeak3QueryApi/Query/Protocols/TelnetProtocol.cs rename to src/TeamSpeak3QueryApi/Query/TelnetQueryClient.cs index 712f3f9..44e7323 100644 --- a/src/TeamSpeak3QueryApi/Query/Protocols/TelnetProtocol.cs +++ b/src/TeamSpeak3QueryApi/Query/TelnetQueryClient.cs @@ -1,35 +1,33 @@ using System; -using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Net.Sockets; -using System.Text; using System.Threading; using System.Threading.Tasks; using TeamSpeak3QueryApi.Net.Enums; using TeamSpeak3QueryApi.Net.Extensions; -namespace TeamSpeak3QueryApi.Net.Query.Protocols +namespace TeamSpeak3QueryApi.Net.Query { - public class TelnetProtocol : QueryClient + public class TelnetQueryClient : QueryClient { /// The default port which is used when no port is provided. public const short DefaultPort = 10011; /// Creates a new instance of using the and . - public TelnetProtocol() + public TelnetQueryClient() : this(DefaultHost, DefaultPort) { } /// Creates a new instance of using the provided host and the . /// The host name of the remote server. - public TelnetProtocol(string hostName) + public TelnetQueryClient(string hostName) : this(hostName, DefaultPort) { } /// Creates a new instance of using the provided host TCP port. /// The host name of the remote server. /// The TCP port of the Query API server. - public TelnetProtocol(string hostName, int port) + public TelnetQueryClient(string hostName, int port) { if (string.IsNullOrWhiteSpace(hostName)) throw new ArgumentNullException(nameof(hostName)); diff --git a/src/TeamSpeak3QueryApi/TeamSpeakClient.cs b/src/TeamSpeak3QueryApi/TeamSpeakClient.cs index dd4b175..db3dd6a 100644 --- a/src/TeamSpeak3QueryApi/TeamSpeakClient.cs +++ b/src/TeamSpeak3QueryApi/TeamSpeakClient.cs @@ -10,11 +10,9 @@ using TeamSpeak3QueryApi.Net.Query; using TeamSpeak3QueryApi.Net.Enums; using TeamSpeak3QueryApi.Net.Extensions; -using System.Diagnostics; using TeamSpeak3QueryApi.Net.Query.Parameters; using TeamSpeak3QueryApi.Net.Query.Responses; using TeamSpeak3QueryApi.Net.Query.Enums; -using TeamSpeak3QueryApi.Net.Query.Protocols; using TeamSpeak3QueryApi.Net.Query.Notifications; namespace TeamSpeak3QueryApi.Net @@ -32,21 +30,21 @@ public class TeamSpeakClient : IDisposable /// Creates a new instance of using the and . public TeamSpeakClient() - : this(QueryClient.DefaultHost, TelnetProtocol.DefaultPort, Protocol.Telnet) + : this(QueryClient.DefaultHost, TelnetQueryClient.DefaultPort, Protocol.Telnet) { } /// Creates a new instance of using the provided host TCP port. /// The host name of the remote server. /// The TCP port of the Query API server. - public TeamSpeakClient(string hostName, int port = TelnetProtocol.DefaultPort, Protocol type = Protocol.Telnet) + public TeamSpeakClient(string hostName, int port = TelnetQueryClient.DefaultPort, Protocol type = Protocol.Telnet) { switch (type) { case Protocol.Telnet: - Client = new TelnetProtocol(hostName, port); + Client = new TelnetQueryClient(hostName, port); break; case Protocol.SSH: - Client = new SshProtocol(hostName, port); + Client = new SshQueryClient(hostName, port); break; } _fileTransferClient = new FileTransferClient(hostName); From be69cafbe3d53c7e713a8e056527e74783068515 Mon Sep 17 00:00:00 2001 From: Lukas Gundermann Date: Fri, 28 Aug 2020 11:50:08 +0200 Subject: [PATCH 14/14] Fix unsubscribe bug --- src/TeamSpeak3QueryApi/TeamSpeakClient.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TeamSpeak3QueryApi/TeamSpeakClient.cs b/src/TeamSpeak3QueryApi/TeamSpeakClient.cs index db3dd6a..5cf29f7 100644 --- a/src/TeamSpeak3QueryApi/TeamSpeakClient.cs +++ b/src/TeamSpeak3QueryApi/TeamSpeakClient.cs @@ -80,7 +80,7 @@ public void Unsubscribe(Action> callback) where T : Notification { var notification = GetNotificationType(); - var cbt = _callbacks.SingleOrDefault(t => t.Item1 == notification && t.Item2 == callback as object); + var cbt = _callbacks.SingleOrDefault(t => t.Item1 == notification && t.Item2.Equals(callback)); if (cbt != null) Client.Unsubscribe(notification.ToString(), cbt.Item3); }