// ReSharper disable once ReturnTypeCanBeEnumerable.Global public static EmojiRenderResult[] RenderEmojiAsStringList(EmojiPackType pack, IList <long> activeEmoji) { var result = new List <EmojiRenderResult>(); var dictionary = emojiList[pack]; for (int i = 0; i < activeEmoji.Count; i++) { bool u = false; int max = Math.Min(i + 3, activeEmoji.Count - 1); int j = max; for (; j >= i; j--) { var a = new List <long>(); for (int n = i; n <= j; n++) { a.Add(activeEmoji[n]); } var emojiString = GetStringForCodes(a); if (dictionary.Contains(emojiString)) { u = true; result.Add(new EmojiRenderResult() { emojiCode = emojiString }); break; } } if (u) { // Такой сиквенс, который начинается на activeEmoji[i] есть в словаре i = j; } else { // Такого сиквенса не существует result.Add(new EmojiRenderResult() { isSuccess = false, rawText = Utf8ToUnicode.UnicodeCodeToString(activeEmoji[i]) }); } } return(result.ToArray()); }
private static string AddMessageReactionHTMLWithEmojiPack( NKDiscordChatWidget.DiscordBot.Classes.EventMessageCreate.EventMessageCreate_Reaction reaction, EmojiPackType emojiPack ) { var longs = Utf8ToUnicode.ToUnicodeCode(reaction.emoji.name); var u = longs.Any(code => !UnicodeEmojiEngine.IsInIntervalEmoji(code, emojiPack)); if (u) { // Реакция без ID, но при этом не является эмодзи, рисуем как есть return(HttpUtility.HtmlEncode(reaction.emoji.name)); } // Реакция без ID и является эмодзи, поэтому рисуем как картинку var localEmojiList = UnicodeEmojiEngine.RenderEmojiAsStringList( emojiPack, longs); var emojiHtml = ""; // ReSharper disable once LoopCanBeConvertedToQuery foreach (var item in localEmojiList) { if (!item.isSuccess) { // Этого символа нет в паке, выводим как есть. Куда деваться emojiHtml += HttpUtility.HtmlEncode(item.rawText); continue; } // hint: localEmojiList.Count может быть больше 1 в случае сложных эмодзи типа :one: var emojiSubFolderName = UnicodeEmojiEngine.GetImageSubFolder(emojiPack); var emojiExtension = UnicodeEmojiEngine.GetImageExtension(emojiPack); var url = string.Format("/images/emoji/{0}/{1}.{2}", emojiSubFolderName, item.emojiCode, emojiExtension ); emojiHtml += string.Format("<img src='{0}' alt=':{1}:'>", HttpUtility.HtmlEncode(url), HttpUtility.HtmlEncode(reaction.emoji.name) ); } return(emojiHtml); }
private static string DrawMessageContent(EventMessageCreate message, ChatDrawOption chatOption) { var usedEmbedsUrls = new HashSet <string>(); foreach (var embed in message.embeds) { usedEmbedsUrls.Add(embed.url); } var guildID = message.guild_id; var guild = NKDiscordChatWidget.DiscordBot.Bot.guilds[guildID]; var thisGuildEmojis = new HashSet <string>(guild.emojis.Select(emoji => emoji.id).ToList()); // Основной текст string directContentHTML = NKDiscordChatWidget.General.MessageMarkdownParser.RenderMarkdownAsHTML( message.content, chatOption, message.mentions, guildID, usedEmbedsUrls); bool containOnlyUnicodeAndSpace; { var rEmojiWithinText = new Regex(@"<\:(.+?)\:([0-9]+)>", RegexOptions.Compiled); long[] longs = { }; if (message.content != null) { longs = Utf8ToUnicode.ToUnicodeCode(rEmojiWithinText.Replace(message.content, "")); } containOnlyUnicodeAndSpace = Utf8ToUnicode.ContainOnlyUnicodeAndSpace(longs); } string html = string.Format("<div class='content-direct {1}'>{0}</div>", directContentHTML, containOnlyUnicodeAndSpace ? "only-emoji" : ""); // attachments if ((message.attachments != null) && message.attachments.Any() && (chatOption.attachments != 2)) { string attachmentHTML = ""; foreach (var attachment in message.attachments) { var extension = attachment.filename.Split('.').Last().ToLowerInvariant(); // ReSharper disable once SwitchStatementMissingSomeCases switch (extension) { case "mp4": case "webm": // TODO: Отображать размер видео attachmentHTML += string.Format( "<div class='attachment {1}'><div class='attachment-wrapper'><video><source src='{0}'></video></div></div>", HttpUtility.HtmlEncode(attachment.proxy_url), ((chatOption.attachments == 1) || attachment.IsSpoiler) ? "blur" : "" ); break; case "jpeg": case "jpg": case "bmp": case "gif": case "png": attachmentHTML += string.Format( "<div class='attachment {3}'><div class='attachment-wrapper'><img src='{0}' data-width='{1}' data-height='{2}'></div></div>", HttpUtility.HtmlEncode(attachment.proxy_url), attachment.width, attachment.height, ((chatOption.attachments == 1) || attachment.IsSpoiler) ? "blur" : "" ); break; } } html += string.Format("<div class='attachment-block'>{0}</div>", attachmentHTML); } // Preview if ((message.embeds != null) && message.embeds.Any() && (chatOption.link_preview != 2)) { string previewHTML = ""; foreach (var embed in message.embeds) { var subHTML = ""; if (embed.provider != null) { subHTML += string.Format("<div class='provider'>{0}</div>", HttpUtility.HtmlEncode(embed.provider.name)); } if (embed.author != null) { subHTML += string.Format("<div class='author'>{0}</div>", HttpUtility.HtmlEncode(embed.author.name)); } subHTML += string.Format("<div class='title'>{0}</div>", HttpUtility.HtmlEncode(embed.title)); if (embed.thumbnail != null) { subHTML += string.Format("<div class='preview'><img src='{0}' alt='{1}'></div>", HttpUtility.HtmlEncode(embed.thumbnail.proxy_url), HttpUtility.HtmlEncode("Превью для «" + embed.title + "»") ); } var nickColor = embed.color.ToString("X"); nickColor = "#" + nickColor.PadLeft(6, '0'); previewHTML += string.Format( "<div class='embed {2}'><div class='embed-pill' style='background-color: {1};'></div>" + "<div class='embed-content {3}'>{0}</div></div>", subHTML, nickColor, (chatOption.link_preview == 1) ? "blur" : "", string.IsNullOrEmpty(embed.title) ? "embed-content_no-title" : "" ); } html += string.Format("<div class='embed-block'>{0}</div>", previewHTML); } // Реакции if ( (message.reactions != null) && message.reactions.Any() && ((chatOption.message_relative_reaction != 2) || (chatOption.message_stranger_reaction != 2)) ) { // Реакции var reactionHTMLs = new List <string>(); foreach (var reaction in message.reactions) { bool isRelative = ((reaction.emoji.id == null) || thisGuildEmojis.Contains(reaction.emoji.id)); int emojiShow = isRelative ? chatOption.message_relative_reaction : chatOption.message_stranger_reaction; if (emojiShow == 2) // @todo убрать магическую константу { continue; } AddMessageReactionHTML( reactionHTMLs, reaction, emojiShow, chatOption ); } var s = reactionHTMLs.Aggregate("", (current, s1) => current + s1); html += string.Format("<div class='content-reaction'>{0}</div>", s); } return(html); }
/// <summary> /// Парсинг эмодзи из дополнительных plain'ов в Unicode /// </summary> /// <param name="text">Текст с сырым Markdown</param> /// <param name="chatOption">Опции чата, заданные стримером для виджета</param> /// <param name="waitDictionary">Dictionary для саб-блоков</param> /// <returns></returns> public static string MarkEmojiUnicode( string text, ChatDrawOption chatOption, Dictionary <string, string> waitDictionary ) { if (!UnicodeEmojiEngine.emojiList[chatOption.unicode_emoji_displaying].Any()) { return(text); } var activeEmoji = new List <long>(); var longs = Utf8ToUnicode.ToUnicodeCode(text); var textAfter = ""; var containEmoji = false; foreach (var code in longs) { if (!UnicodeEmojiEngine.IsInIntervalEmoji(code, chatOption.unicode_emoji_displaying)) { // Этот символ НЕ является unicode emoji if (activeEmoji.Any()) { // У нас непустой буффер emoji символов, надо их записать в строку var localEmojiList = UnicodeEmojiEngine.RenderEmojiAsStringList( chatOption.unicode_emoji_displaying, activeEmoji); textAfter += RenderEmojiStringListAsHtml( localEmojiList, chatOption.unicode_emoji_displaying, waitDictionary, chatOption.emoji_relative ); activeEmoji = new List <long>(); } textAfter += Utf8ToUnicode.UnicodeCodeToString(code); continue; } // Этот символ ЯВЛЯЕТСЯ unicode emoji containEmoji = true; activeEmoji.Add(code); } // foreach if (activeEmoji.Any()) { // У нас не пустой буффер emoji символов, надо их записать в строку var localEmojiList = UnicodeEmojiEngine.RenderEmojiAsStringList( chatOption.unicode_emoji_displaying, activeEmoji); textAfter += RenderEmojiStringListAsHtml( localEmojiList, chatOption.unicode_emoji_displaying, waitDictionary, chatOption.emoji_relative ); } if (containEmoji) { text = textAfter; } return(text); }