From 0064df8ae46cf45aa41fd6417d468931762b08bd Mon Sep 17 00:00:00 2001 From: Kwoth Date: Sun, 11 Jul 2021 23:37:19 +0200 Subject: [PATCH] - .say now uses new SmartText instead of CREmbed - Added IMessageChannel extensions for sending smarttext - Added implicit operator from string to smarttext (which just creates smartplaintext instance) --- src/NadekoBot/Common/Replacements/Replacer.cs | 52 +++++++++++++++++++ src/NadekoBot/Common/SmartText/SmartText.cs | 6 ++- .../Common/TypeReaders/KwumTypeReader.cs | 8 +++ src/NadekoBot/Modules/Utility/Utility.cs | 25 +++------ src/NadekoBot/_Extensions/Extensions.cs | 17 ++++++ 5 files changed, 87 insertions(+), 21 deletions(-) diff --git a/src/NadekoBot/Common/Replacements/Replacer.cs b/src/NadekoBot/Common/Replacements/Replacer.cs index 414b0c7f8..7b8778769 100644 --- a/src/NadekoBot/Common/Replacements/Replacer.cs +++ b/src/NadekoBot/Common/Replacements/Replacer.cs @@ -34,6 +34,58 @@ namespace NadekoBot.Common.Replacements return input; } + public SmartText Replace(SmartText data) + => data switch + { + SmartEmbedText embedData => Replace(embedData), + SmartPlainText plain => Replace(plain), + _ => throw new ArgumentOutOfRangeException(nameof(data), "Unsupported argument type") + }; + + public SmartPlainText Replace(SmartPlainText plainText) + => Replace(plainText.Text); + + public SmartEmbedText Replace(SmartEmbedText embedData) + { + var newEmbedData = new SmartEmbedText(); + newEmbedData.PlainText = Replace(embedData.PlainText); + newEmbedData.Description = Replace(embedData.Description); + newEmbedData.Title = Replace(embedData.Title); + newEmbedData.Thumbnail = Replace(embedData.Thumbnail); + newEmbedData.Image = Replace(embedData.Image); + if (embedData.Author != null) + { + newEmbedData.Author = new SmartTextEmbedAuthor(); + newEmbedData.Author.Name = Replace(embedData.Author.Name); + newEmbedData.Author.IconUrl = Replace(embedData.Author.IconUrl); + } + + if (embedData.Fields != null) + { + var fields = new List(); + foreach (var f in embedData.Fields) + { + var newF = new SmartTextEmbedField(); + newF.Name = Replace(f.Name); + newF.Value = Replace(f.Value); + fields.Add(newF); + } + + newEmbedData.Fields = fields.ToArray(); + } + + if (embedData.Footer != null) + { + newEmbedData.Footer = new SmartTextEmbedFooter(); + newEmbedData.Footer.Text = Replace(embedData.Footer.Text); + newEmbedData.Footer.IconUrl = Replace(embedData.Footer.IconUrl); + } + + newEmbedData.Color = embedData.Color; + + return newEmbedData; + } + public CREmbed Replace(CREmbed embedData) { embedData.PlainText = Replace(embedData.PlainText); diff --git a/src/NadekoBot/Common/SmartText/SmartText.cs b/src/NadekoBot/Common/SmartText/SmartText.cs index 70ffe1123..4a747d40f 100644 --- a/src/NadekoBot/Common/SmartText/SmartText.cs +++ b/src/NadekoBot/Common/SmartText/SmartText.cs @@ -2,15 +2,17 @@ namespace NadekoBot { - // todo 3.3 check if saving embeds in db has IsEmbed field, to prevent rechecking and generating exceptions on every use public abstract class SmartText { public bool IsEmbed => this is SmartEmbedText; public bool IsPlainText => this is SmartPlainText; + public static implicit operator SmartText(string input) + => new SmartPlainText(input); + public static SmartText CreateFrom(string input) { - if (string.IsNullOrWhiteSpace(input) || !input.Trim().StartsWith("{")) + if (string.IsNullOrWhiteSpace(input) || !input.TrimStart().StartsWith("{")) { return new SmartPlainText(input); } diff --git a/src/NadekoBot/Common/TypeReaders/KwumTypeReader.cs b/src/NadekoBot/Common/TypeReaders/KwumTypeReader.cs index 4d0485035..2a6bde307 100644 --- a/src/NadekoBot/Common/TypeReaders/KwumTypeReader.cs +++ b/src/NadekoBot/Common/TypeReaders/KwumTypeReader.cs @@ -13,4 +13,12 @@ namespace NadekoBot.Common.TypeReaders return Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, "Input is not a valid kwum")); } } + + public sealed class SmartTextTypeReader : NadekoTypeReader + { + public override Task ReadAsync(ICommandContext ctx, string input) + { + return Task.FromResult(TypeReaderResult.FromSuccess(SmartText.CreateFrom(input))); + } + } } \ No newline at end of file diff --git a/src/NadekoBot/Modules/Utility/Utility.cs b/src/NadekoBot/Modules/Utility/Utility.cs index 9e61cabef..c797a2021 100644 --- a/src/NadekoBot/Modules/Utility/Utility.cs +++ b/src/NadekoBot/Modules/Utility/Utility.cs @@ -41,36 +41,23 @@ namespace NadekoBot.Modules.Utility [RequireContext(ContextType.Guild)] [UserPerm(GuildPerm.ManageMessages)] [Priority(1)] - public async Task Say(ITextChannel channel, [Leftover] string message) + public async Task Say(ITextChannel channel, [Leftover] SmartText message) { - if (string.IsNullOrWhiteSpace(message)) - return; - var rep = new ReplacementBuilder() .WithDefault(ctx.User, channel, (SocketGuild)ctx.Guild, (DiscordSocketClient)ctx.Client) .Build(); - if (CREmbed.TryParse(message, out var embedData)) - { - rep.Replace(embedData); - await channel.EmbedAsync(embedData, _eb, sanitizeAll: !((IGuildUser)Context.User).GuildPermissions.MentionEveryone).ConfigureAwait(false); - } - else - { - var msg = rep.Replace(message); - if (!string.IsNullOrWhiteSpace(msg)) - { - await channel.SendConfirmAsync(_eb, msg).ConfigureAwait(false); - } - } + rep.Replace(message); + + await channel.SendAsync(_eb, message, !((IGuildUser)Context.User).GuildPermissions.MentionEveryone); } [NadekoCommand, Aliases] [RequireContext(ContextType.Guild)] [UserPerm(GuildPerm.ManageMessages)] [Priority(0)] - public Task Say([Leftover] string message) => - Say((ITextChannel)ctx.Channel, message); + public Task Say([Leftover] string message) + => Say((ITextChannel)ctx.Channel, message); [NadekoCommand, Aliases] [RequireContext(ContextType.Guild)] diff --git a/src/NadekoBot/_Extensions/Extensions.cs b/src/NadekoBot/_Extensions/Extensions.cs index 25c63330d..7819d78f4 100644 --- a/src/NadekoBot/_Extensions/Extensions.cs +++ b/src/NadekoBot/_Extensions/Extensions.cs @@ -35,6 +35,23 @@ namespace NadekoBot.Extensions public static TOut[] Map(this TIn[] arr, Func f) => Array.ConvertAll(arr, x => f(x)); + public static Task SendAsync(this IMessageChannel channel, string plainText, Embed embed, bool sanitizeAll = false) + { + plainText = sanitizeAll + ? plainText?.SanitizeAllMentions() ?? "" + : plainText?.SanitizeMentions() ?? ""; + + return channel.SendMessageAsync(plainText, embed: embed); + } + + public static Task SendAsync(this IMessageChannel channel, IEmbedBuilderService eb, SmartText text, bool sanitizeAll = false) + => text switch + { + SmartEmbedText set => channel.SendAsync(set.PlainText, set.GetEmbed(eb).Build(), sanitizeAll), + SmartPlainText st => channel.SendAsync(st.Text, null, sanitizeAll), + _ => throw new ArgumentOutOfRangeException(nameof(text)) + }; + public static Task EmbedAsync(this IMessageChannel channel, CREmbed crEmbed, IEmbedBuilderService eb, bool sanitizeAll = false) { var plainText = sanitizeAll