mirror of
				https://gitlab.com/Kwoth/nadekobot.git
				synced 2025-11-03 16:24:27 -05:00 
			
		
		
		
	- Removed some duplicated code from custom reactions
- CREmbed completely removed and replaced by SmartText
This commit is contained in:
		@@ -1,125 +0,0 @@
 | 
				
			|||||||
using Discord;
 | 
					 | 
				
			||||||
using NadekoBot.Extensions;
 | 
					 | 
				
			||||||
using Newtonsoft.Json;
 | 
					 | 
				
			||||||
using System;
 | 
					 | 
				
			||||||
using NadekoBot.Services;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace NadekoBot.Common
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    public class CREmbed
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        public CREmbedAuthor Author { get; set; }
 | 
					 | 
				
			||||||
        public string PlainText { get; set; }
 | 
					 | 
				
			||||||
        public string Title { get; set; }
 | 
					 | 
				
			||||||
        public string Description { get; set; }
 | 
					 | 
				
			||||||
        public string Url { get; set; }
 | 
					 | 
				
			||||||
        public CREmbedFooter Footer { get; set; }
 | 
					 | 
				
			||||||
        public string Thumbnail { get; set; }
 | 
					 | 
				
			||||||
        public string Image { get; set; }
 | 
					 | 
				
			||||||
        public CREmbedField[] Fields { get; set; }
 | 
					 | 
				
			||||||
        public uint Color { get; set; } = 7458112;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public bool IsValid =>
 | 
					 | 
				
			||||||
            IsEmbedValid || !string.IsNullOrWhiteSpace(PlainText);
 | 
					 | 
				
			||||||
        public bool IsEmbedValid =>
 | 
					 | 
				
			||||||
            !string.IsNullOrWhiteSpace(Title) ||
 | 
					 | 
				
			||||||
            !string.IsNullOrWhiteSpace(Description) ||
 | 
					 | 
				
			||||||
            !string.IsNullOrWhiteSpace(Url) ||
 | 
					 | 
				
			||||||
            !string.IsNullOrWhiteSpace(Thumbnail) ||
 | 
					 | 
				
			||||||
            !string.IsNullOrWhiteSpace(Image) ||
 | 
					 | 
				
			||||||
            (Footer != null && (!string.IsNullOrWhiteSpace(Footer.Text) || !string.IsNullOrWhiteSpace(Footer.IconUrl))) ||
 | 
					 | 
				
			||||||
            (Fields != null && Fields.Length > 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public IEmbedBuilder ToEmbed(IEmbedBuilderService eb)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            var embed = new EmbedBuilder();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (!string.IsNullOrWhiteSpace(Title))
 | 
					 | 
				
			||||||
                embed.WithTitle(Title);
 | 
					 | 
				
			||||||
            if (!string.IsNullOrWhiteSpace(Description))
 | 
					 | 
				
			||||||
                embed.WithDescription(Description);
 | 
					 | 
				
			||||||
            if (Url != null && Uri.IsWellFormedUriString(Url, UriKind.Absolute))
 | 
					 | 
				
			||||||
                embed.WithUrl(Url);
 | 
					 | 
				
			||||||
            embed.WithColor(new Discord.Color(Color));
 | 
					 | 
				
			||||||
            if (Footer != null)
 | 
					 | 
				
			||||||
                embed.WithFooter(Footer.Text,
 | 
					 | 
				
			||||||
                    Uri.IsWellFormedUriString(Footer.IconUrl, UriKind.Absolute)
 | 
					 | 
				
			||||||
                        ? Footer.IconUrl
 | 
					 | 
				
			||||||
                        : null);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (Thumbnail != null && Uri.IsWellFormedUriString(Thumbnail, UriKind.Absolute))
 | 
					 | 
				
			||||||
                embed.WithThumbnailUrl(Thumbnail);
 | 
					 | 
				
			||||||
            if (Image != null && Uri.IsWellFormedUriString(Image, UriKind.Absolute))
 | 
					 | 
				
			||||||
                embed.WithImageUrl(Image);
 | 
					 | 
				
			||||||
            if (Author != null && !string.IsNullOrWhiteSpace(Author.Name))
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                if (!Uri.IsWellFormedUriString(Author.IconUrl, UriKind.Absolute))
 | 
					 | 
				
			||||||
                    Author.IconUrl = null;
 | 
					 | 
				
			||||||
                if (!Uri.IsWellFormedUriString(Author.Url, UriKind.Absolute))
 | 
					 | 
				
			||||||
                    Author.Url = null;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                embed.WithAuthor(Author.Name, Author.IconUrl, Author.Url);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (Fields != null)
 | 
					 | 
				
			||||||
                foreach (var f in Fields)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    if (!string.IsNullOrWhiteSpace(f.Name) && !string.IsNullOrWhiteSpace(f.Value))
 | 
					 | 
				
			||||||
                        embed.AddField(f.Name, f.Value, f.Inline);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            return eb.Create(embed);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public static bool TryParse(string input, out CREmbed embed)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            embed = null;
 | 
					 | 
				
			||||||
            if (string.IsNullOrWhiteSpace(input) || !input.Trim().StartsWith('{'))
 | 
					 | 
				
			||||||
                return false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            try
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                var crembed = JsonConvert.DeserializeObject<CREmbed>(input);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if (crembed.Fields != null && crembed.Fields.Length > 0)
 | 
					 | 
				
			||||||
                    foreach (var f in crembed.Fields)
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        f.Name = f.Name.TrimTo(256);
 | 
					 | 
				
			||||||
                        f.Value = f.Value.TrimTo(1024);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                if (!crembed.IsValid)
 | 
					 | 
				
			||||||
                    return false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                embed = crembed;
 | 
					 | 
				
			||||||
                return true;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            catch
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                return false;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public class CREmbedField
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        public string Name { get; set; }
 | 
					 | 
				
			||||||
        public string Value { get; set; }
 | 
					 | 
				
			||||||
        public bool Inline { get; set; }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public class CREmbedFooter
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        public string Text { get; set; }
 | 
					 | 
				
			||||||
        public string IconUrl { get; set; }
 | 
					 | 
				
			||||||
        [JsonProperty("icon_url")]
 | 
					 | 
				
			||||||
        private string Icon_Url { set => IconUrl = value; }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    public class CREmbedAuthor
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        public string Name { get; set; }
 | 
					 | 
				
			||||||
        public string IconUrl { get; set; }
 | 
					 | 
				
			||||||
        [JsonProperty("icon_url")]
 | 
					 | 
				
			||||||
        private string Icon_Url { set => IconUrl = value; }
 | 
					 | 
				
			||||||
        public string Url { get; set; }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -85,34 +85,5 @@ namespace NadekoBot.Common.Replacements
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            return newEmbedData;
 | 
					            return newEmbedData;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					 | 
				
			||||||
        public CREmbed Replace(CREmbed embedData)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            embedData.PlainText = Replace(embedData.PlainText);
 | 
					 | 
				
			||||||
            embedData.Description = Replace(embedData.Description);
 | 
					 | 
				
			||||||
            embedData.Title = Replace(embedData.Title);
 | 
					 | 
				
			||||||
            embedData.Thumbnail = Replace(embedData.Thumbnail);
 | 
					 | 
				
			||||||
            embedData.Image = Replace(embedData.Image);
 | 
					 | 
				
			||||||
            if (embedData.Author != null)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                embedData.Author.Name = Replace(embedData.Author.Name);
 | 
					 | 
				
			||||||
                embedData.Author.IconUrl = Replace(embedData.Author.IconUrl);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (embedData.Fields != null)
 | 
					 | 
				
			||||||
                foreach (var f in embedData.Fields)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    f.Name = Replace(f.Name);
 | 
					 | 
				
			||||||
                    f.Value = Replace(f.Value);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (embedData.Footer != null)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                embedData.Footer.Text = Replace(embedData.Footer.Text);
 | 
					 | 
				
			||||||
                embedData.Footer.IconUrl = Replace(embedData.Footer.IconUrl);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            return embedData;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,110 +1,27 @@
 | 
				
			|||||||
using AngleSharp;
 | 
					using Discord;
 | 
				
			||||||
using AngleSharp.Html.Dom;
 | 
					 | 
				
			||||||
using Discord;
 | 
					 | 
				
			||||||
using Discord.WebSocket;
 | 
					using Discord.WebSocket;
 | 
				
			||||||
using NadekoBot.Common;
 | 
					 | 
				
			||||||
using NadekoBot.Common.Replacements;
 | 
					using NadekoBot.Common.Replacements;
 | 
				
			||||||
using NadekoBot.Services.Database.Models;
 | 
					using NadekoBot.Services.Database.Models;
 | 
				
			||||||
using NadekoBot.Extensions;
 | 
					using NadekoBot.Extensions;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					 | 
				
			||||||
using System.Linq;
 | 
					 | 
				
			||||||
using System.Runtime.CompilerServices;
 | 
					using System.Runtime.CompilerServices;
 | 
				
			||||||
using System.Text.RegularExpressions;
 | 
					 | 
				
			||||||
using System.Threading.Tasks;
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
using NadekoBot.Services;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace NadekoBot.Modules.CustomReactions.Extensions
 | 
					namespace NadekoBot.Modules.CustomReactions.Extensions
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public static class CustomReactionExtensions
 | 
					    public static class CustomReactionExtensions
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        private static readonly Regex imgRegex = new Regex("%(img|image):(?<tag>.*?)%", RegexOptions.Compiled);
 | 
					        private static string ResolveTriggerString(this string str, DiscordSocketClient client)
 | 
				
			||||||
 | 
					 | 
				
			||||||
        private static Dictionary<Regex, Func<Match, Task<string>>> regexPlaceholders { get; } =
 | 
					 | 
				
			||||||
            new Dictionary<Regex, Func<Match, Task<string>>>()
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    imgRegex, async (match) =>
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        var tag = match.Groups["tag"].ToString();
 | 
					 | 
				
			||||||
                        if (string.IsNullOrWhiteSpace(tag))
 | 
					 | 
				
			||||||
                            return "";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                        var fullQueryLink = $"http://imgur.com/search?q={tag}";
 | 
					 | 
				
			||||||
                        var config = Configuration.Default.WithDefaultLoader();
 | 
					 | 
				
			||||||
                        using (var document = await BrowsingContext.New(config).OpenAsync(fullQueryLink)
 | 
					 | 
				
			||||||
                            .ConfigureAwait(false))
 | 
					 | 
				
			||||||
                        {
 | 
					 | 
				
			||||||
                            var elems = document.QuerySelectorAll("a.image-list-link").ToArray();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                            if (!elems.Any())
 | 
					 | 
				
			||||||
                                return "";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                            var img = (elems.ElementAtOrDefault(new NadekoRandom().Next(0, elems.Length))?.Children
 | 
					 | 
				
			||||||
                                ?.FirstOrDefault() as IHtmlImageElement);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                            if (img?.Source is null)
 | 
					 | 
				
			||||||
                                return "";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                            return " " + img.Source.Replace("b.", ".", StringComparison.InvariantCulture) + " ";
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        private static string ResolveTriggerString(this string str, IUserMessage ctx, DiscordSocketClient client)
 | 
					 | 
				
			||||||
            => str.Replace("%bot.mention%", client.CurrentUser.Mention, StringComparison.Ordinal);
 | 
					            => str.Replace("%bot.mention%", client.CurrentUser.Mention, StringComparison.Ordinal);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private static async Task<string> ResolveResponseStringAsync(this string str, IUserMessage ctx,
 | 
					 | 
				
			||||||
            DiscordSocketClient client, string resolvedTrigger, bool containsAnywhere)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            var substringIndex = resolvedTrigger.Length;
 | 
					 | 
				
			||||||
            if (containsAnywhere)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                var pos = ctx.Content.AsSpan().GetWordPosition(resolvedTrigger);
 | 
					 | 
				
			||||||
                if (pos == WordPosition.Start)
 | 
					 | 
				
			||||||
                    substringIndex += 1;
 | 
					 | 
				
			||||||
                else if (pos == WordPosition.End)
 | 
					 | 
				
			||||||
                    substringIndex = ctx.Content.Length;
 | 
					 | 
				
			||||||
                else if (pos == WordPosition.Middle)
 | 
					 | 
				
			||||||
                    substringIndex += ctx.Content.IndexOf(resolvedTrigger, StringComparison.InvariantCulture);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            var canMentionEveryone = (ctx.Author as IGuildUser)?.GuildPermissions.MentionEveryone ?? true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            var rep = new ReplacementBuilder()
 | 
					 | 
				
			||||||
                .WithDefault(ctx.Author, ctx.Channel, (ctx.Channel as ITextChannel)?.Guild as SocketGuild, client)
 | 
					 | 
				
			||||||
                .WithOverride("%target%", () =>
 | 
					 | 
				
			||||||
                    canMentionEveryone
 | 
					 | 
				
			||||||
                        ? ctx.Content.Substring(substringIndex).Trim()
 | 
					 | 
				
			||||||
                        : ctx.Content.Substring(substringIndex).Trim().SanitizeMentions(true))
 | 
					 | 
				
			||||||
                .Build();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            str = rep.Replace(str);
 | 
					 | 
				
			||||||
#if !GLOBAL_NADEKO
 | 
					 | 
				
			||||||
            foreach (var ph in regexPlaceholders)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                str = await ph.Key.ReplaceAsync(str, ph.Value).ConfigureAwait(false);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
            return str;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public static Task<string> ResponseWithContextAsync(this CustomReaction cr, IUserMessage ctx,
 | 
					 | 
				
			||||||
            DiscordSocketClient client, bool containsAnywhere)
 | 
					 | 
				
			||||||
            => cr.Response.ResolveResponseStringAsync(ctx, client, cr.Trigger.ResolveTriggerString(ctx, client),
 | 
					 | 
				
			||||||
                containsAnywhere);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public static async Task<IUserMessage> Send(this CustomReaction cr, IUserMessage ctx,
 | 
					        public static async Task<IUserMessage> Send(this CustomReaction cr, IUserMessage ctx,
 | 
				
			||||||
            DiscordSocketClient client, IEmbedBuilderService eb, bool sanitize)
 | 
					            DiscordSocketClient client, bool sanitize)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var channel = cr.DmResponse
 | 
					            var channel = cr.DmResponse
 | 
				
			||||||
                ? await ctx.Author.GetOrCreateDMChannelAsync().ConfigureAwait(false)
 | 
					                ? await ctx.Author.GetOrCreateDMChannelAsync().ConfigureAwait(false)
 | 
				
			||||||
                : ctx.Channel;
 | 
					                : ctx.Channel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (CREmbed.TryParse(cr.Response, out CREmbed crembed))
 | 
					            var trigger = cr.Trigger.ResolveTriggerString(client);
 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                var trigger = cr.Trigger.ResolveTriggerString(ctx, client);
 | 
					 | 
				
			||||||
            var substringIndex = trigger.Length;
 | 
					            var substringIndex = trigger.Length;
 | 
				
			||||||
            if (cr.ContainsAnywhere)
 | 
					            if (cr.ContainsAnywhere)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
@@ -126,15 +43,10 @@ namespace NadekoBot.Modules.CustomReactions.Extensions
 | 
				
			|||||||
                    : ctx.Content.Substring(substringIndex).Trim().SanitizeMentions(true))
 | 
					                    : ctx.Content.Substring(substringIndex).Trim().SanitizeMentions(true))
 | 
				
			||||||
                .Build();
 | 
					                .Build();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                rep.Replace(crembed);
 | 
					            var text = SmartText.CreateFrom(cr.Response);
 | 
				
			||||||
 | 
					            text = rep.Replace(text);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                return await channel.EmbedAsync(crembed, eb, sanitize).ConfigureAwait(false);
 | 
					            return await channel.SendAsync(text, sanitize);
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            return await channel
 | 
					 | 
				
			||||||
                .SendMessageAsync(
 | 
					 | 
				
			||||||
                    (await cr.ResponseWithContextAsync(ctx, client, cr.ContainsAnywhere).ConfigureAwait(false))
 | 
					 | 
				
			||||||
                    .SanitizeMentions(sanitize)).ConfigureAwait(false);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 | 
					        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -429,7 +429,7 @@ namespace NadekoBot.Modules.CustomReactions.Services
 | 
				
			|||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var sentMsg = await cr.Send(msg, _client, _eb, false).ConfigureAwait(false);
 | 
					                var sentMsg = await cr.Send(msg, _client, false).ConfigureAwait(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var reactions = cr.GetReactions();
 | 
					                var reactions = cr.GetReactions();
 | 
				
			||||||
                foreach (var reaction in reactions)
 | 
					                foreach (var reaction in reactions)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -68,17 +68,6 @@ namespace NadekoBot.Extensions
 | 
				
			|||||||
                _ => throw new ArgumentOutOfRangeException(nameof(text))
 | 
					                _ => throw new ArgumentOutOfRangeException(nameof(text))
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public static Task<IUserMessage> EmbedAsync(this IMessageChannel channel, CREmbed crEmbed, IEmbedBuilderService eb, bool sanitizeAll = false)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            var plainText = sanitizeAll
 | 
					 | 
				
			||||||
                ? crEmbed.PlainText?.SanitizeAllMentions() ?? ""
 | 
					 | 
				
			||||||
                : crEmbed.PlainText?.SanitizeMentions() ?? "";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            return channel.SendMessageAsync(plainText, embed: crEmbed.IsEmbedValid
 | 
					 | 
				
			||||||
                ? crEmbed.ToEmbed(eb).Build()
 | 
					 | 
				
			||||||
                : null);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public static List<ulong> GetGuildIds(this DiscordSocketClient client)
 | 
					        public static List<ulong> GetGuildIds(this DiscordSocketClient client)
 | 
				
			||||||
            => client.Guilds.Select(x => x.Id).ToList();
 | 
					            => client.Guilds.Select(x => x.Id).ToList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user