コード例 #1
0
 public ChatMessage(string botUsername, string userId, string userName, string displayName, string colorHex, Color color, EmoteSet emoteSet,
                    string message, UserType userType, string channel, string id, bool isSubscriber, int subscribedMonthCount, string roomId, bool isTurbo, bool isModerator,
                    bool isMe, bool isBroadcaster, Noisy noisy, string rawIrcMessage, string emoteReplacedMessage, List <KeyValuePair <string, string> > badges,
                    CheerBadge cheerBadge, int bits, double bitsInDollars)
 {
     BotUsername          = botUsername;
     UserId               = userId;
     DisplayName          = displayName;
     ColorHex             = colorHex;
     Color                = color;
     EmoteSet             = emoteSet;
     Message              = message;
     UserType             = userType;
     Channel              = channel;
     Id                   = id;
     IsSubscriber         = isSubscriber;
     SubscribedMonthCount = subscribedMonthCount;
     RoomId               = roomId;
     IsTurbo              = isTurbo;
     IsModerator          = isModerator;
     IsMe                 = isMe;
     IsBroadcaster        = isBroadcaster;
     Noisy                = Noisy;
     RawIrcMessage        = rawIrcMessage;
     EmoteReplacedMessage = emoteReplacedMessage;
     Badges               = badges;
     CheerBadge           = cheerBadge;
     Bits                 = bits;
     BitsInDollars        = bitsInDollars;
 }
