public void StartListening() { _cancellationToken = new CancellationTokenSource(); _networkStream = _tcpClient.GetStream(); _listeningTask = new Task(() => { $"### Client {ClientId} starts listening now...".Dump(); try { while (_networkStream != null && _networkStream.CanRead && !_cancellationToken.Token.IsCancellationRequested) { byte[] rcvBuffer = new byte[_tcpClient.ReceiveBufferSize]; int sumNumberOfBytesRead = 0; int numberOfBytesRead = 0; string completeMessage = string.Empty; //do //{ // numberOfBytesRead = _networkStream.Read(rcvBuffer, 0, rcvBuffer.Length); // sumNumberOfBytesRead += numberOfBytesRead; // completeMessage = string.Concat(completeMessage, Encoding.ASCII.GetString(rcvBuffer, 0, numberOfBytesRead)); //} //while (_networkStream.DataAvailable); numberOfBytesRead = _networkStream.Read(rcvBuffer, 0, rcvBuffer.Length); sumNumberOfBytesRead += numberOfBytesRead; completeMessage = string.Concat(completeMessage, Encoding.ASCII.GetString(rcvBuffer, 0, numberOfBytesRead)); if (!string.IsNullOrWhiteSpace(completeMessage)) { $" RECEIVING | {completeMessage}".Dump(); var singleCommands = completeMessage.Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries); foreach (var singleCommand in singleCommands) { foreach (var subscribeCommand in _settings.SubscribeCommand.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries)) { if (singleCommand.StartsWith(subscribeCommand)) { var symbol = singleCommand.Substring(singleCommand.IndexOf(" ")).Trim(); _symbols.Add(symbol); OnSubscriptionReceived?.Invoke(symbol); } } foreach (var unsubscribeCommand in _settings.UnsubscribeCommand.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries)) { if (singleCommand.StartsWith(unsubscribeCommand)) { var symbol = singleCommand.Substring(singleCommand.IndexOf(" ")).Trim(); _symbols.Remove(symbol); OnUnsubscribeReceived?.Invoke(symbol); } } } OnMessageReceived?.Invoke(completeMessage); } if (_settings.SendReplyCommands) { foreach (var key in _settings.ReplyCommands.Keys) { if (completeMessage.Contains(key)) { SendMessage("MESSAGE", _settings.ReplyCommands[key]); } } } } } catch (Exception ex) { $"### Client {ClientId} throws exception: {ex.Message}".Dump(); } $"### Client {ClientId} stops listening now...".Dump(); this.Close(); }, _cancellationToken.Token); _listeningTask.Start(); }
private void HandleChannelMessage(string ircRawMessage, string channelName, IRCParser.TwitchChannelMessageType channelMessageType) { switch (channelMessageType) { case IRCParser.TwitchChannelMessageType.Usernotice: { UserNotice usernotice = new UserNotice(ircRawMessage); if (usernotice.MessageID != UserNotice.SubscriptionType.None) { OnSubscriptionEventArgs subEvent = new OnSubscriptionEventArgs(usernotice); OnSubscriptionReceived?.Invoke(this, subEvent); } return; } case IRCParser.TwitchChannelMessageType.ChannelMessage: { ChatMessage chatMessage = new ChatMessage(ircRawMessage); OnChatMessageReceivedEventArgs onChatReceivedEvent = new OnChatMessageReceivedEventArgs(chatMessage); OnChatMessageReceived?.Invoke(this, onChatReceivedEvent); return; } case IRCParser.TwitchChannelMessageType.LeftChannel: { // USER LEFT CHANNEL //:[email protected] PART #sirtucx string sUsername = ircRawMessage.Substring(1, ircRawMessage.IndexOf('!') - 1); OnUserLeaveEventArgs onUserLeaveEventArgs = new OnUserLeaveEventArgs(sUsername, channelName); OnUserLeaveEvent?.Invoke(this, onUserLeaveEventArgs); return; } case IRCParser.TwitchChannelMessageType.Mode: { string[] sModeSplit = ircRawMessage.Split(' '); if (sModeSplit[3] == "+o") { // TODO: MOD JOINED CHANNEL } else if (sModeSplit[3] == "-o") { // TODO: MOD LEFT CHANNEL } else { // TODO: UNKNOWN } return; } case IRCParser.TwitchChannelMessageType.Notice: { if (ircRawMessage.Contains("Improperly formatted auth")) { // TODO: AUTH ERROR } else if (ircRawMessage.Contains("has gone offline")) { // TODO: HOST LEFT } else if (ircRawMessage.Contains("The moderators of this room are:")) { // TODO: LIST ALL MODERATORS } else if (ircRawMessage.Contains("Your color has been changed.")) { // TODO: DETECT COLOR CHANGE } return; } case IRCParser.TwitchChannelMessageType.RoomState: { // TODO: ROOM STATE CHANGED return; } case IRCParser.TwitchChannelMessageType.UserState: { // USER JOINED CHANNEL // Example: @badges=staff/1;color=#0D4200;display-name=ronni;emote-sets=0,33,50,237,793,2126,3517,4578,5569,9400,10337,12239;mod=1;subscriber=1;turbo=1;user-type=staff :tmi.twitch.tv USERSTATE #dallas UserState userState = new UserState(ircRawMessage); OnUserJoinedEventArgs onUserJoinedEventArgs = new OnUserJoinedEventArgs(userState); OnUserJoinedEvent?.Invoke(this, onUserJoinedEventArgs); return; } case IRCParser.TwitchChannelMessageType.ClearChat: { // TODO: HANDLE BANS/TIMEOUTS return; } } }