private void ParseIrcMessage(string ircMessage) { // Hack to accomodate at least cyrillic characters, possibly more string decodedMessage = Encoding.UTF8.GetString(Encoding.Default.GetBytes(ircMessage)); #region Chat Parsing DetectionReturn response; // On Connected if (ChatParsing.detectConnected(decodedMessage)) { IsConnected = true; OnConnected?.Invoke(this, new OnConnectedArgs { AutoJoinChannel = "", Username = TwitchUsername }); return; } // On New Subscriber response = ChatParsing.detectNewSubscriber(decodedMessage, JoinedChannels); if (response.Successful) { OnNewSubscriber?.Invoke(this, new OnNewSubscriberArgs { Subscriber = new NewSubscriber(decodedMessage), Channel = response.Channel }); return; } // On Command Received (PURPOSELY DROP THROUGH WITHOUT RETURN) response = ChatParsing.detectCommandReceived(TwitchUsername, decodedMessage, JoinedChannels, ChannelEmotes, WillReplaceEmotes, _chatCommandIdentifiers); if (response.Successful) { var chatMessage = new ChatMessage(TwitchUsername, decodedMessage, ref _channelEmotes, WillReplaceEmotes); OnChatCommandReceived?.Invoke(this, new OnChatCommandReceivedArgs { Command = new ChatCommand(decodedMessage, chatMessage) }); // purposely drop through without return } // On Message Received response = ChatParsing.detectMessageReceived(decodedMessage, JoinedChannels); if (response.Successful) { var chatMessage = new ChatMessage(TwitchUsername, decodedMessage, ref _channelEmotes, WillReplaceEmotes); foreach (var joinedChannel in JoinedChannels.Where(x => x.Channel.ToLower() == response.Channel.ToLower())) { joinedChannel.HandleMessage(chatMessage); } OnMessageReceived?.Invoke(this, new OnMessageReceivedArgs { ChatMessage = chatMessage }); return; } // On Viewer Joined response = ChatParsing.detectUserJoined(decodedMessage, JoinedChannels); if (response.Successful) { if (TwitchUsername.ToLower() == decodedMessage.Split('!')[1].Split('@')[0].ToLower()) { OnJoinedChannel?.Invoke(this, new OnJoinedChannelArgs { Channel = response.Channel, Username = decodedMessage.Split('!')[1].Split('@')[0] }); } else { OnUserJoined?.Invoke(this, new OnUserJoinedArgs { Username = decodedMessage.Split('!')[1].Split('@')[0], Channel = response.Channel }); } return; } // On Viewer Left response = ChatParsing.detectedUserLeft(decodedMessage, JoinedChannels); if (response.Successful) { string username = decodedMessage.Split(':')[1].Split('!')[0]; if (username.ToLower() == TwitchUsername) { JoinedChannels.Remove(JoinedChannels.FirstOrDefault(x => x.Channel.ToLower() == response.Channel)); _hasSeenJoinedChannels.Remove(response.Channel.ToLower()); OnClientLeftChannel?.Invoke(this, new OnClientLeftChannelArgs { BotUsername = username, Channel = response.Channel }); } else { OnUserLeft?.Invoke(this, new OnUserLeftArgs { Username = username, Channel = response.Channel }); } return; } // On Moderator Joined response = ChatParsing.detectedModeratorJoined(decodedMessage, JoinedChannels); if (response.Successful) { OnModeratorJoined?.Invoke(this, new OnModeratorJoinedArgs { Username = decodedMessage.Split(' ')[4], Channel = response.Channel }); return; } // On Moderator Left response = ChatParsing.detectedModeatorLeft(decodedMessage, JoinedChannels); if (response.Successful) { OnModeratorLeft?.Invoke(this, new OnModeratorLeftArgs { Username = decodedMessage.Split(' ')[4], Channel = response.Channel }); return; } // On Incorrect login response = ChatParsing.detectedIncorrectLogin(decodedMessage); if (response.Successful) { Disconnect(); OnIncorrectLogin?.Invoke(this, new OnIncorrectLoginArgs { Exception = new ErrorLoggingInException(decodedMessage, _credentials.TwitchUsername) }); return; } // On Malformed OAuth response = ChatParsing.detectedMalformedOAuth(decodedMessage, JoinedChannels); if (response.Successful) { Disconnect(); OnIncorrectLogin?.Invoke(this, new OnIncorrectLoginArgs { Exception = new ErrorLoggingInException("Invalid OAuth key. Remember to add 'oauth:' as a prefix. Example: oauth:19nds9sbnga9asd", _credentials.TwitchUsername) }); return; } // On Host Left response = ChatParsing.detectedHostLeft(decodedMessage, JoinedChannels); if (response.Successful) { OnHostLeft?.Invoke(this, null); return; } // On Channel State Changed response = ChatParsing.detectedChannelStateChanged(decodedMessage, JoinedChannels); if (response.Successful) { OnChannelStateChanged?.Invoke(this, new OnChannelStateChangedArgs { ChannelState = new ChannelState(decodedMessage), Channel = response.Channel }); return; } // On User State Changed response = ChatParsing.detectedUserStateChanged(decodedMessage, JoinedChannels); if (response.Successful) { var userState = new UserState(decodedMessage); if (!_hasSeenJoinedChannels.Contains(userState.Channel.ToLower())) { // UserState fired from joining channel _hasSeenJoinedChannels.Add(userState.Channel.ToLower()); OnUserStateChanged?.Invoke(this, new OnUserStateChangedArgs { UserState = userState }); } else { // UserState fired from sending a message OnMessageSent?.Invoke(this, new OnMessageSentArgs { SentMessage = new SentMessage(userState, _lastMessageSent) }); } return; } // On ReSubscriber response = ChatParsing.detectedReSubscriber(decodedMessage, JoinedChannels); if (response.Successful) { var resub = new ReSubscriber(decodedMessage); OnReSubscriber?.Invoke(this, new OnReSubscriberArgs { ReSubscriber = resub }); return; } // On PING received response = ChatParsing.detectedPing(decodedMessage); if (response.Successful && !DisableAutoPong) { SendRaw("PONG"); return; } // On PONG received (don't do anything) response = ChatParsing.detectedPong(decodedMessage); if (response.Successful) { return; } // On Hosting Stopped if (ChatParsing.detectedHostingStopped(decodedMessage)) { int viewers; int.TryParse(decodedMessage.Split(' ')[4], out viewers); OnHostingStopped?.Invoke(this, new OnHostingStoppedArgs() { Viewers = viewers, HostingChannel = decodedMessage.Split(' ')[2].Remove(0, 1) }); return; } // On Hosting Started if (ChatParsing.detectedHostingStarted(decodedMessage)) { int viewers; int.TryParse(decodedMessage.Split(' ')[4], out viewers); OnHostingStarted?.Invoke(this, new OnHostingStartedArgs() { Viewers = viewers, HostingChannel = decodedMessage.Split(' ')[2].Remove(0, 1), TargetChannel = decodedMessage.Split(' ')[3].Remove(0, 1) }); return; } // On Existing Users Detected response = ChatParsing.detectedExistingUsers(decodedMessage, _credentials.TwitchUsername, JoinedChannels); if (response.Successful) { OnExistingUsersDetected?.Invoke(this, new OnExistingUsersDetectedArgs { Channel = response.Channel, Users = decodedMessage.Replace($":{_credentials.TwitchUsername}.tmi.twitch.tv 353 {_credentials.TwitchUsername} = #{response.Channel} :", "").Split(' ').ToList <string>() }); return; } // On Now Hosting response = ChatParsing.detectedNowHosting(decodedMessage, JoinedChannels); if (response.Successful) { OnNowHosting?.Invoke(this, new OnNowHostingArgs { Channel = response.Channel, HostedChannel = decodedMessage.Split(' ')[6].Replace(".", "") }); return; } // On channel join completed with all existing names response = ChatParsing.detectedJoinChannelCompleted(decodedMessage); if (response.Successful) { currentlyJoiningChannels = false; queueingJoinCheck(); } #endregion #region Clear Chat, Timeouts, and Bans // On clear chat detected response = ChatParsing.detectedClearedChat(decodedMessage, JoinedChannels); if (response.Successful) { OnChatCleared?.Invoke(this, new OnChatClearedArgs { Channel = response.Channel }); return; } // On timeout detected response = ChatParsing.detectedUserTimedout(decodedMessage, JoinedChannels); if (response.Successful) { OnUserTimedout?.Invoke(this, new OnUserTimedoutArgs { Channel = response.Channel, TimeoutDuration = int.Parse(decodedMessage.Split(';')[0].Split('=')[1]), TimeoutReason = decodedMessage.Split(' ')[0].Split('=')[2].Replace("\\s", " "), Username = decodedMessage.Split(':')[2] }); return; } // On ban detected response = ChatParsing.detectedUserBanned(decodedMessage, JoinedChannels); if (response.Successful) { OnUserBanned?.Invoke(this, new OnUserBannedArgs { Channel = response.Channel, BanReason = decodedMessage.Split(' ')[0].Split('=')[1].Replace("\\s", " "), Username = decodedMessage.Split(':')[2] }); return; } // On moderators received detected response = ChatParsing.detectedModeratorsReceived(decodedMessage, JoinedChannels); if (response.Successful) { OnModeratorsReceived?.Invoke(this, new OnModeratorsReceivedArgs { Channel = decodedMessage.Split('#')[1].Split(' ')[0], Moderators = decodedMessage.Replace(" ", "").Split(':')[3].Split(',').ToList <string>() }); return; } #endregion #region Others // On chat color changed detected response = ChatParsing.detectedChatColorChanged(decodedMessage, JoinedChannels); if (response.Successful) { OnChatColorChanged?.Invoke(this, new OnChatColorChangedArgs { Channel = decodedMessage.Split('#')[1].Split(' ')[0] }); return; } #endregion #region Whisper Parsing if (decodedMessage.Split(' ').Count() > 2 && (decodedMessage.Split(' ')[1] == "WHISPER" || decodedMessage.Split(' ')[2] == "WHISPER")) { // On Whisper Message Received WhisperMessage receivedMessage = null; if (WhisperParsing.detectedWhisperReceived(decodedMessage, _credentials.TwitchUsername)) { receivedMessage = new WhisperMessage(decodedMessage, _credentials.TwitchUsername); PreviousWhisper = receivedMessage; OnWhisperReceived?.Invoke(this, new OnWhisperReceivedArgs { WhisperMessage = receivedMessage }); // Fall through to detect command as well } // On Whisper Command Received if (WhisperParsing.detectedWhisperCommandReceived(decodedMessage, _credentials.TwitchUsername, _whisperCommandIdentifiers)) { var whisperMessage = new WhisperMessage(decodedMessage, _credentials.TwitchUsername); string command = whisperMessage.Message.Split(' ')?[0].Substring(1, whisperMessage.Message.Split(' ')[0].Length - 1) ?? whisperMessage.Message.Substring(1, whisperMessage.Message.Length - 1); var argumentsAsList = whisperMessage.Message.Split(' ')?.Where(arg => arg != whisperMessage.Message[0] + command).ToList <string>() ?? new List <string>(); string argumentsAsString = whisperMessage.Message.Replace(whisperMessage.Message.Split(' ')?[0] +" ", "") ?? ""; OnWhisperCommandReceived?.Invoke(this, new OnWhisperCommandReceivedArgs { Command = command, WhisperMessage = whisperMessage, ArgumentsAsList = argumentsAsList, ArgumentsAsString = argumentsAsString }); return; } // Return if whisper message was parsed successfully if (receivedMessage != null) { return; } } #endregion // Any other messages here if (_logging) { Common.Log($"Unaccounted for: {decodedMessage}"); } }
private void OnReadLine(object sender, ReadLineEventArgs e) { // Hack to accomodate at least cyrillic characters, possibly more string decodedMessage = Encoding.UTF8.GetString(Encoding.Default.GetBytes(e.Line)); if (_logging) { Console.WriteLine(decodedMessage); } #region Chat Parsing // On Connected if (ChatParsing.detectConnected(decodedMessage)) { _connected = true; OnConnected?.Invoke(null, new OnConnectedArgs { Channel = _channel, Username = TwitchUsername }); return; } // On New Subscriber if (ChatParsing.detectNewSubscriber(decodedMessage, _channel)) { OnNewSubscriber?.Invoke(null, new OnNewSubscriberArgs { Subscriber = new NewSubscriber(decodedMessage), Channel = _channel }); return; } // On Command Received (PURPOSELY DROP THROUGH WITHOUT RETURN) if (ChatParsing.detectCommandReceived(decodedMessage, _channel, _channelEmotes, WillReplaceEmotes, _chatCommandIdentifiers)) { var chatMessage = new ChatMessage(decodedMessage, ref _channelEmotes, WillReplaceEmotes); string command = chatMessage.Message.Split(' ')?[0].Substring(1, chatMessage.Message.Split(' ')[0].Length - 1) ?? chatMessage.Message.Substring(1, chatMessage.Message.Length - 1); var argumentsAsList = chatMessage.Message.Split(' ')?.Where(arg => arg != chatMessage.Message[0] + command).ToList <string>() ?? new List <string>(); string argumentsAsString = chatMessage.Message.Replace(chatMessage.Message.Split(' ')?[0] +" ", "") ?? ""; OnChatCommandReceived?.Invoke(null, new OnChatCommandReceivedArgs { Command = command, ChatMessage = chatMessage, Channel = _channel, ArgumentsAsList = argumentsAsList, ArgumentsAsString = argumentsAsString }); // purposely drop through without return } // On Message Received if (ChatParsing.detectMessageReceived(decodedMessage, _channel)) { var chatMessage = new ChatMessage(decodedMessage, ref _channelEmotes, WillReplaceEmotes); _previousMessage = chatMessage; OnMessageReceived?.Invoke(null, new OnMessageReceivedArgs { ChatMessage = chatMessage }); return; } // On Viewer Joined if (ChatParsing.detectViewerJoined(decodedMessage, _channel)) { OnViewerJoined?.Invoke(null, new OnViewerJoinedArgs { Username = decodedMessage.Split('!')[1].Split('@')[0], Channel = _channel }); return; } // On Viewer Left if (ChatParsing.detectedViewerLeft(decodedMessage, _channel)) { OnViewerLeft?.Invoke(null, new OnViewerLeftArgs { Username = decodedMessage.Split(':')[1].Split('!')[0], Channel = _channel }); return; } // On Moderator Joined if (ChatParsing.detectedModeratorJoined(decodedMessage, _channel)) { OnModeratorJoined?.Invoke(null, new OnModeratorJoinedArgs { Username = decodedMessage.Split(' ')[4], Channel = _channel }); return; } // On Moderator Left if (ChatParsing.detectedModeatorLeft(decodedMessage, _channel)) { OnModeratorLeft?.Invoke(null, new OnModeratorLeftArgs { Username = decodedMessage.Split(' ')[4], Channel = _channel }); return; } // On Incorrect login if (ChatParsing.detectedIncorrectLogin(decodedMessage, _channel)) { _client.Disconnect(); OnIncorrectLogin?.Invoke(null, new OnIncorrectLoginArgs { Exception = new ErrorLoggingInException(decodedMessage, _credentials.TwitchUsername) }); return; } // On Host Left if (ChatParsing.detectedHostLeft(decodedMessage, _channel)) { OnHostLeft?.Invoke(null, null); return; } // On Channel State Changed if (ChatParsing.detectedChannelStateChanged(decodedMessage, _channel)) { OnChannelStateChanged?.Invoke(null, new OnChannelStateChangedArgs { ChannelState = new ChannelState(decodedMessage) }); return; } // On User State Changed if (ChatParsing.detectedUserStateChanged(decodedMessage, _channel)) { OnUserStateChanged?.Invoke(null, new OnUserStateChangedArgs { UserState = new UserState(decodedMessage) }); return; } // On ReSubscriber if (ChatParsing.detectedReSubscriber(decodedMessage, _channel)) { OnReSubscriber?.Invoke(null, new OnReSubscriberArgs { ReSubscriber = new ReSubscriber(decodedMessage) }); return; } // On PING received if (ChatParsing.detectedPing(decodedMessage) && !DisableAutoPong) { SendRaw("PONG :tmi.twitch.tv"); return; } // On Hosting Stopped if (ChatParsing.detectedHostingStopped(decodedMessage)) { int viewers; int.TryParse(decodedMessage.Split(' ')[4], out viewers); OnHostingStopped?.Invoke(null, new OnHostingStoppedArgs() { Viewers = viewers, HostingChannel = decodedMessage.Split(' ')[2].Remove(0, 1) }); return; } // On Hosting Started if (ChatParsing.detectedHostingStarted(decodedMessage)) { int viewers; int.TryParse(decodedMessage.Split(' ')[4], out viewers); OnHostingStarted?.Invoke(null, new OnHostingStartedArgs() { Viewers = viewers, HostingChannel = decodedMessage.Split(' ')[2].Remove(0, 1), TargetChannel = decodedMessage.Split(' ')[3].Remove(0, 1) }); return; } // On Existing Users Detected if (ChatParsing.detectedExistingUsers(decodedMessage, _credentials.TwitchUsername)) { var parsedUsers = decodedMessage.Replace($":{_credentials.TwitchUsername}.tmi.twitch.tv 353 {_credentials.TwitchUsername} = #{_channel} :", "").Split(' '); OnExistingUsersDetected?.Invoke(null, new OnExistingUsersDetectedArgs { Channel = _channel, ExistingUsers = decodedMessage.Replace($":{_credentials.TwitchUsername}.tmi.twitch.tv 353 {_credentials.TwitchUsername} = #{_channel} :", "").Split(' ').ToList <string>() }); return; } #endregion #region Whisper Parsing if (decodedMessage.Split(' ').Count() > 2 && (decodedMessage.Split(' ')[1] == "WHISPER" || decodedMessage.Split(' ')[2] == "WHISPER")) { // On Whisper Message Received if (WhisperParsing.detectedWhisperReceived(decodedMessage, _credentials.TwitchUsername)) { OnWhisperReceived?.Invoke(null, new OnWhisperReceivedArgs { WhisperMessage = new WhisperMessage(decodedMessage, _credentials.TwitchUsername) }); return; } // On Whisper Command Received if (WhisperParsing.detectedWhisperCommandReceived(decodedMessage, _credentials.TwitchUsername, _whisperCommandIdentifiers)) { var whisperMessage = new WhisperMessage(decodedMessage, _credentials.TwitchUsername); string command = whisperMessage.Message.Split(' ')?[0].Substring(1, whisperMessage.Message.Split(' ')[0].Length - 1) ?? whisperMessage.Message.Substring(1, whisperMessage.Message.Length - 1); var argumentsAsList = whisperMessage.Message.Split(' ')?.Where(arg => arg != whisperMessage.Message[0] + command).ToList <string>() ?? new List <string>(); string argumentsAsString = whisperMessage.Message.Replace(whisperMessage.Message.Split(' ')?[0] +" ", "") ?? ""; OnWhisperCommandReceived?.Invoke(null, new OnWhisperCommandReceivedArgs { Command = command, WhisperMessage = whisperMessage, ArgumentsAsList = argumentsAsList, ArgumentsAsString = argumentsAsString }); } } #endregion // Any other messages here if (_logging) { Console.WriteLine($"Unaccounted for: {decodedMessage}"); } }