コード例 #2
0
        //Example IRC message: @badges=moderator/1,warcraft/alliance;color=;display-name=Swiftyspiffyv4;emotes=;mod=1;room-id=40876073;subscriber=0;turbo=0;user-id=103325214;user-type=mod :[email protected] PRIVMSG #swiftyspiffy :asd
        /// <summary>Constructor for ChatMessage object.</summary>
        /// <param name="botUsername">The username of the bot that received the message.</param>
        /// <param name="ircMessage">The IRC message from Twitch to be processed.</param>
        /// <param name="emoteCollection">The <see cref="MessageEmoteCollection"/> to register new emotes on and, if desired, use for emote replacement.</param>
        /// <param name="replaceEmotes">Whether to replace emotes for this chat message. Defaults to false.</param>
        public ChatMessage(
            string botUsername,
            IrcMessage ircMessage,
            ref MessageEmoteCollection emoteCollection,
            bool replaceEmotes = false)
        {
            BotUsername      = botUsername;
            RawIrcMessage    = ircMessage.ToString();
            Message          = ircMessage.Message;
            _emoteCollection = emoteCollection;

            Username = ircMessage.User;
            Channel  = ircMessage.Channel;

            foreach (var tag in ircMessage.Tags.Keys)
            {
                var tagValue = ircMessage.Tags[tag];

                switch (tag)
                {
                case Tags.Badges:
                    Badges = Common.Helpers.ParseBadges(tagValue);
                    // Iterate through saved badges for special circumstances
                    foreach (var badge in Badges)
                    {
                        switch (badge.Key)
                        {
                        case "bits":
                            CheerBadge = new CheerBadge(int.Parse(badge.Value));
                            break;

                        case "subscriber":
                            // Prioritize BadgeInfo subscribe count, as its more accurate
                            if (SubscribedMonthCount == 0)
                            {
                                SubscribedMonthCount = int.Parse(badge.Value);
                            }
                            break;

                        case "vip":
                            IsVip = true;
                            break;
                        }
                    }
                    break;

                case Tags.BadgeInfo:
                    BadgeInfo = Common.Helpers.ParseBadges(tagValue);
                    // check if founder is one of them, and get months from that
                    var founderBadge = BadgeInfo.Find(b => b.Key == "founder");
                    if (!founderBadge.Equals(default(KeyValuePair <string, string>)))
                    {
                        IsSubscriber         = true;
                        SubscribedMonthCount = int.Parse(founderBadge.Value);
                    }
                    else
                    {
                        var subBadge = BadgeInfo.Find(b => b.Key == "subscriber");
                        // BadgeInfo has better accuracy than Badges subscriber value
                        if (!subBadge.Equals(default(KeyValuePair <string, string>)))
                        {
                            SubscribedMonthCount = int.Parse(subBadge.Value);
                        }
                    }
                    break;

                case Tags.Bits:
                    Bits          = int.Parse(tagValue);
                    BitsInDollars = ConvertBitsToUsd(Bits);
                    break;

                case Tags.Color:
                    ColorHex = tagValue;
                    if (!string.IsNullOrWhiteSpace(ColorHex))
                    {
                        Color = ColorTranslator.FromHtml(ColorHex);
                    }
                    break;

                case Tags.CustomRewardId:
                    CustomRewardId = tagValue;
                    break;

                case Tags.DisplayName:
                    DisplayName = tagValue;
                    break;

                case Tags.Emotes:
                    EmoteSet = new EmoteSet(tagValue, Message);
                    break;

                case Tags.Id:
                    Id = tagValue;
                    break;

                case Tags.MsgId:
                    handleMsgId(tagValue);
                    break;

                case Tags.Mod:
                    IsModerator = Common.Helpers.ConvertToBool(tagValue);
                    break;

                case Tags.Noisy:
                    Noisy = Common.Helpers.ConvertToBool(tagValue) ? Noisy.True : Noisy.False;
                    break;

                case Tags.RoomId:
                    RoomId = tagValue;
                    break;

                case Tags.Subscriber:
                    // this check because when founder is set, the subscriber value is actually 0, which is problematic
                    IsSubscriber = IsSubscriber == false?Common.Helpers.ConvertToBool(tagValue) : true;

                    break;

                case Tags.TmiSentTs:
                    TmiSentTs = tagValue;
                    break;

                case Tags.Turbo:
                    IsTurbo = Common.Helpers.ConvertToBool(tagValue);
                    break;

                case Tags.UserId:
                    UserId = tagValue;
                    break;

                case Tags.UserType:
                    switch (tagValue)
                    {
                    case "mod":
                        UserType = UserType.Moderator;
                        break;

                    case "global_mod":
                        UserType = UserType.GlobalModerator;
                        break;

                    case "admin":
                        UserType = UserType.Admin;
                        break;

                    case "staff":
                        UserType = UserType.Staff;
                        break;

                    default:
                        UserType = UserType.Viewer;
                        break;
                    }
                    break;
                }
            }

            if (Message.Length > 0 && (byte)Message[0] == 1 && (byte)Message[Message.Length - 1] == 1)
            {
                //Actions (/me {action}) are wrapped by byte=1 and prepended with "ACTION "
                //This setup clears all of that leaving just the action's text.
                //If you want to clear just the nonstandard bytes, use:
                //_message = _message.Substring(1, text.Length-2);
                if (Message.StartsWith("\u0001ACTION ") && Message.EndsWith("\u0001"))
                {
                    Message = Message.Trim('\u0001').Substring(7);
                    IsMe    = true;
                }
            }

            //Parse the emoteSet
            if (EmoteSet != null && Message != null && EmoteSet.Emotes.Count > 0)
            {
                var uniqueEmotes = EmoteSet.RawEmoteSetString.Split('/');
                foreach (var emote in uniqueEmotes)
                {
                    var firstColon = emote.IndexOf(':');
                    var firstComma = emote.IndexOf(',');
                    if (firstComma == -1)
                    {
                        firstComma = emote.Length;
                    }
                    var firstDash = emote.IndexOf('-');
                    if (firstColon > 0 && firstDash > firstColon && firstComma > firstDash)
                    {
                        if (int.TryParse(emote.Substring(firstColon + 1, firstDash - firstColon - 1), out var low) &&
                            int.TryParse(emote.Substring(firstDash + 1, firstComma - firstDash - 1), out var high))
                        {
                            if (low >= 0 && low < high && high < Message.Length)
                            {
                                //Valid emote, let's parse
                                var id = emote.Substring(0, firstColon);
                                //Pull the emote text from the message
                                var text = Message.Substring(low, high - low + 1);
                                _emoteCollection.Add(new MessageEmote(id, text));
                            }
                        }
                    }
                }
                if (replaceEmotes)
                {
                    EmoteReplacedMessage = _emoteCollection.ReplaceEmotes(Message);
                }
            }

            if (EmoteSet == null)
            {
                EmoteSet = new EmoteSet(default(string), Message);
            }

            // Check if display name was set, and if it wasn't, set it to username
            if (string.IsNullOrEmpty(DisplayName))
            {
                DisplayName = Username;
            }

            // Check if message is from broadcaster
            if (string.Equals(Channel, Username, StringComparison.InvariantCultureIgnoreCase))
            {
                UserType      = UserType.Broadcaster;
                IsBroadcaster = true;
            }

            if (Channel.Split(':').Length == 3)
            {
                if (string.Equals(Channel.Split(':')[1], UserId, StringComparison.InvariantCultureIgnoreCase))
                {
                    UserType      = UserType.Broadcaster;
                    IsBroadcaster = true;
                }
            }
        }
