protected async void ReadLoop() { while (Client != null && Client.Connected) { string message = await ReadLineAsync(false).ConfigureAwait(false); if (message == null) { continue; } if (message.StartsWith("error", StringComparison.CurrentCultureIgnoreCase)) { if (!AtLeastOneResponseReceived) { AtLeastOneResponseReceived = true; // Remove welcome messages after connect ReceivedLines.Clear(); } string responseText = string.Join("\n\r", ReceivedLines.Concat(new[] { message })); MessageResponses.Enqueue(responseText); ReceivedLines.Clear(); SimpleResponse response = SimpleResponse.Parse(responseText); if (response.IsBanned) { BanDetected?.Invoke(this, new EventArgs <SimpleResponse>(response)); DisconnectForced("Banned!"); return; } } else if (message.StartsWith("notify", StringComparison.CurrentCultureIgnoreCase)) { ThreadPool.QueueUserWorkItem(OnNotificationReceived, message); } else { if (!AtLeastOneResponseReceived) { const string LastServerConnectionHandlerIdText = "selected schandlerid="; if (message.StartsWith(LastServerConnectionHandlerIdText, StringComparison.InvariantCultureIgnoreCase) && int.TryParse(message.Substring(LastServerConnectionHandlerIdText.Length).Trim(), out int handlerId)) { LastServerConnectionHandlerId = handlerId; } } ReceivedLines.Add(message); } } }
public async Task <ConnectResponse> ConnectAsync() { if (Client != null) { return(new ConnectResponse(message: "Already connected!")); } Client = new TcpClient(); await Client.ConnectAsync(Host, Port).ConfigureAwait(false); if (!Client.Connected) { throw new IOException($"Could not connect to {Host} on port {Port}."); } ReceivedLines.Clear(); AtLeastOneResponseReceived = false; ClientStream = Client.GetStream(); ClientReader = new StreamReader(ClientStream); ClientWriter = new StreamWriter(ClientStream) { NewLine = "\n" }; string message = await ReadLineAsync().ConfigureAwait(false); CommunicationLog.RawMessageReceived(message); QueryType queryType; if (message.StartsWith("TS3", StringComparison.OrdinalIgnoreCase)) { queryType = QueryType.Server; } else if (message.StartsWith("TS3 Client", StringComparison.OrdinalIgnoreCase)) { queryType = QueryType.Client; } else { string statusMessage = $"Invalid greeting received: {message}"; DisconnectForced(statusMessage); return(new ConnectResponse(statusMessage)); } Connected = true; ReadLoopTask = Task.Factory.StartNew(ReadLoop, TaskCreationOptions.LongRunning); KeepAliveTask = Task.Factory.StartNew(KeepAliveLoop, TaskCreationOptions.LongRunning); return(new ConnectResponse(message, queryType, true)); }
private void DisconnectForced(string reason) { bool clientWasConnected = Client?.Connected == true; ReceivedLines.Clear(); Client?.Dispose(); ClientStream?.Dispose(); ClientReader?.Dispose(); ClientWriter?.Dispose(); Client = null; ClientStream = null; ClientReader = null; ClientWriter = null; Connected = false; ReadLoopTask = null; KeepAliveTask = null; if (clientWasConnected) { ConnectionClosed?.Invoke(this, new EventArgs <string>(reason)); } }
protected async void ReadLoop() { while (Client != null && Client.Connected) { string message = await ReadLineAsync(false).ConfigureAwait(false); CommunicationLog.RawMessageReceived(message); if (message == null) { continue; } if (message.StartsWith("error", StringComparison.CurrentCultureIgnoreCase)) { if (!AtLeastOneResponseReceived) { AtLeastOneResponseReceived = true; // Remove welcome messages after connect ReceivedLines.Clear(); } string responseText = string.Join(Util.QUERY_LINE_BREAK, ReceivedLines.Concat(new[] { message })); MessageResponses.Enqueue(responseText); ReceivedLines.Clear(); CommandResponse commandResponse = new CommandResponse(); commandResponse.ApplyResponseText(responseText); if (commandResponse.IsBanned) { BanDetected?.Invoke(this, new EventArgs <ICommandResponse>(commandResponse)); DisconnectForced("Banned!"); return; } } else if (message.StartsWith("notify", StringComparison.CurrentCultureIgnoreCase)) { // If 2 or more notifications are equal in a 200ms range, consider just one of them. if (LastRawNotification == message && (DateTime.Now - LastNotificationTime).TotalMilliseconds < 200) { continue; } LastRawNotification = message; LastNotificationTime = DateTime.Now; int indexOfFirstWhitespace = message.IndexOf(' '); string notificationName = message.Substring(0, indexOfFirstWhitespace); NotificationHub?.HandleRawNotification(this, notificationName, message); } else { if (!AtLeastOneResponseReceived) { const string LastServerConnectionHandlerIdText = "selected schandlerid="; if (message.StartsWith(LastServerConnectionHandlerIdText, StringComparison.CurrentCultureIgnoreCase) && int.TryParse(message.Substring(LastServerConnectionHandlerIdText.Length).Trim(), out int handlerId)) { LastServerConnectionHandlerId = handlerId; } } ReceivedLines.Add(message); } } }