protected void Page_Load(object sender, EventArgs e) { if (this.drpBadges.Items.Count == 0) { DataSet ds = BadgeInfoProvider.GetBadges(null, null, 0, "BadgeDisplayName, BadgeIsAutomatic, BadgeID"); // Check dataset if (!DataHelper.DataSourceIsEmpty(ds)) { foreach (DataRow dr in ds.Tables[0].Rows) { BadgeInfo bi = new BadgeInfo(dr); // Create and add custom table list item string name = ResHelper.LocalizeString(bi.BadgeDisplayName); if (bi.BadgeIsAutomatic) { name += GetString("badge.automatic"); } drpBadges.Items.Add(new ListItem(name, bi.BadgeID.ToString())); } drpBadges.Items.Insert(0, new ListItem(GetString("general.selectnone"), "0")); drpBadges.SelectedValue = mValue; } } }
/// <summary> /// OK button click event handler. /// </summary> protected void btnOK_Click(object sender, EventArgs e) { // Validate entered values string error = new Validator().IsCodeName(txtName.Text.Trim(), GetString("general.invalidcodename")) .NotEmpty(txtDisplayName.Text.Trim(), GetString("badge.errors.displayname")).Result; // Save new values if (DataHelper.IsEmpty(error)) { // Check that code name is unique BadgeInfo bi = BadgeInfoProvider.GetBadgeInfo(txtName.Text.Trim()); if ((bi == null) || ((bi != null) && (bi.BadgeID == badgeId))) { // Update existing record if (bi == null) { bi = new BadgeInfo(); } // Set properties bi.BadgeID = badgeId; bi.BadgeName = txtName.Text.Trim(); bi.BadgeDisplayName = txtDisplayName.Text.Trim(); bi.BadgeImageURL = txtImageURL.Text.Trim(); int topLimit = ValidationHelper.GetInteger(txtTopLimit.Text.Trim(), 0); if (topLimit >= 0) { bi.BadgeTopLimit = topLimit; } else { bi.BadgeTopLimit = 0; } bi.BadgeIsAutomatic = chkIsAutomatic.Checked; // Save BadgeInfo BadgeInfoProvider.SetBadgeInfo(bi); URLHelper.Redirect("~/CMSModules/Badges/Badges_Edit.aspx?saved=1&badgeid=" + bi.BadgeID); } else { lblError.ResourceString = "badge.errors.uniquecodename"; lblError.Visible = true; } } else { lblError.ResourceString = error; //badge.errors.values lblError.Visible = true; } }
/// <summary> /// Loads data to fields. /// </summary> /// <param name="badgeId">ID of badge record</param> private void LoadData(BadgeInfo bi) { if (bi != null) { // Load data to appropriate fields txtName.Text = bi.BadgeName; txtDisplayName.Text = bi.BadgeDisplayName; txtImageURL.Text = bi.BadgeImageURL; chkIsAutomatic.Checked = bi.BadgeIsAutomatic; txtTopLimit.Text = bi.BadgeTopLimit.ToString(); } }
/// <summary> /// Creates badge. Called when the "Create badge" button is pressed. /// </summary> private bool CreateBadge() { // Create new badge object BadgeInfo newBadge = new BadgeInfo(); // Set the properties newBadge.BadgeDisplayName = "My new badge"; newBadge.BadgeName = "MyNewBadge"; newBadge.BadgeTopLimit = 50; newBadge.BadgeImageURL = GetImageUrl("Objects/CMS_Badge/Default/siteadmin.gif"); newBadge.BadgeIsAutomatic = true; // Save the badge BadgeInfoProvider.SetBadgeInfo(newBadge); return true; }
/// <summary> /// Gets and bulk updates badges. Called when the "Get and bulk update badges" button is pressed. /// Expects the CreateBadge method to be run first. /// </summary> private bool GetAndBulkUpdateBadges() { // Prepare the parameters string where = "BadgeName LIKE N'MyNewBadge%'"; // Get the data DataSet badges = BadgeInfoProvider.GetBadges(where, null); if (!DataHelper.DataSourceIsEmpty(badges)) { // Loop through the individual items foreach (DataRow badgeDr in badges.Tables[0].Rows) { // Create object from DataRow BadgeInfo modifyBadge = new BadgeInfo(badgeDr); // Update the properties modifyBadge.BadgeDisplayName = modifyBadge.BadgeDisplayName.ToUpper(); // Save the changes BadgeInfoProvider.SetBadgeInfo(modifyBadge); } return true; } return false; }
/// <summary> /// OnPrerender check whether. /// </summary> protected override void OnPreRender(EventArgs e) { postTreeElem.Selected = ValidationHelper.GetInteger(hdnSelected.Value, SelectedPost); if ((mSelectedPost == 0) && (RequestHelper.IsAJAXRequest())) { mSelectedPost = postTreeElem.Selected; } if (mSelectedPost > 0) { ForumPostInfo fpi = ForumPostInfoProvider.GetForumPostInfo(mSelectedPost); if ((fpi != null) && (ForumContext.CurrentForum != null) && (fpi.PostForumID == ForumContext.CurrentForum.ForumID)) { plcPostPreview.Visible = true; ltlPostSubject.Text = HTMLHelper.HTMLEncode(fpi.PostSubject); ltlPostText.Text = ResolvePostText(fpi.PostText); ltlSignature.Text = GetSignatureArea(fpi, "<div class=\"SignatureArea\">", "</div>"); ltlPostTime.Text = TimeZoneHelper.ConvertToUserTimeZone(fpi.PostTime, false, MembershipContext.AuthenticatedUser, SiteContext.CurrentSite).ToString(); ltlPostUser.Text = "<span class=\"PostUserName\">" + GetUserName(fpi) + "</span>"; ltlAvatar.Text = AvatarImage(fpi); mUnapproved = !fpi.PostApproved ? " Unapproved" : ""; if (ForumContext.CurrentForum.ForumEnableAdvancedImage) { ltlPostText.AllowedControls = ControlsHelper.ALLOWED_FORUM_CONTROLS; } else { ltlPostText.AllowedControls = "none"; } attachmentDisplayer.ClearData(); attachmentDisplayer.PostID = fpi.PostId; attachmentDisplayer.PostAttachmentCount = fpi.PostAttachmentCount; attachmentDisplayer.ReloadData(); #region "Badge" if (DisplayBadgeInfo) { if (fpi.PostUserID > 0) { UserInfo ui = UserInfoProvider.GetUserInfo(fpi.PostUserID); if ((ui != null) && (!ui.IsPublic())) { BadgeInfo bi = BadgeInfoProvider.GetBadgeInfo(ui.UserSettings.UserBadgeID); if (bi != null) { ltlBadge.Text = "<div class=\"Badge\">" + HTMLHelper.HTMLEncode(bi.BadgeDisplayName) + "</div>"; if (!String.IsNullOrEmpty(bi.BadgeImageURL)) { ltlBadge.Text += "<div class=\"BadgeImage\"><img alt=\"" + HTMLHelper.HTMLEncode(bi.BadgeDisplayName) + "\" src=\"" + HTMLHelper.HTMLEncode(GetImageUrl(bi.BadgeImageURL)) + "\" /></div>"; } } } } // Set public badge if no badge is set if (String.IsNullOrEmpty(ltlBadge.Text)) { ltlBadge.Text = "<div class=\"Badge\">" + GetString("Forums.PublicBadge") + "</div>"; } } #endregion #region "Post actions" // Get the parent thread ID (for reply and quote) int threadId = ForumPostInfoProvider.GetPostRootFromIDPath(fpi.PostIDPath); ltlReply.Text = GetLink(fpi, GetString("Forums_WebInterface_ForumPost.replyLinkText"), "PostActionLink", ForumActionType.Reply, threadId); ltlQuote.Text = GetLink(fpi, GetString("Forums_WebInterface_ForumPost.quoteLinkText"), "PostActionLink", ForumActionType.Quote, threadId); ltlSubscribe.Text = GetLink(fpi, GetString("Forums_WebInterface_ForumPost.Subscribe"), "PostActionLink", ForumActionType.SubscribeToPost, threadId); ltlAnswer.Text = GetLink(fpi, GetString("general.yes"), "ActionLink", ForumActionType.IsAnswer); ltlNotAnswer.Text = GetLink(fpi, GetString("general.no"), "ActionLink", ForumActionType.IsNotAnswer); if (ltlAnswer.Text != String.Empty) { ltlWasHelpful.Text = GetString("Forums_WebInterface_ForumPost.Washelpful") + " "; ltlAnswer.Text += "|"; } ltlAddPostToFavorites.Text = GetLink(fpi, GetString("Forums_WebInterface_ForumPost.AddPostToFavorites"), "ActionLink", ForumActionType.AddPostToFavorites); ltlDelete.Text = GetLink(fpi, GetString("general.delete"), "ActionLink", ForumActionType.Delete); ltlEdit.Text = GetLink(fpi, GetString("general.edit"), "ActionLink", ForumActionType.Edit); ltlAttachments.Text = GetLink(fpi, GetString("general.attachments"), "ActionLink", ForumActionType.Attachment); #endregion #region "Extended actions" if ((EnableFriendship || EnableMessaging) && (fpi.PostUserID > 0)) { GenerateActionScripts = true; ltlActions.Text = "<div class=\"PostExtendedActions\">"; if (EnableMessaging) { ltlActions.Text += "<a class=\"SendMessage\" onclick=\"PrivateMessage(" + fpi.PostUserID + "); return false;\" title=\"" + GetString("sendmessage.sendmessage") + "\" href=\"#\"><span>" + GetString("sendmessage.sendmessage") + "</span></a>"; } if (EnableFriendship) { ltlActions.Text += "<a class=\"Friendship\" onclick=\"FriendshipRequest(" + fpi.PostUserID + "); return false;\" title=\"" + GetString("friends.requestfriendship") + "\" href=\"#\"><span>" + GetString("friends.requestfriendship") + "</span></a>"; } ltlActions.Text += "</div>"; } #endregion // Hide separators if ((ltlReply.Text == "") || (ltlReply.Text != "" && ltlQuote.Text == "")) { plcFirstSeparator.Visible = false; } if ((ltlSubscribe.Text == "") || (ltlSubscribe.Text != "" && ltlQuote.Text == "")) { plcSecondSeparator.Visible = false; } if (ltlReply.Text != "" && ltlSubscribe.Text != "") { plcFirstSeparator.Visible = true; } pnlManage.Visible = (EnableOnSiteManagement && (ForumContext.CurrentForum != null)) ? ForumContext.UserIsModerator(ForumContext.CurrentForum.ForumID, CommunityGroupID) : false; if (pnlManage.Visible) { ltlApprove.Text = GetLink(fpi, GetString("general.approve"), "ActionLink", ForumActionType.Appprove); ltlApproveAll.Text = GetLink(fpi, GetString("forums.approveall"), "ActionLink", ForumActionType.ApproveAll); ltlReject.Text = GetLink(fpi, GetString("general.reject"), "ActionLink", ForumActionType.Reject); ltlRejectAll.Text = GetLink(fpi, GetString("forums.rejectall"), "ActionLink", ForumActionType.RejectAll); ltlSplit.Text = GetLink(fpi, GetString("forums.splitthread"), "ActionLink", ForumActionType.SplitThread); ltlMove.Text = GetLink(fpi, GetString("forums.movethread"), "ActionLink", ForumActionType.MoveToTheOtherForum, threadId); } } } else { plcPostPreview.Visible = false; } if (ControlsHelper.IsInUpdatePanel(this)) { ControlsHelper.GetUpdatePanel(this).Update(); } base.OnPreRender(e); }
protected void Page_Load(object sender, EventArgs e) { if (IsAdHocForum) { plcHeader.Visible = false; } forumEdit.OnPreview += new EventHandler(forumEdit_OnPreview); forumEdit.OnModerationRequired += new EventHandler(forumEdit_OnModerationRequired); // Check whether subscription is for forum or post if (ForumContext.CurrentReplyThread == null) { ltrTitle.Text = GetString("Forums_ForumNewPost_Header.NewThread"); if (ForumContext.CurrentPost != null && ForumContext.CurrentMode == ForumMode.Edit) { ltrTitle.Text = GetString("Forums_ForumNewPost_Header.EditPost"); } } else { plcPreview.Visible = true; ltrTitle.Text = GetString("Forums_ForumNewPost_Header.Reply"); ltrAvatar.Text = AvatarImage(ForumContext.CurrentReplyThread); ltrSubject.Text = HTMLHelper.HTMLEncode(ForumContext.CurrentReplyThread.PostSubject); if (ForumContext.CurrentForum != null) { if (ForumContext.CurrentForum.ForumEnableAdvancedImage) { ltrText.AllowedControls = ControlsHelper.ALLOWED_FORUM_CONTROLS; } else { ltrText.AllowedControls = "none"; } ltrText.Text = ResolvePostText(ForumContext.CurrentReplyThread.PostText); } ltrUserName.Text = HTMLHelper.HTMLEncode(ForumContext.CurrentReplyThread.PostUserName); ltrTime.Text = CMSContext.ConvertDateTime(ForumContext.CurrentReplyThread.PostTime, this).ToString(); UserSettingsInfo usi = UserSettingsInfoProvider.GetUserSettingsInfoByUser(ForumContext.CurrentReplyThread.PostUserID); BadgeInfo bi = null; string badgeName = null; string badgeImageUrl = null; if (usi != null) { bi = BadgeInfoProvider.GetBadgeInfo(usi.UserBadgeID); if (bi != null) { badgeName = HTMLHelper.HTMLEncode(ResHelper.LocalizeString(bi.BadgeDisplayName)); badgeImageUrl = HTMLHelper.HTMLEncode(bi.BadgeImageURL); } } ltrBadge.Text = GetNotEmpty(badgeName, "<div class=\"Badge\">" + badgeName + "</div>", "<div class=\"Badge\">" + GetString("Forums.PublicBadge") + "</div>", ForumActionType.Badge) + GetNotEmpty(badgeImageUrl, "<div class=\"BadgeImage\"><img alt=\"" + badgeName + "\" src=\"" + GetImageUrl(ValidationHelper.GetString(badgeImageUrl, "")) + "\" /></div>", "", ForumActionType.Badge); } }
public static void Parse(ChatMessage newChatMessage) { // Setup local variables char swapChar = (char)0xE000; List <EmoteInfo> parsedEmotes = new List <EmoteInfo>(); List <BadgeInfo> parsedBadges = new List <BadgeInfo>(); StringBuilder emojilessMessageBuilder = new StringBuilder(newChatMessage.displayMsg); // Parse and download any emojis included in the message var matches = EmojiUtilities.GetEmojisInString(newChatMessage.displayMsg); if (matches.Count > 0) { List <string> foundEmojis = new List <string>(); foreach (Match m in matches) { string emojiIndex = EmojiUtilities.WebParseEmojiRegExMatchEvaluator(m); string replaceString = m.Value; // Build up a copy of the message with no emojis so we can parse out our twitch emotes properly emojilessMessageBuilder = emojilessMessageBuilder.Replace(m.Value, " "); if (emojiIndex != String.Empty) { emojiIndex += ".png"; if (!ImageDownloader.CachedTextures.ContainsKey(emojiIndex)) { ImageDownloader.Instance.Queue(new TextureDownloadInfo(emojiIndex, ImageType.Emoji, newChatMessage.origMessage.id)); } if (!foundEmojis.Contains(emojiIndex)) { foundEmojis.Add(emojiIndex); EmoteInfo swapInfo = new EmoteInfo(); swapInfo.imageType = ImageType.Emoji; swapInfo.isEmoji = true; swapInfo.swapChar = swapChar; swapInfo.swapString = replaceString; swapInfo.textureIndex = emojiIndex; parsedEmotes.Add(swapInfo); swapChar++; } } } parsedEmotes = parsedEmotes.OrderByDescending(o => o.swapString.Length).ToList(); Thread.Sleep(5); } bool isActionMessage = false; if (newChatMessage.origMessage is TwitchMessage) { // If this is a twitch message, check if they used /me and color it accordingly isActionMessage = newChatMessage.displayMsg.Substring(1).StartsWith("ACTION") && newChatMessage.displayMsg[0] == (char)0x1; if (isActionMessage) { newChatMessage.displayMsg = newChatMessage.displayMsg.TrimEnd((char)0x1).Substring(8); } // Parse and download any twitch emotes in the message var emotes = _emoteRegex.Matches(newChatMessage.origMessage.Twitch.emotes); if (emotes.Count > 0) { string emojilessMessage = emojilessMessageBuilder.ToString(); foreach (Match e in emotes) { string emoteIndex = $"T{e.Groups["EmoteIndex"].Value}"; if (!ImageDownloader.CachedTextures.ContainsKey(emoteIndex)) { ImageDownloader.Instance.Queue(new TextureDownloadInfo(emoteIndex, ImageType.Twitch, newChatMessage.origMessage.id)); } int startReplace = Convert.ToInt32(e.Groups["StartIndex"].Value); int endReplace = Convert.ToInt32(e.Groups["EndIndex"].Value); EmoteInfo swapInfo = new EmoteInfo(); swapInfo.swapChar = swapChar; swapInfo.swapString = emojilessMessage.Substring(startReplace, endReplace - startReplace + 1); swapInfo.textureIndex = emoteIndex; swapInfo.imageType = ImageType.Twitch; parsedEmotes.Add(swapInfo); swapChar++; } Thread.Sleep(5); } // Parse and download any twitch badges included in the message var badges = _badgeRegex.Matches(newChatMessage.origMessage.user.Twitch.badges); if (badges.Count > 0) { foreach (Match b in badges) { string badgeName = $"{b.Groups["BadgeName"].Value}{b.Groups["BadgeVersion"].Value}"; string badgeIndex = string.Empty; if (ImageDownloader.TwitchBadgeIDs.ContainsKey(badgeName)) { badgeIndex = ImageDownloader.TwitchBadgeIDs[badgeName]; if (!ImageDownloader.CachedTextures.ContainsKey(badgeIndex)) { ImageDownloader.Instance.Queue(new TextureDownloadInfo(badgeIndex, ImageType.Badge, newChatMessage.origMessage.id)); } BadgeInfo swapInfo = new BadgeInfo(); swapInfo.swapChar = swapChar; swapInfo.textureIndex = badgeIndex; swapInfo.imageType = ImageType.Badge; parsedBadges.Add(swapInfo); swapChar++; } } Thread.Sleep(5); } // Parse and download any BTTV/FFZ emotes and cheeremotes in the message string[] msgParts = newChatMessage.displayMsg.Split(' ').Distinct().ToArray(); foreach (string w in msgParts) { string word = w; //Plugin.Log($"WORD: {word}"); string textureIndex = String.Empty; ImageType imageType = ImageType.None; if (ImageDownloader.BTTVEmoteIDs.ContainsKey(word)) { if (ChatConfig.Instance.ShowBTTVEmotes) { textureIndex = $"B{ImageDownloader.BTTVEmoteIDs[word]}"; imageType = ImageType.BTTV; } } else if (ImageDownloader.BTTVAnimatedEmoteIDs.ContainsKey(word)) { if (ChatConfig.Instance.ShowBTTVEmotes) { textureIndex = $"AB{ImageDownloader.BTTVAnimatedEmoteIDs[word]}"; imageType = ImageType.BTTV_Animated; } } else if (ImageDownloader.FFZEmoteIDs.ContainsKey(word)) { if (ChatConfig.Instance.ShowFFZEmotes) { textureIndex = $"F{ImageDownloader.FFZEmoteIDs[word]}"; imageType = ImageType.FFZ; } } else if (newChatMessage.origMessage.Twitch.bits > 0 && EmojiUtilities.cheermoteRegex.IsMatch(word.ToLower())) { Match match = EmojiUtilities.cheermoteRegex.Match(word.ToLower()); string prefix = match.Groups["Prefix"].Value; if (ImageDownloader.TwitchCheermoteIDs.ContainsKey(prefix)) { int bits = Convert.ToInt32(match.Groups["Value"].Value); string tier = ImageDownloader.TwitchCheermoteIDs[prefix].GetTier(bits); textureIndex = $"{prefix}{tier}"; imageType = ImageType.Cheermote; } } if (imageType != ImageType.None) { if (!ImageDownloader.CachedTextures.ContainsKey(textureIndex)) { ImageDownloader.Instance.Queue(new TextureDownloadInfo(textureIndex, imageType, newChatMessage.origMessage.id)); } EmoteInfo swapInfo = new EmoteInfo(); swapInfo.imageType = imageType; swapInfo.swapChar = swapChar; swapInfo.swapString = word; swapInfo.textureIndex = textureIndex; parsedEmotes.Add(swapInfo); swapChar++; } } Thread.Sleep(5); } else if (newChatMessage.origMessage is YouTubeMessage) { if (!ImageDownloader.CachedTextures.ContainsKey(newChatMessage.origMessage.user.YouTube.profileImageUrl)) { ImageDownloader.Instance.Queue(new TextureDownloadInfo(newChatMessage.origMessage.user.YouTube.profileImageUrl, ImageType.YouTube_Profile, newChatMessage.origMessage.id, true)); } BadgeInfo swapInfo = new BadgeInfo(); swapInfo.swapChar = swapChar; swapInfo.textureIndex = newChatMessage.origMessage.user.YouTube.profileImageUrl; swapInfo.imageType = ImageType.YouTube_Profile; parsedBadges.Add(swapInfo); swapChar++; } string[] parts = newChatMessage.displayMsg.Split(' '); // Replace each emote with a unicode character from a private range; we'll draw the emote at the position of this character later on foreach (EmoteInfo e in parsedEmotes.Where(e => !e.isEmoji)) { string extraInfo = String.Empty; if (e.imageType == ImageType.Cheermote) { // Insert an animated cheermote into the message Match cheermote = EmojiUtilities.cheermoteRegex.Match(e.swapString); string numBits = cheermote.Groups["Value"].Value; extraInfo = $"\u200A<color={ImageDownloader.TwitchCheermoteIDs[cheermote.Groups["Prefix"].Value].GetColor(Convert.ToInt32(numBits))}>\u200A<size=3><b>{numBits}</b></size></color>\u200A"; } // Replace any instances of the swapString we find in the message string replaceString = $"\u00A0{Drawing.imageSpacing}{Char.ConvertFromUtf32(e.swapChar)}{extraInfo}"; for (int i = 0; i < parts.Length; i++) { if (parts[i] == e.swapString) { parts[i] = replaceString; } } } // Then replace our emojis after all the emotes are handled, since these aren't sensitive to spacing StringBuilder sb = new StringBuilder(string.Join(" ", parts)); foreach (EmoteInfo e in parsedEmotes.Where(e => e.isEmoji)) { sb.Replace(e.swapString, $"\u00A0{Drawing.imageSpacing}{Char.ConvertFromUtf32(e.swapChar)}"); } newChatMessage.displayMsg = sb.ToString(); Thread.Sleep(5); //// TODO: Re-add tagging, why doesn't unity have highlighting in its default rich text markup? //// Highlight messages that we've been tagged in //if (Plugin._twitchUsername != String.Empty && msg.Contains(Plugin._twitchUsername)) { // msg = $"<mark=#ffff0050>{msg}</mark>"; //} string displayColor = newChatMessage.origMessage.user.color; int nameHash = newChatMessage.origMessage.user.displayName.GetHashCode(); // If the user doesn't already have a displayColor, generate one and store it for later user if (string.IsNullOrEmpty(displayColor) && !_userColors.TryGetValue(nameHash, out displayColor)) { // Generate a random color Random rand = new Random(nameHash); int r = rand.Next(255); int g = rand.Next(255); int b = rand.Next(255); // Convert it to a pastel color System.Drawing.Color pastelColor = Drawing.GetPastelShade(System.Drawing.Color.FromArgb(255, r, g, b)); int argb = ((int)pastelColor.R << 16) + ((int)pastelColor.G << 8) + (int)pastelColor.B; string colorString = String.Format("#{0:X6}", argb) + "FF"; _userColors.Add(nameHash, colorString); displayColor = colorString; } // Set the final displayColor to our message newChatMessage.displayColor = displayColor; // Add the users name to the message with the correct color newChatMessage.displayMsg = $"<color={newChatMessage.displayColor}><b>{newChatMessage.origMessage.user.displayName}</b></color>{(isActionMessage ? String.Empty : ":")} {newChatMessage.displayMsg}"; // Prepend the users badges to the front of the message StringBuilder badgeStr = new StringBuilder(); if (parsedBadges.Count > 0) { parsedBadges.Reverse(); for (int i = 0; i < parsedBadges.Count; i++) { badgeStr.Insert(0, $"\u200A{Drawing.imageSpacing}{Char.ConvertFromUtf32(parsedBadges[i].swapChar)}\u2004"); } } badgeStr.Append("\u200A"); badgeStr.Append(newChatMessage.displayMsg); // Finally, store our final message, parsedEmotes and parsedBadges; then render the message newChatMessage.displayMsg = badgeStr.ToString(); newChatMessage.parsedEmotes = parsedEmotes; newChatMessage.parsedBadges = parsedBadges; newChatMessage.isActionMessage = isActionMessage; ChatHandler.RenderQueue.Enqueue(newChatMessage); }
//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; case "admin": IsStaff = true; break; case "staff": IsStaff = true; break; case "partner": IsPartner = 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.ReplyParentDisplayName: if (ChatReply == null) { ChatReply = new ChatReply(); } // ChatReply is null if not reply ChatReply.ParentDisplayName = tagValue; break; case Tags.ReplyParentMsgBody: if (ChatReply == null) { ChatReply = new ChatReply(); } // ChatReply is null if not reply ChatReply.ParentMsgBody = tagValue; break; case Tags.ReplyParentMsgId: if (ChatReply == null) { ChatReply = new ChatReply(); } // ChatReply is null if not reply ChatReply.ParentMsgId = tagValue; break; case Tags.ReplyParentUserId: if (ChatReply == null) { ChatReply = new ChatReply(); } // ChatReply is null if not reply ChatReply.ParentUserId = tagValue; break; case Tags.ReplyParentUserLogin: if (ChatReply == null) { ChatReply = new ChatReply(); } // ChatReply is null if not reply ChatReply.ParentUserLogin = tagValue; 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; IsStaff = true; break; case "staff": UserType = UserType.Staff; IsStaff = true; 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; } } }