コード例 #3
0
        //Example IRC message: @badges=moderator/1,warcraft/alliance;color=;display-name=Swiftyspiffyv4;emotes=;mod=1;room-id=40876073;subscriber=0;turbo=0;user-id=103325214;user-type=mod :[email protected] PRIVMSG #swiftyspiffy :asd
        /// <summary>Constructor for ChatMessage object.</summary>
        /// <param name="botUsername">The username of the bot that received the message.</param>
        /// <param name="ircString">The raw string received from Twitch to be processed.</param>
        /// <param name="emoteCollection">The <see cref="MessageEmoteCollection"/> to register new emotes on and, if desired, use for emote replacement.</param>
        /// <param name="replaceEmotes">Whether to replace emotes for this chat message. Defaults to false.</param>
        public ChatMessage(string botUsername, string ircString, ref MessageEmoteCollection emoteCollection, bool replaceEmotes = false)
        {
            BotUsername      = botUsername;
            RawIrcMessage    = ircString;
            _emoteCollection = emoteCollection;

            Username = ircString.Split('!')[1].Split('@')[0];
            Channel  = ircString.Split(new[] { " #" }, StringSplitOptions.None)[1].Split(' ')[0];

            var userTypeStr = ircString.Split(new[] { ";user-type=" }, StringSplitOptions.None)[1].Split(' ')[0];

            switch (userTypeStr)
            {
            case "mod":
                UserType = Enums.UserType.Moderator;
                break;

            case "global_mod":
                UserType = Enums.UserType.GlobalModerator;
                break;

            case "admin":
                UserType = Enums.UserType.Admin;
                break;

            case "staff":
                UserType = Enums.UserType.Staff;
                break;

            default:
                UserType = Enums.UserType.Viewer;
                break;
            }

            var parts = ircString.Split(new[] { $":{Username}!{Username}@{Username}.tmi.twitch.tv" }, StringSplitOptions.None)[0].Split(';');

            foreach (var part in parts)
            {
                if (part.Contains("@badges="))
                {
                    Badges = new List <KeyValuePair <string, string> >();
                    var badges = part.Split('=')[1];
                    if (badges.Contains('/'))
                    {
                        if (!badges.Contains(","))
                        {
                            Badges.Add(new KeyValuePair <string, string>(badges.Split('/')[0], badges.Split('/')[1]));
                        }
                        else
                        {
                            foreach (var badge in badges.Split(','))
                            {
                                Badges.Add(new KeyValuePair <string, string>(badge.Split('/')[0], badge.Split('/')[1]));
                            }
                        }
                    }
                    // Iterate through saved badges for special circumstances
                    foreach (var badge in Badges)
                    {
                        switch (badge.Key)
                        {
                        case "bits":
                            CheerBadge = new CheerBadge(int.Parse(badge.Value));
                            break;

                        case "subscriber":
                            SubscribedMonthCount = int.Parse(badge.Value);
                            break;
                        }
                    }
                }
                else if (part.Contains("bits="))
                {
                    Bits          = int.Parse(part.Split('=')[1]);
                    BitsInDollars = ConvertBitsToUsd(Bits);
                }
                else if (part.Contains("color="))
                {
                    if (ColorHex == null)
                    {
                        ColorHex = part.Split('=')[1];
                    }
                    if (!string.IsNullOrEmpty(ColorHex))
                    {
                        Color = ColorTranslator.FromHtml(ColorHex);
                    }
                }
                else if (part.Contains("display-name"))
                {
                    if (DisplayName == null)
                    {
                        DisplayName = part.Split('=')[1];
                    }
                }
                else if (part.Contains("emotes="))
                {
                    if (_emoteSetStorage == null)
                    {
                        _emoteSetStorage = part.Split('=')[1];
                    }
                }
                else if (part.Contains("subscriber="))
                {
                    IsSubscriber = part.Split('=')[1] == "1";
                }
                else if (part.Contains("turbo="))
                {
                    IsTurbo = part.Split('=')[1] == "1";
                }
                else if (part.Contains("user-id="))
                {
                    UserId = part.Split('=')[1];
                }
                else if (part.Contains("mod="))
                {
                    IsModerator = part.Split('=')[1] == "1";
                }
                else if (part.Contains("room-id="))
                {
                    RoomId = part.Split('=')[1];
                }
                else if (part.Contains("noisy="))
                {
                    Noisy = part.Split('=')[1] == "1" ? Enums.Noisy.True : Enums.Noisy.False;
                }
            }
            Message  = ircString.Split(new[] { $" PRIVMSG #{Channel} :" }, 2, StringSplitOptions.None)[1];
            EmoteSet = new EmoteSet(_emoteSetStorage, Message);
            if (Message.Length > 0 && (byte)Message[0] == 1 && (byte)Message[Message.Length - 1] == 1)
            {
                //Actions (/me {action}) are wrapped by byte=1 and prepended with "ACTION "
                //This setup clears all of that leaving just the action's text.
                //If you want to clear just the nonstandard bytes, use:
                //_message = _message.Substring(1, text.Length-2);
                if (Message.StartsWith("\u0001ACTION ") && Message.EndsWith("\u0001"))
                {
                    Message = Message.Trim('\u0001').Substring(7);
                    IsMe    = true;
                }
            }

            //Parse the emoteSet
            if (EmoteSet != null && Message != null && EmoteSet.Emotes.Count > 0)
            {
                var    uniqueEmotes = EmoteSet.RawEmoteSetString.Split('/');
                string id, text;
                int    firstColon, firstComma, firstDash, low, high;
                foreach (var emote in uniqueEmotes)
                {
                    firstColon = emote.IndexOf(':');
                    firstComma = emote.IndexOf(',');
                    if (firstComma == -1)
                    {
                        firstComma = emote.Length;
                    }
                    firstDash = emote.IndexOf('-');
                    if (firstColon > 0 && firstDash > firstColon && firstComma > firstDash)
                    {
                        if (int.TryParse(emote.Substring(firstColon + 1, firstDash - firstColon - 1), out low) &&
                            int.TryParse(emote.Substring(firstDash + 1, firstComma - firstDash - 1), out high))
                        {
                            if (low >= 0 && low < high && high < Message.Length)
                            {
                                //Valid emote, let's parse
                                id = emote.Substring(0, firstColon);
                                //Pull the emote text from the message
                                text = Message.Substring(low, high - low + 1);
                                _emoteCollection.Add(new MessageEmote(id, text));
                            }
                        }
                    }
                }
                if (replaceEmotes)
                {
                    EmoteReplacedMessage = _emoteCollection.ReplaceEmotes(Message);
                }
            }

            // Check if display name was set, and if it wasn't, set it to username
            if (string.IsNullOrEmpty(DisplayName))
            {
                DisplayName = Username;
            }

            // Check if message is from broadcaster
            if (string.Equals(Channel, Username, StringComparison.InvariantCultureIgnoreCase))
            {
                UserType      = Enums.UserType.Broadcaster;
                IsBroadcaster = true;
            }

            if (Channel.Split(':').Length == 3)
            {
                if (string.Equals(Channel.Split(':')[1], UserId, StringComparison.InvariantCultureIgnoreCase))
                {
                    UserType      = Enums.UserType.Broadcaster;
                    IsBroadcaster = true;
                }
            }
            if (string.Equals(Channel, Username, StringComparison.InvariantCultureIgnoreCase))
            {
                UserType      = Enums.UserType.Broadcaster;
                IsBroadcaster = true;
            }
        }