void ReceiveJoin(IrcMessage message) { string user = message.ExtractUser(); users.Add(user); UserJoined?.Invoke(this, user); }
void ReceivePart(IrcMessage message) { string user = message.ExtractUser(); users.Remove(user); UserLeft?.Invoke(this, user); }
void ProcessMessage(IrcMessage message) { if (message.Command == $":{message.Source}" && message.Arguments.Length > 0) { // twitch seems to have issues building proper irc messages ProcessMessage(new IrcMessage(message.Arguments[0], message.Arguments.Skip(1).ToArray())); return; } string channelname; switch (message.Command) { case "CAP": if (message.Arguments.Length < 3) { break; } if (message.Arguments[1] == "ACK") { CapAcknowledged?.Invoke(message.Arguments[2]); } break; case "PING": SendMessage(new IrcMessage("PONG", message.Arguments)); break; case "JOIN": channelname = GetChannelName(message.Arguments[0]); if (message.ExtractUser().ToLower() == user.ToLower()) { JoinChannel(channelname); } SendChannelMessage(channelname, message); break; case "PART": channelname = GetChannelName(message.Arguments[0]); SendChannelMessage(channelname, message); if (message.ExtractUser().ToLower() == user.ToLower()) { ChatChannel channel; lock (channellock) { if (channels.TryGetValue(channelname, out channel)) { channels.Remove(channelname); } } if (channel != null) { ChannelLeft?.Invoke(channel); } } break; case "tmi.twitch.tv RECONNECT": case "RECONNECT": Reconnect?.Invoke(); break; case "001": case "002": case "003": case "004": // connection success break; case "372": case "375": // message of the day break; case "376": connectionwait.Set(); // end of message of the day break; case "353": GetChannel(message.Arguments[2])?.OnMessage(message); break; case "366": GetChannel(message.Arguments[1])?.OnMessage(message); break; case "ROOMSTATE": case "PRIVMSG": case "USERNOTICE": case "NOTICE": case "USERSTATE": SendChannelMessage(message.Arguments[0], message); break; case "HOSTTARGET": if (!message.Arguments[1].StartsWith("-")) { TrySendChannelMessage(message.Arguments[0], message); TrySendChannelMessage(message.Arguments[1].Split(' ')[0], message); } break; case "MODE": // channel or user mode ... not that important for now break; default: Logger.Warning(this, "Unprocessed message", message.ToString()); break; } }
void ReceiveMessage(IrcMessage message) { ChatMessage chatmessage = new ChatMessage { User = message.ExtractUser(), Channel = message.Arguments[0].Substring(1), Message = message.Arguments[1] }; if (message.Tags != null) { foreach (IrcTag attribute in message.Tags) { if (string.IsNullOrEmpty(attribute.Value)) { continue; } switch (attribute.Key) { case "badges": chatmessage.Badges = ExtractBadges(attribute.Value).ToArray(); break; case "bits": chatmessage.Bits = int.Parse(attribute.Value); break; case "color": chatmessage.Color = attribute.Value; break; case "display-name": chatmessage.DisplayName = attribute.Value; break; case "emotes": chatmessage.Emotes = ExtractEmotes(attribute.Value).OrderBy(e => e.FirstIndex).ToArray(); break; case "id": chatmessage.ID = attribute.Value; break; case "mod": chatmessage.IsMod = attribute.Value == "1"; break; case "room-id": chatmessage.RoomID = attribute.Value; break; case "subscriber": chatmessage.IsSubscriber = attribute.Value == "1"; break; case "turbo": chatmessage.IsTurbo = attribute.Value == "1"; break; case "user-id": chatmessage.UserID = attribute.Value; break; case "user-type": chatmessage.UserType = (UserType)Enum.Parse(typeof(UserType), attribute.Value.Replace("_", ""), true); break; case "sent-ts": case "tmi-sent-ts": // not too interested in the timestamps for now break; case "emote-only": // this basically just tells us that the user has sent a message containing only emotes ... whatever ... break; default: Logger.Info(this, $"Unknown tag '{attribute.Key}' with value '{attribute.Value}' in chat message"); break; } } } MessageReceived?.Invoke(chatmessage); }