mirror of
				https://gitlab.com/Kwoth/nadekobot.git
				synced 2025-11-03 16:24:27 -05:00 
			
		
		
		
	- Reworked embed builder
- Use IEmbedBuilderService to create embed builders - Wrapped embed builder and using IEmbedBuilder
This commit is contained in:
		@@ -2,6 +2,7 @@ using Discord;
 | 
				
			|||||||
using NadekoBot.Extensions;
 | 
					using NadekoBot.Extensions;
 | 
				
			||||||
using Newtonsoft.Json;
 | 
					using Newtonsoft.Json;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
 | 
					using NadekoBot.Services;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace NadekoBot.Common
 | 
					namespace NadekoBot.Common
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -29,7 +30,7 @@ namespace NadekoBot.Common
 | 
				
			|||||||
            (Footer != null && (!string.IsNullOrWhiteSpace(Footer.Text) || !string.IsNullOrWhiteSpace(Footer.IconUrl))) ||
 | 
					            (Footer != null && (!string.IsNullOrWhiteSpace(Footer.Text) || !string.IsNullOrWhiteSpace(Footer.IconUrl))) ||
 | 
				
			||||||
            (Fields != null && Fields.Length > 0);
 | 
					            (Fields != null && Fields.Length > 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public EmbedBuilder ToEmbed()
 | 
					        public IEmbedBuilder ToEmbed(IEmbedBuilderService eb)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var embed = new EmbedBuilder();
 | 
					            var embed = new EmbedBuilder();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -67,7 +68,7 @@ namespace NadekoBot.Common
 | 
				
			|||||||
                        embed.AddField(f.Name, f.Value, f.Inline);
 | 
					                        embed.AddField(f.Name, f.Value, f.Inline);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return embed;
 | 
					            return eb.Create(embed);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public static bool TryParse(string input, out CREmbed embed)
 | 
					        public static bool TryParse(string input, out CREmbed embed)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										26
									
								
								src/NadekoBot/Common/IEmbedBuilder.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/NadekoBot/Common/IEmbedBuilder.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					using Discord;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// todo test guild colors
 | 
				
			||||||
 | 
					namespace NadekoBot
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public interface IEmbedBuilder
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        IEmbedBuilder WithDescription(string desc);
 | 
				
			||||||
 | 
					        IEmbedBuilder WithTitle(string title);
 | 
				
			||||||
 | 
					        IEmbedBuilder AddField(string title, object value, bool isInline = false);
 | 
				
			||||||
 | 
					        IEmbedBuilder WithFooter(string text, string iconUrl = null);
 | 
				
			||||||
 | 
					        IEmbedBuilder WithAuthor(string name, string iconUrl = null, string url = null);
 | 
				
			||||||
 | 
					        IEmbedBuilder WithColor(EmbedColor color);
 | 
				
			||||||
 | 
					        Embed Build();
 | 
				
			||||||
 | 
					        IEmbedBuilder WithUrl(string url);
 | 
				
			||||||
 | 
					        IEmbedBuilder WithImageUrl(string url);
 | 
				
			||||||
 | 
					        IEmbedBuilder WithThumbnailUrl(string url);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public enum EmbedColor
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Ok,
 | 
				
			||||||
 | 
					        Pending,
 | 
				
			||||||
 | 
					        Error,
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -14,6 +14,7 @@ namespace NadekoBot.Modules
 | 
				
			|||||||
        public IBotStrings Strings { get; set; }
 | 
					        public IBotStrings Strings { get; set; }
 | 
				
			||||||
        public CommandHandler CmdHandler { get; set; }
 | 
					        public CommandHandler CmdHandler { get; set; }
 | 
				
			||||||
        public ILocalization Localization { get; set; }
 | 
					        public ILocalization Localization { get; set; }
 | 
				
			||||||
 | 
					        public IEmbedBuilderService _eb { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public string Prefix => CmdHandler.GetPrefix(ctx.Guild);
 | 
					        public string Prefix => CmdHandler.GetPrefix(ctx.Guild);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -34,36 +35,51 @@ namespace NadekoBot.Modules
 | 
				
			|||||||
        protected string GetText(string key, params object[] args) =>
 | 
					        protected string GetText(string key, params object[] args) =>
 | 
				
			||||||
            Strings.GetText(key, _cultureInfo, args);
 | 
					            Strings.GetText(key, _cultureInfo, args);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public Task<IUserMessage> SendErrorAsync(string error)
 | 
				
			||||||
 | 
					            => ctx.Channel.SendErrorAsync(_eb, error);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        public Task<IUserMessage> SendErrorAsync(string title, string error, string url = null, string footer = null)
 | 
				
			||||||
 | 
					            => ctx.Channel.SendErrorAsync(_eb, title, error, url, footer);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        public Task<IUserMessage> SendConfirmAsync(string text)
 | 
				
			||||||
 | 
					            => ctx.Channel.SendConfirmAsync(_eb, text);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        public Task<IUserMessage> SendConfirmAsync(string title, string text, string url = null, string footer = null)
 | 
				
			||||||
 | 
					            => ctx.Channel.SendConfirmAsync(_eb, title, text, url, footer);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        public Task<IUserMessage> SendPendingAsync(string text)
 | 
				
			||||||
 | 
					            => ctx.Channel.SendPendingAsync(_eb, text);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
        public Task<IUserMessage> ErrorLocalizedAsync(string textKey, params object[] args)
 | 
					        public Task<IUserMessage> ErrorLocalizedAsync(string textKey, params object[] args)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var text = GetText(textKey, args);
 | 
					            var text = GetText(textKey, args);
 | 
				
			||||||
            return ctx.Channel.SendErrorAsync(text);
 | 
					            return SendErrorAsync(text);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public Task<IUserMessage> ReplyErrorLocalizedAsync(string textKey, params object[] args)
 | 
					        public Task<IUserMessage> ReplyErrorLocalizedAsync(string textKey, params object[] args)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var text = GetText(textKey, args);
 | 
					            var text = GetText(textKey, args);
 | 
				
			||||||
            return ctx.Channel.SendErrorAsync(Format.Bold(ctx.User.ToString()) + " " + text);
 | 
					            return SendErrorAsync(Format.Bold(ctx.User.ToString()) + " " + text);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        public Task<IUserMessage> ReplyPendingLocalizedAsync(string textKey, params object[] args)
 | 
					        public Task<IUserMessage> ReplyPendingLocalizedAsync(string textKey, params object[] args)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var text = GetText(textKey, args);
 | 
					            var text = GetText(textKey, args);
 | 
				
			||||||
            return ctx.Channel.SendPendingAsync(Format.Bold(ctx.User.ToString()) + " " + text);
 | 
					            return SendPendingAsync(Format.Bold(ctx.User.ToString()) + " " + text);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public Task<IUserMessage> ConfirmLocalizedAsync(string textKey, params object[] args)
 | 
					        public Task<IUserMessage> ConfirmLocalizedAsync(string textKey, params object[] args)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var text = GetText(textKey, args);
 | 
					            var text = GetText(textKey, args);
 | 
				
			||||||
            return ctx.Channel.SendConfirmAsync(text);
 | 
					            return SendConfirmAsync(text);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public Task<IUserMessage> ReplyConfirmLocalizedAsync(string textKey, params object[] args)
 | 
					        public Task<IUserMessage> ReplyConfirmLocalizedAsync(string textKey, params object[] args)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var text = GetText(textKey, args);
 | 
					            var text = GetText(textKey, args);
 | 
				
			||||||
            return ctx.Channel.SendConfirmAsync(Format.Bold(ctx.User.ToString()) + " " + text);
 | 
					            return SendConfirmAsync(Format.Bold(ctx.User.ToString()) + " " + text);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public async Task<bool> PromptUserConfirmAsync(EmbedBuilder embed)
 | 
					        public async Task<bool> PromptUserConfirmAsync(IEmbedBuilder embed)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            embed
 | 
					            embed
 | 
				
			||||||
                .WithPendingColor()
 | 
					                .WithPendingColor()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -50,7 +50,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
            var guild = (SocketGuild) ctx.Guild;
 | 
					            var guild = (SocketGuild) ctx.Guild;
 | 
				
			||||||
            var (enabled, channels) = _service.GetDelMsgOnCmdData(ctx.Guild.Id);
 | 
					            var (enabled, channels) = _service.GetDelMsgOnCmdData(ctx.Guild.Id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var embed = new EmbedBuilder()
 | 
					            var embed = _eb.Create()
 | 
				
			||||||
                .WithOkColor()
 | 
					                .WithOkColor()
 | 
				
			||||||
                .WithTitle(GetText("server_delmsgoncmd"))
 | 
					                .WithTitle(GetText("server_delmsgoncmd"))
 | 
				
			||||||
                .WithDescription(enabled ? "✅" : "❌");
 | 
					                .WithDescription(enabled ? "✅" : "❌");
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,7 +22,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
                sql = string.Format(sql, reps);
 | 
					                sql = string.Format(sql, reps);
 | 
				
			||||||
                try
 | 
					                try
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    var embed = new EmbedBuilder()
 | 
					                    var embed = _eb.Create()
 | 
				
			||||||
                        .WithTitle(GetText("sql_confirm_exec"))
 | 
					                        .WithTitle(GetText("sql_confirm_exec"))
 | 
				
			||||||
                        .WithDescription(Format.Code(sql));
 | 
					                        .WithDescription(Format.Code(sql));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -32,11 +32,11 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    var res = await _service.ExecuteSql(sql).ConfigureAwait(false);
 | 
					                    var res = await _service.ExecuteSql(sql).ConfigureAwait(false);
 | 
				
			||||||
                    await ctx.Channel.SendConfirmAsync(res.ToString()).ConfigureAwait(false);
 | 
					                    await SendConfirmAsync(res.ToString()).ConfigureAwait(false);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                catch (Exception ex)
 | 
					                catch (Exception ex)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    await ctx.Channel.SendErrorAsync(ex.ToString()).ConfigureAwait(false);
 | 
					                    await SendErrorAsync(ex.ToString()).ConfigureAwait(false);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -52,13 +52,13 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                    if (!items.Any())
 | 
					                    if (!items.Any())
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        return new EmbedBuilder()
 | 
					                        return _eb.Create()
 | 
				
			||||||
                            .WithErrorColor()
 | 
					                            .WithErrorColor()
 | 
				
			||||||
                            .WithFooter(sql)
 | 
					                            .WithFooter(sql)
 | 
				
			||||||
                            .WithDescription("-");
 | 
					                            .WithDescription("-");
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    return new EmbedBuilder()
 | 
					                    return _eb.Create()
 | 
				
			||||||
                        .WithOkColor()
 | 
					                        .WithOkColor()
 | 
				
			||||||
                        .WithFooter(sql)
 | 
					                        .WithFooter(sql)
 | 
				
			||||||
                        .WithTitle(string.Join(" ║ ", result.ColumnNames))
 | 
					                        .WithTitle(string.Join(" ║ ", result.ColumnNames))
 | 
				
			||||||
@@ -106,7 +106,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
            [OwnerOnly]
 | 
					            [OwnerOnly]
 | 
				
			||||||
            public async Task PurgeUser(ulong userId)
 | 
					            public async Task PurgeUser(ulong userId)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var embed = new EmbedBuilder()
 | 
					                var embed = _eb.Create()
 | 
				
			||||||
                    .WithDescription(GetText("purge_user_confirm", Format.Bold(userId.ToString())));
 | 
					                    .WithDescription(GetText("purge_user_confirm", Format.Bold(userId.ToString())));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (!await PromptUserConfirmAsync(embed).ConfigureAwait(false))
 | 
					                if (!await PromptUserConfirmAsync(embed).ConfigureAwait(false))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -41,7 +41,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
            [UserPerm(GuildPerm.Administrator)]
 | 
					            [UserPerm(GuildPerm.Administrator)]
 | 
				
			||||||
            public async Task DiscordPermOverrideReset()
 | 
					            public async Task DiscordPermOverrideReset()
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var result = await PromptUserConfirmAsync(new EmbedBuilder()
 | 
					                var result = await PromptUserConfirmAsync(_eb.Create()
 | 
				
			||||||
                    .WithOkColor()
 | 
					                    .WithOkColor()
 | 
				
			||||||
                    .WithDescription(GetText("perm_override_all_confirm")));
 | 
					                    .WithDescription(GetText("perm_override_all_confirm")));
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
@@ -64,7 +64,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                await ctx.SendPaginatedConfirmAsync(page, curPage =>
 | 
					                await ctx.SendPaginatedConfirmAsync(page, curPage =>
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    var eb = new EmbedBuilder()
 | 
					                    var eb = _eb.Create()
 | 
				
			||||||
                        .WithTitle(GetText("perm_overrides"))
 | 
					                        .WithTitle(GetText("perm_overrides"))
 | 
				
			||||||
                        .WithOkColor();
 | 
					                        .WithOkColor();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -122,7 +122,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
            [NadekoCommand, Aliases]
 | 
					            [NadekoCommand, Aliases]
 | 
				
			||||||
            public async Task LanguagesList()
 | 
					            public async Task LanguagesList()
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                await ctx.Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
 | 
					                await ctx.Channel.EmbedAsync(_eb.Create().WithOkColor()
 | 
				
			||||||
                    .WithTitle(GetText("lang_list"))
 | 
					                    .WithTitle(GetText("lang_list"))
 | 
				
			||||||
                    .WithDescription(string.Join("\n",
 | 
					                    .WithDescription(string.Join("\n",
 | 
				
			||||||
                        supportedLocales.Select(x => $"{Format.Code(x.Key),-10} => {x.Value}")))).ConfigureAwait(false);
 | 
					                        supportedLocales.Select(x => $"{Format.Code(x.Key),-10} => {x.Value}")))).ConfigureAwait(false);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -69,7 +69,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
                        return Format.Bold(x);
 | 
					                        return Format.Bold(x);
 | 
				
			||||||
                    }));
 | 
					                    }));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                await ctx.Channel.SendConfirmAsync(Format.Bold(GetText("log_events")) + "\n" +
 | 
					                await SendConfirmAsync(Format.Bold(GetText("log_events")) + "\n" +
 | 
				
			||||||
                    str)
 | 
					                    str)
 | 
				
			||||||
                    .ConfigureAwait(false);
 | 
					                    .ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -133,7 +133,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                await ctx.Channel.SendConfirmAsync(GetText("prot_enable", "Anti-Raid"),
 | 
					                await SendConfirmAsync(GetText("prot_enable", "Anti-Raid"),
 | 
				
			||||||
                        $"{ctx.User.Mention} {GetAntiRaidString(stats)}")
 | 
					                        $"{ctx.User.Mention} {GetAntiRaidString(stats)}")
 | 
				
			||||||
                        .ConfigureAwait(false);
 | 
					                        .ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -199,7 +199,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                var stats = await _service.StartAntiSpamAsync(ctx.Guild.Id, messageCount, action, time, role?.Id).ConfigureAwait(false);
 | 
					                var stats = await _service.StartAntiSpamAsync(ctx.Guild.Id, messageCount, action, time, role?.Id).ConfigureAwait(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                await ctx.Channel.SendConfirmAsync(GetText("prot_enable", "Anti-Spam"),
 | 
					                await SendConfirmAsync(GetText("prot_enable", "Anti-Spam"),
 | 
				
			||||||
                    $"{ctx.User.Mention} {GetAntiSpamString(stats)}").ConfigureAwait(false);
 | 
					                    $"{ctx.User.Mention} {GetAntiSpamString(stats)}").ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -231,7 +231,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var embed = new EmbedBuilder().WithOkColor()
 | 
					                var embed = _eb.Create().WithOkColor()
 | 
				
			||||||
                    .WithTitle(GetText("prot_active"));
 | 
					                    .WithTitle(GetText("prot_active"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (spam != null)
 | 
					                if (spam != null)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -130,7 +130,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
            [UserPerm(GuildPerm.ManageRoles)]
 | 
					            [UserPerm(GuildPerm.ManageRoles)]
 | 
				
			||||||
            public async Task ReactionRolesList()
 | 
					            public async Task ReactionRolesList()
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var embed = new EmbedBuilder()
 | 
					                var embed = _eb.Create()
 | 
				
			||||||
                    .WithOkColor();
 | 
					                    .WithOkColor();
 | 
				
			||||||
                if (!_service.Get(ctx.Guild.Id, out var rrs) ||
 | 
					                if (!_service.Get(ctx.Guild.Id, out var rrs) ||
 | 
				
			||||||
                    !rrs.Any())
 | 
					                    !rrs.Any())
 | 
				
			||||||
@@ -319,7 +319,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
            [Priority(1)]
 | 
					            [Priority(1)]
 | 
				
			||||||
            public async Task RoleColor([Leftover] IRole role)
 | 
					            public async Task RoleColor([Leftover] IRole role)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                await ctx.Channel.SendConfirmAsync("Role Color", role.Color.RawValue.ToString("x6")).ConfigureAwait(false);
 | 
					                await SendConfirmAsync("Role Color", role.Color.RawValue.ToString("x6")).ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            [NadekoCommand, Aliases]
 | 
					            [NadekoCommand, Aliases]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -154,7 +154,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
                        rolesStr.AppendLine();
 | 
					                        rolesStr.AppendLine();
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    return new EmbedBuilder().WithOkColor()
 | 
					                    return _eb.Create().WithOkColor()
 | 
				
			||||||
                        .WithTitle(Format.Bold(GetText("self_assign_list", roles.Count())))
 | 
					                        .WithTitle(Format.Bold(GetText("self_assign_list", roles.Count())))
 | 
				
			||||||
                        .WithDescription(rolesStr.ToString())
 | 
					                        .WithDescription(rolesStr.ToString())
 | 
				
			||||||
                        .WithFooter(exclusive
 | 
					                        .WithFooter(exclusive
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -57,7 +57,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
                };
 | 
					                };
 | 
				
			||||||
                _service.AddNewAutoCommand(cmd);
 | 
					                _service.AddNewAutoCommand(cmd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                await ctx.Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
 | 
					                await ctx.Channel.EmbedAsync(_eb.Create().WithOkColor()
 | 
				
			||||||
                    .WithTitle(GetText("scadd"))
 | 
					                    .WithTitle(GetText("scadd"))
 | 
				
			||||||
                    .AddField(GetText("server"), cmd.GuildId is null ? $"-" : $"{cmd.GuildName}/{cmd.GuildId}", true)
 | 
					                    .AddField(GetText("server"), cmd.GuildId is null ? $"-" : $"{cmd.GuildName}/{cmd.GuildId}", true)
 | 
				
			||||||
                    .AddField(GetText("channel"), $"{cmd.ChannelName}/{cmd.ChannelId}", true)
 | 
					                    .AddField(GetText("channel"), $"{cmd.ChannelName}/{cmd.ChannelId}", true)
 | 
				
			||||||
@@ -113,7 +113,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
                else
 | 
					                else
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    var i = 0;
 | 
					                    var i = 0;
 | 
				
			||||||
                    await ctx.Channel.SendConfirmAsync(
 | 
					                    await SendConfirmAsync(
 | 
				
			||||||
                        text: string.Join("\n", scmds
 | 
					                        text: string.Join("\n", scmds
 | 
				
			||||||
                        .Select(x => $@"```css
 | 
					                        .Select(x => $@"```css
 | 
				
			||||||
#{++i + page * 5}
 | 
					#{++i + page * 5}
 | 
				
			||||||
@@ -145,7 +145,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
                else
 | 
					                else
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    var i = 0;
 | 
					                    var i = 0;
 | 
				
			||||||
                    await ctx.Channel.SendConfirmAsync(
 | 
					                    await SendConfirmAsync(
 | 
				
			||||||
                        text: string.Join("\n", scmds
 | 
					                        text: string.Join("\n", scmds
 | 
				
			||||||
                        .Select(x => $@"```css
 | 
					                        .Select(x => $@"```css
 | 
				
			||||||
#{++i + page * 5}
 | 
					#{++i + page * 5}
 | 
				
			||||||
@@ -173,7 +173,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
                ctx.Message.DeleteAfter(0);
 | 
					                ctx.Message.DeleteAfter(0);
 | 
				
			||||||
                try
 | 
					                try
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    var msg = await ctx.Channel.SendConfirmAsync($"⏲ {miliseconds}ms")
 | 
					                    var msg = await SendConfirmAsync($"⏲ {miliseconds}ms")
 | 
				
			||||||
                        .ConfigureAwait(false);
 | 
					                        .ConfigureAwait(false);
 | 
				
			||||||
                    msg.DeleteAfter(miliseconds / 1000);
 | 
					                    msg.DeleteAfter(miliseconds / 1000);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@@ -277,7 +277,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
                    if (string.IsNullOrWhiteSpace(str))
 | 
					                    if (string.IsNullOrWhiteSpace(str))
 | 
				
			||||||
                        str = GetText("no_shards_on_page");
 | 
					                        str = GetText("no_shards_on_page");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    return new EmbedBuilder()
 | 
					                    return _eb.Create()
 | 
				
			||||||
                        .WithOkColor()
 | 
					                        .WithOkColor()
 | 
				
			||||||
                        .WithDescription($"{status}\n\n{str}");
 | 
					                        .WithDescription($"{status}\n\n{str}");
 | 
				
			||||||
                }, allShardStrings.Length, 25).ConfigureAwait(false);
 | 
					                }, allShardStrings.Length, 25).ConfigureAwait(false);
 | 
				
			||||||
@@ -477,7 +477,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
                    if (CREmbed.TryParse(msg, out var crembed))
 | 
					                    if (CREmbed.TryParse(msg, out var crembed))
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        rep.Replace(crembed);
 | 
					                        rep.Replace(crembed);
 | 
				
			||||||
                        await ch.EmbedAsync(crembed).ConfigureAwait(false);
 | 
					                        await ch.EmbedAsync(crembed, _eb).ConfigureAwait(false);
 | 
				
			||||||
                        await ReplyConfirmLocalizedAsync("message_sent").ConfigureAwait(false);
 | 
					                        await ReplyConfirmLocalizedAsync("message_sent").ConfigureAwait(false);
 | 
				
			||||||
                        return;
 | 
					                        return;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
@@ -495,7 +495,8 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
                    if (CREmbed.TryParse(msg, out var crembed))
 | 
					                    if (CREmbed.TryParse(msg, out var crembed))
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        rep.Replace(crembed);
 | 
					                        rep.Replace(crembed);
 | 
				
			||||||
                        await (await user.GetOrCreateDMChannelAsync().ConfigureAwait(false)).EmbedAsync(crembed)
 | 
					                        await (await user.GetOrCreateDMChannelAsync().ConfigureAwait(false))
 | 
				
			||||||
 | 
					                            .EmbedAsync(crembed, _eb)
 | 
				
			||||||
                            .ConfigureAwait(false);
 | 
					                            .ConfigureAwait(false);
 | 
				
			||||||
                        await ReplyConfirmLocalizedAsync("message_sent").ConfigureAwait(false);
 | 
					                        await ReplyConfirmLocalizedAsync("message_sent").ConfigureAwait(false);
 | 
				
			||||||
                        return;
 | 
					                        return;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,12 +24,14 @@ namespace NadekoBot.Modules.Administration.Services
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        private readonly DbService _db;
 | 
					        private readonly DbService _db;
 | 
				
			||||||
        private readonly ILogCommandService _logService;
 | 
					        private readonly ILogCommandService _logService;
 | 
				
			||||||
 | 
					        private readonly IEmbedBuilderService _eb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public AdministrationService(Bot bot, CommandHandler cmdHandler, DbService db,
 | 
					        public AdministrationService(Bot bot, CommandHandler cmdHandler, DbService db,
 | 
				
			||||||
            ILogCommandService logService)
 | 
					            ILogCommandService logService, IEmbedBuilderService eb)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _db = db;
 | 
					            _db = db;
 | 
				
			||||||
            _logService = logService;
 | 
					            _logService = logService;
 | 
				
			||||||
 | 
					            _eb = eb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            DeleteMessagesOnCommand = new ConcurrentHashSet<ulong>(bot.AllGuildConfigs
 | 
					            DeleteMessagesOnCommand = new ConcurrentHashSet<ulong>(bot.AllGuildConfigs
 | 
				
			||||||
                .Where(g => g.DeleteMessageOnCommand)
 | 
					                .Where(g => g.DeleteMessageOnCommand)
 | 
				
			||||||
@@ -170,7 +172,7 @@ namespace NadekoBot.Modules.Administration.Services
 | 
				
			|||||||
                rep.Replace(crembed);
 | 
					                rep.Replace(crembed);
 | 
				
			||||||
                await umsg.ModifyAsync(x =>
 | 
					                await umsg.ModifyAsync(x =>
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    x.Embed = crembed.ToEmbed().Build();
 | 
					                    x.Embed = crembed.ToEmbed(_eb).Build();
 | 
				
			||||||
                    x.Content = crembed.PlainText?.SanitizeMentions() ?? "";
 | 
					                    x.Content = crembed.PlainText?.SanitizeMentions() ?? "";
 | 
				
			||||||
                }).ConfigureAwait(false);
 | 
					                }).ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -68,13 +68,19 @@ namespace NadekoBot.Modules.Administration.Services
 | 
				
			|||||||
        private readonly MuteService _mute;
 | 
					        private readonly MuteService _mute;
 | 
				
			||||||
        private readonly ProtectionService _prot;
 | 
					        private readonly ProtectionService _prot;
 | 
				
			||||||
        private readonly GuildTimezoneService _tz;
 | 
					        private readonly GuildTimezoneService _tz;
 | 
				
			||||||
 | 
					        private readonly IEmbedBuilderService _eb;
 | 
				
			||||||
 | 
					        private readonly IMemoryCache _memoryCache;
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        private readonly Timer _clearTimer;
 | 
				
			||||||
 | 
					        private readonly ConcurrentHashSet<ulong> _ignoreMessageIds = new ConcurrentHashSet<ulong>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public LogCommandService(DiscordSocketClient client, IBotStrings strings,
 | 
					        public LogCommandService(DiscordSocketClient client, IBotStrings strings,
 | 
				
			||||||
            DbService db, MuteService mute, ProtectionService prot, GuildTimezoneService tz, 
 | 
					            DbService db, MuteService mute, ProtectionService prot, GuildTimezoneService tz, 
 | 
				
			||||||
            IMemoryCache memoryCache)
 | 
					            IMemoryCache memoryCache, IEmbedBuilderService eb)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _client = client;
 | 
					            _client = client;
 | 
				
			||||||
            _memoryCache = memoryCache;
 | 
					            _memoryCache = memoryCache;
 | 
				
			||||||
 | 
					            _eb = eb;
 | 
				
			||||||
            _strings = strings;
 | 
					            _strings = strings;
 | 
				
			||||||
            _db = db;
 | 
					            _db = db;
 | 
				
			||||||
            _mute = mute;
 | 
					            _mute = mute;
 | 
				
			||||||
@@ -111,7 +117,7 @@ namespace NadekoBot.Modules.Administration.Services
 | 
				
			|||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        var title = GetText(key.Guild, "presence_updates");
 | 
					                        var title = GetText(key.Guild, "presence_updates");
 | 
				
			||||||
                        var desc = string.Join(Environment.NewLine, msgs);
 | 
					                        var desc = string.Join(Environment.NewLine, msgs);
 | 
				
			||||||
                        return key.SendConfirmAsync(title, desc.TrimTo(2048));
 | 
					                        return key.SendConfirmAsync(_eb, title, desc.TrimTo(2048));
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    return Task.CompletedTask;
 | 
					                    return Task.CompletedTask;
 | 
				
			||||||
@@ -148,10 +154,6 @@ namespace NadekoBot.Modules.Administration.Services
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private readonly Timer _clearTimer;
 | 
					 | 
				
			||||||
        private readonly ConcurrentHashSet<ulong> _ignoreMessageIds = new ConcurrentHashSet<ulong>();
 | 
					 | 
				
			||||||
        private readonly IMemoryCache _memoryCache;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public LogSetting GetGuildLogSettings(ulong guildId)
 | 
					        public LogSetting GetGuildLogSettings(ulong guildId)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            GuildLogSettings.TryGetValue(guildId, out LogSetting logSetting);
 | 
					            GuildLogSettings.TryGetValue(guildId, out LogSetting logSetting);
 | 
				
			||||||
@@ -254,7 +256,7 @@ namespace NadekoBot.Modules.Administration.Services
 | 
				
			|||||||
                        await TryGetLogChannel(g, logSetting, LogType.UserUpdated).ConfigureAwait(false)) is null)
 | 
					                        await TryGetLogChannel(g, logSetting, LogType.UserUpdated).ConfigureAwait(false)) is null)
 | 
				
			||||||
                        return;
 | 
					                        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    var embed = new EmbedBuilder();
 | 
					                    var embed = _eb.Create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if (before.Username != after.Username)
 | 
					                    if (before.Username != after.Username)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
@@ -441,7 +443,7 @@ namespace NadekoBot.Modules.Administration.Services
 | 
				
			|||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    var embed = new EmbedBuilder().WithAuthor(mutes)
 | 
					                    var embed = _eb.Create().WithAuthor(mutes)
 | 
				
			||||||
                        .WithTitle($"{usr.Username}#{usr.Discriminator} | {usr.Id}")
 | 
					                        .WithTitle($"{usr.Username}#{usr.Discriminator} | {usr.Id}")
 | 
				
			||||||
                        .WithFooter(CurrentTime(usr.Guild))
 | 
					                        .WithFooter(CurrentTime(usr.Guild))
 | 
				
			||||||
                        .WithOkColor();
 | 
					                        .WithOkColor();
 | 
				
			||||||
@@ -486,7 +488,7 @@ namespace NadekoBot.Modules.Administration.Services
 | 
				
			|||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    var embed = new EmbedBuilder().WithAuthor(mutes)
 | 
					                    var embed = _eb.Create().WithAuthor(mutes)
 | 
				
			||||||
                        .WithTitle($"{usr.Username}#{usr.Discriminator} | {usr.Id}")
 | 
					                        .WithTitle($"{usr.Username}#{usr.Discriminator} | {usr.Id}")
 | 
				
			||||||
                        .WithFooter($"{CurrentTime(usr.Guild)}")
 | 
					                        .WithFooter($"{CurrentTime(usr.Guild)}")
 | 
				
			||||||
                        .WithOkColor();
 | 
					                        .WithOkColor();
 | 
				
			||||||
@@ -541,7 +543,7 @@ namespace NadekoBot.Modules.Administration.Services
 | 
				
			|||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    var embed = new EmbedBuilder().WithAuthor($"🛡 Anti-{protection}")
 | 
					                    var embed = _eb.Create().WithAuthor($"🛡 Anti-{protection}")
 | 
				
			||||||
                        .WithTitle(GetText(logChannel.Guild, "users") + " " + punishment)
 | 
					                        .WithTitle(GetText(logChannel.Guild, "users") + " " + punishment)
 | 
				
			||||||
                        .WithDescription(string.Join("\n", users.Select(u => u.ToString())))
 | 
					                        .WithDescription(string.Join("\n", users.Select(u => u.ToString())))
 | 
				
			||||||
                        .WithFooter(CurrentTime(logChannel.Guild))
 | 
					                        .WithFooter(CurrentTime(logChannel.Guild))
 | 
				
			||||||
@@ -589,7 +591,7 @@ namespace NadekoBot.Modules.Administration.Services
 | 
				
			|||||||
                        (logChannel = await TryGetLogChannel(before.Guild, logSetting, LogType.UserUpdated)
 | 
					                        (logChannel = await TryGetLogChannel(before.Guild, logSetting, LogType.UserUpdated)
 | 
				
			||||||
                            .ConfigureAwait(false)) != null)
 | 
					                            .ConfigureAwait(false)) != null)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        var embed = new EmbedBuilder().WithOkColor()
 | 
					                        var embed = _eb.Create().WithOkColor()
 | 
				
			||||||
                            .WithFooter(CurrentTime(before.Guild))
 | 
					                            .WithFooter(CurrentTime(before.Guild))
 | 
				
			||||||
                            .WithTitle($"{before.Username}#{before.Discriminator} | {before.Id}");
 | 
					                            .WithTitle($"{before.Username}#{before.Discriminator} | {before.Id}");
 | 
				
			||||||
                        if (before.Nickname != after.Nickname)
 | 
					                        if (before.Nickname != after.Nickname)
 | 
				
			||||||
@@ -691,7 +693,7 @@ namespace NadekoBot.Modules.Administration.Services
 | 
				
			|||||||
                        .ConfigureAwait(false)) is null)
 | 
					                        .ConfigureAwait(false)) is null)
 | 
				
			||||||
                        return;
 | 
					                        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    var embed = new EmbedBuilder().WithOkColor()
 | 
					                    var embed = _eb.Create().WithOkColor()
 | 
				
			||||||
                        .WithFooter(CurrentTime(before.Guild));
 | 
					                        .WithFooter(CurrentTime(before.Guild));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    var beforeTextChannel = cbefore as ITextChannel;
 | 
					                    var beforeTextChannel = cbefore as ITextChannel;
 | 
				
			||||||
@@ -749,7 +751,7 @@ namespace NadekoBot.Modules.Administration.Services
 | 
				
			|||||||
                    else
 | 
					                    else
 | 
				
			||||||
                        title = GetText(logChannel.Guild, "text_chan_destroyed");
 | 
					                        title = GetText(logChannel.Guild, "text_chan_destroyed");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    await logChannel.EmbedAsync(new EmbedBuilder()
 | 
					                    await logChannel.EmbedAsync(_eb.Create()
 | 
				
			||||||
                        .WithOkColor()
 | 
					                        .WithOkColor()
 | 
				
			||||||
                        .WithTitle("🆕 " + title)
 | 
					                        .WithTitle("🆕 " + title)
 | 
				
			||||||
                        .WithDescription($"{ch.Name} | {ch.Id}")
 | 
					                        .WithDescription($"{ch.Name} | {ch.Id}")
 | 
				
			||||||
@@ -788,7 +790,7 @@ namespace NadekoBot.Modules.Administration.Services
 | 
				
			|||||||
                    else
 | 
					                    else
 | 
				
			||||||
                        title = GetText(logChannel.Guild, "text_chan_created");
 | 
					                        title = GetText(logChannel.Guild, "text_chan_created");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    await logChannel.EmbedAsync(new EmbedBuilder()
 | 
					                    await logChannel.EmbedAsync(_eb.Create()
 | 
				
			||||||
                        .WithOkColor()
 | 
					                        .WithOkColor()
 | 
				
			||||||
                        .WithTitle("🆕 " + title)
 | 
					                        .WithTitle("🆕 " + title)
 | 
				
			||||||
                        .WithDescription($"{ch.Name} | {ch.Id}")
 | 
					                        .WithDescription($"{ch.Name} | {ch.Id}")
 | 
				
			||||||
@@ -920,7 +922,7 @@ namespace NadekoBot.Modules.Administration.Services
 | 
				
			|||||||
                    if ((logChannel = await TryGetLogChannel(usr.Guild, logSetting, LogType.UserLeft)
 | 
					                    if ((logChannel = await TryGetLogChannel(usr.Guild, logSetting, LogType.UserLeft)
 | 
				
			||||||
                        .ConfigureAwait(false)) is null)
 | 
					                        .ConfigureAwait(false)) is null)
 | 
				
			||||||
                        return;
 | 
					                        return;
 | 
				
			||||||
                    var embed = new EmbedBuilder()
 | 
					                    var embed = _eb.Create()
 | 
				
			||||||
                        .WithOkColor()
 | 
					                        .WithOkColor()
 | 
				
			||||||
                        .WithTitle("❌ " + GetText(logChannel.Guild, "user_left"))
 | 
					                        .WithTitle("❌ " + GetText(logChannel.Guild, "user_left"))
 | 
				
			||||||
                        .WithDescription(usr.ToString())
 | 
					                        .WithDescription(usr.ToString())
 | 
				
			||||||
@@ -955,7 +957,7 @@ namespace NadekoBot.Modules.Administration.Services
 | 
				
			|||||||
                        .ConfigureAwait(false)) is null)
 | 
					                        .ConfigureAwait(false)) is null)
 | 
				
			||||||
                        return;
 | 
					                        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    var embed = new EmbedBuilder()
 | 
					                    var embed = _eb.Create()
 | 
				
			||||||
                        .WithOkColor()
 | 
					                        .WithOkColor()
 | 
				
			||||||
                        .WithTitle("✅ " + GetText(logChannel.Guild, "user_joined"))
 | 
					                        .WithTitle("✅ " + GetText(logChannel.Guild, "user_joined"))
 | 
				
			||||||
                        .WithDescription($"{usr.Mention} `{usr}`")
 | 
					                        .WithDescription($"{usr.Mention} `{usr}`")
 | 
				
			||||||
@@ -995,7 +997,7 @@ namespace NadekoBot.Modules.Administration.Services
 | 
				
			|||||||
                    if ((logChannel = await TryGetLogChannel(guild, logSetting, LogType.UserUnbanned)
 | 
					                    if ((logChannel = await TryGetLogChannel(guild, logSetting, LogType.UserUnbanned)
 | 
				
			||||||
                        .ConfigureAwait(false)) is null)
 | 
					                        .ConfigureAwait(false)) is null)
 | 
				
			||||||
                        return;
 | 
					                        return;
 | 
				
			||||||
                    var embed = new EmbedBuilder()
 | 
					                    var embed = _eb.Create()
 | 
				
			||||||
                        .WithOkColor()
 | 
					                        .WithOkColor()
 | 
				
			||||||
                        .WithTitle("♻️ " + GetText(logChannel.Guild, "user_unbanned"))
 | 
					                        .WithTitle("♻️ " + GetText(logChannel.Guild, "user_unbanned"))
 | 
				
			||||||
                        .WithDescription(usr.ToString())
 | 
					                        .WithDescription(usr.ToString())
 | 
				
			||||||
@@ -1030,7 +1032,7 @@ namespace NadekoBot.Modules.Administration.Services
 | 
				
			|||||||
                            await TryGetLogChannel(guild, logSetting, LogType.UserBanned).ConfigureAwait(false)) ==
 | 
					                            await TryGetLogChannel(guild, logSetting, LogType.UserBanned).ConfigureAwait(false)) ==
 | 
				
			||||||
                        null)
 | 
					                        null)
 | 
				
			||||||
                        return;
 | 
					                        return;
 | 
				
			||||||
                    var embed = new EmbedBuilder()
 | 
					                    var embed = _eb.Create()
 | 
				
			||||||
                        .WithOkColor()
 | 
					                        .WithOkColor()
 | 
				
			||||||
                        .WithTitle("🚫 " + GetText(logChannel.Guild, "user_banned"))
 | 
					                        .WithTitle("🚫 " + GetText(logChannel.Guild, "user_banned"))
 | 
				
			||||||
                        .WithDescription(usr.ToString())
 | 
					                        .WithDescription(usr.ToString())
 | 
				
			||||||
@@ -1079,7 +1081,7 @@ namespace NadekoBot.Modules.Administration.Services
 | 
				
			|||||||
                        return;
 | 
					                        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    var resolvedMessage = msg.Resolve(userHandling: TagHandling.FullName);
 | 
					                    var resolvedMessage = msg.Resolve(userHandling: TagHandling.FullName);
 | 
				
			||||||
                    var embed = new EmbedBuilder()
 | 
					                    var embed = _eb.Create()
 | 
				
			||||||
                        .WithOkColor()
 | 
					                        .WithOkColor()
 | 
				
			||||||
                        .WithTitle("🗑 " + GetText(logChannel.Guild, "msg_del", ((ITextChannel) msg.Channel).Name))
 | 
					                        .WithTitle("🗑 " + GetText(logChannel.Guild, "msg_del", ((ITextChannel) msg.Channel).Name))
 | 
				
			||||||
                        .WithDescription(msg.Author.ToString())
 | 
					                        .WithDescription(msg.Author.ToString())
 | 
				
			||||||
@@ -1136,7 +1138,7 @@ namespace NadekoBot.Modules.Administration.Services
 | 
				
			|||||||
                        .ConfigureAwait(false)) is null || logChannel.Id == after.Channel.Id)
 | 
					                        .ConfigureAwait(false)) is null || logChannel.Id == after.Channel.Id)
 | 
				
			||||||
                        return;
 | 
					                        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    var embed = new EmbedBuilder()
 | 
					                    var embed = _eb.Create()
 | 
				
			||||||
                        .WithOkColor()
 | 
					                        .WithOkColor()
 | 
				
			||||||
                        .WithTitle("📝 " + GetText(logChannel.Guild, "msg_update", ((ITextChannel)after.Channel).Name))
 | 
					                        .WithTitle("📝 " + GetText(logChannel.Guild, "msg_update", ((ITextChannel)after.Channel).Name))
 | 
				
			||||||
                        .WithDescription(after.Author.ToString())
 | 
					                        .WithDescription(after.Author.ToString())
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,11 +39,13 @@ namespace NadekoBot.Modules.Administration.Services
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        private readonly DiscordSocketClient _client;
 | 
					        private readonly DiscordSocketClient _client;
 | 
				
			||||||
        private readonly DbService _db;
 | 
					        private readonly DbService _db;
 | 
				
			||||||
 | 
					        private readonly IEmbedBuilderService _eb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public MuteService(DiscordSocketClient client, DbService db)
 | 
					        public MuteService(DiscordSocketClient client, DbService db, IEmbedBuilderService eb)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _client = client;
 | 
					            _client = client;
 | 
				
			||||||
            _db = db;
 | 
					            _db = db;
 | 
				
			||||||
 | 
					            _eb = eb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            using (var uow = db.GetDbContext())
 | 
					            using (var uow = db.GetDbContext())
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
@@ -132,7 +134,7 @@ namespace NadekoBot.Modules.Administration.Services
 | 
				
			|||||||
            if (string.IsNullOrWhiteSpace(reason))
 | 
					            if (string.IsNullOrWhiteSpace(reason))
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            var _ = Task.Run(() => user.SendMessageAsync(embed: new EmbedBuilder()
 | 
					            var _ = Task.Run(() => user.SendMessageAsync(embed: _eb.Create()
 | 
				
			||||||
                .WithDescription($"You've been muted in {user.Guild} server")
 | 
					                .WithDescription($"You've been muted in {user.Guild} server")
 | 
				
			||||||
                .AddField("Mute Type", type.ToString())
 | 
					                .AddField("Mute Type", type.ToString())
 | 
				
			||||||
                .AddField("Moderator", mod.ToString())
 | 
					                .AddField("Moderator", mod.ToString())
 | 
				
			||||||
@@ -145,7 +147,7 @@ namespace NadekoBot.Modules.Administration.Services
 | 
				
			|||||||
            if (string.IsNullOrWhiteSpace(reason))
 | 
					            if (string.IsNullOrWhiteSpace(reason))
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
            var _ = Task.Run(() => user.SendMessageAsync(embed: new EmbedBuilder()
 | 
					            var _ = Task.Run(() => user.SendMessageAsync(embed: _eb.Create()
 | 
				
			||||||
                .WithDescription($"You've been unmuted in {user.Guild} server")
 | 
					                .WithDescription($"You've been unmuted in {user.Guild} server")
 | 
				
			||||||
                .AddField("Unmute Type", type.ToString())
 | 
					                .AddField("Unmute Type", type.ToString())
 | 
				
			||||||
                .AddField("Moderator", mod.ToString())
 | 
					                .AddField("Moderator", mod.ToString())
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -37,6 +37,7 @@ namespace NadekoBot.Modules.Administration.Services
 | 
				
			|||||||
        private readonly IHttpClientFactory _httpFactory;
 | 
					        private readonly IHttpClientFactory _httpFactory;
 | 
				
			||||||
        private readonly BotConfigService _bss;
 | 
					        private readonly BotConfigService _bss;
 | 
				
			||||||
        private readonly IPubSub _pubSub;
 | 
					        private readonly IPubSub _pubSub;
 | 
				
			||||||
 | 
					        private readonly IEmbedBuilderService _eb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //keys
 | 
					        //keys
 | 
				
			||||||
        private readonly TypedKey<ActivityPubData> _activitySetKey;
 | 
					        private readonly TypedKey<ActivityPubData> _activitySetKey;
 | 
				
			||||||
@@ -52,7 +53,8 @@ namespace NadekoBot.Modules.Administration.Services
 | 
				
			|||||||
            IDataCache cache,
 | 
					            IDataCache cache,
 | 
				
			||||||
            IHttpClientFactory factory,
 | 
					            IHttpClientFactory factory,
 | 
				
			||||||
            BotConfigService bss,
 | 
					            BotConfigService bss,
 | 
				
			||||||
            IPubSub pubSub)
 | 
					            IPubSub pubSub,
 | 
				
			||||||
 | 
					            IEmbedBuilderService eb)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _cmdHandler = cmdHandler;
 | 
					            _cmdHandler = cmdHandler;
 | 
				
			||||||
            _db = db;
 | 
					            _db = db;
 | 
				
			||||||
@@ -63,6 +65,7 @@ namespace NadekoBot.Modules.Administration.Services
 | 
				
			|||||||
            _httpFactory = factory;
 | 
					            _httpFactory = factory;
 | 
				
			||||||
            _bss = bss;
 | 
					            _bss = bss;
 | 
				
			||||||
            _pubSub = pubSub;
 | 
					            _pubSub = pubSub;
 | 
				
			||||||
 | 
					            _eb = eb;
 | 
				
			||||||
            _activitySetKey = new("activity.set");
 | 
					            _activitySetKey = new("activity.set");
 | 
				
			||||||
            _imagesReloadKey = new("images.reload");
 | 
					            _imagesReloadKey = new("images.reload");
 | 
				
			||||||
            _guildLeaveKey = new("guild.leave");
 | 
					            _guildLeaveKey = new("guild.leave");
 | 
				
			||||||
@@ -256,7 +259,7 @@ namespace NadekoBot.Modules.Administration.Services
 | 
				
			|||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        try
 | 
					                        try
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            await ownerCh.SendConfirmAsync(title, toSend).ConfigureAwait(false);
 | 
					                            await ownerCh.SendConfirmAsync(_eb, title, toSend).ConfigureAwait(false);
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        catch
 | 
					                        catch
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
@@ -271,7 +274,7 @@ namespace NadekoBot.Modules.Administration.Services
 | 
				
			|||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        try
 | 
					                        try
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            await firstOwnerChannel.SendConfirmAsync(title, toSend).ConfigureAwait(false);
 | 
					                            await firstOwnerChannel.SendConfirmAsync(_eb, title, toSend).ConfigureAwait(false);
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        catch
 | 
					                        catch
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -51,7 +51,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
                
 | 
					                
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                await ctx.SendPaginatedConfirmAsync(page,
 | 
					                await ctx.SendPaginatedConfirmAsync(page,
 | 
				
			||||||
                    (curPage) => new EmbedBuilder()
 | 
					                    (curPage) => _eb.Create()
 | 
				
			||||||
                        .WithOkColor()
 | 
					                        .WithOkColor()
 | 
				
			||||||
                        .WithTitle(GetText("timezones_available"))
 | 
					                        .WithTitle(GetText("timezones_available"))
 | 
				
			||||||
                        .WithDescription(string.Join("\n", timezoneStrings
 | 
					                        .WithDescription(string.Join("\n", timezoneStrings
 | 
				
			||||||
@@ -83,7 +83,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
                _service.SetTimeZone(ctx.Guild.Id, tz);
 | 
					                _service.SetTimeZone(ctx.Guild.Id, tz);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                await ctx.Channel.SendConfirmAsync(tz.ToString()).ConfigureAwait(false);
 | 
					                await SendConfirmAsync(tz.ToString()).ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -60,7 +60,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
                var dmFailed = false;
 | 
					                var dmFailed = false;
 | 
				
			||||||
                try
 | 
					                try
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    await (await user.GetOrCreateDMChannelAsync().ConfigureAwait(false)).EmbedAsync(new EmbedBuilder().WithErrorColor()
 | 
					                    await (await user.GetOrCreateDMChannelAsync().ConfigureAwait(false)).EmbedAsync(_eb.Create().WithErrorColor()
 | 
				
			||||||
                                     .WithDescription(GetText("warned_on", ctx.Guild.ToString()))
 | 
					                                     .WithDescription(GetText("warned_on", ctx.Guild.ToString()))
 | 
				
			||||||
                                     .AddField(GetText("moderator"), ctx.User.ToString())
 | 
					                                     .AddField(GetText("moderator"), ctx.User.ToString())
 | 
				
			||||||
                                     .AddField(GetText("reason"), reason ?? "-"))
 | 
					                                     .AddField(GetText("reason"), reason ?? "-"))
 | 
				
			||||||
@@ -79,7 +79,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
                catch (Exception ex)
 | 
					                catch (Exception ex)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    Log.Warning(ex.Message);
 | 
					                    Log.Warning(ex.Message);
 | 
				
			||||||
                    var errorEmbed = new EmbedBuilder()
 | 
					                    var errorEmbed = _eb.Create()
 | 
				
			||||||
                        .WithErrorColor()
 | 
					                        .WithErrorColor()
 | 
				
			||||||
                        .WithDescription(GetText("cant_apply_punishment"));
 | 
					                        .WithDescription(GetText("cant_apply_punishment"));
 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
@@ -92,7 +92,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var embed = new EmbedBuilder()
 | 
					                var embed = _eb.Create()
 | 
				
			||||||
                    .WithOkColor();
 | 
					                    .WithOkColor();
 | 
				
			||||||
                if (punishment is null)
 | 
					                if (punishment is null)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
@@ -219,7 +219,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
                        .ToArray();
 | 
					                        .ToArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    var user = (ctx.Guild as SocketGuild)?.GetUser(userId)?.ToString() ?? userId.ToString();
 | 
					                    var user = (ctx.Guild as SocketGuild)?.GetUser(userId)?.ToString() ?? userId.ToString();
 | 
				
			||||||
                    var embed = new EmbedBuilder()
 | 
					                    var embed = _eb.Create()
 | 
				
			||||||
                        .WithOkColor()
 | 
					                        .WithOkColor()
 | 
				
			||||||
                        .WithTitle(GetText("warnlog_for", user));
 | 
					                        .WithTitle(GetText("warnlog_for", user));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -272,7 +272,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
                            return (usr?.ToString() ?? x.Key.ToString()) + $" | {total} ({all} - {forgiven})";
 | 
					                            return (usr?.ToString() ?? x.Key.ToString()) + $" | {total} ({all} - {forgiven})";
 | 
				
			||||||
                        });
 | 
					                        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    return new EmbedBuilder().WithOkColor()
 | 
					                    return _eb.Create().WithOkColor()
 | 
				
			||||||
                        .WithTitle(GetText("warnings_list"))
 | 
					                        .WithTitle(GetText("warnings_list"))
 | 
				
			||||||
                        .WithDescription(string.Join("\n", ws));
 | 
					                        .WithDescription(string.Join("\n", ws));
 | 
				
			||||||
                }, warnings.Length, 15).ConfigureAwait(false);
 | 
					                }, warnings.Length, 15).ConfigureAwait(false);
 | 
				
			||||||
@@ -402,7 +402,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
                {
 | 
					                {
 | 
				
			||||||
                    list = GetText("warnpl_none");
 | 
					                    list = GetText("warnpl_none");
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                await ctx.Channel.SendConfirmAsync(
 | 
					                await SendConfirmAsync(
 | 
				
			||||||
                    GetText("warn_punish_list"),
 | 
					                    GetText("warn_punish_list"),
 | 
				
			||||||
                    list).ConfigureAwait(false);
 | 
					                    list).ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -433,7 +433,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
                        if (embed is not null)
 | 
					                        if (embed is not null)
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            var userChannel = await guildUser.GetOrCreateDMChannelAsync();
 | 
					                            var userChannel = await guildUser.GetOrCreateDMChannelAsync();
 | 
				
			||||||
                            await userChannel.EmbedAsync(embed);
 | 
					                            await userChannel.EmbedAsync(embed, _eb);
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    catch
 | 
					                    catch
 | 
				
			||||||
@@ -443,7 +443,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                await _mute.TimedBan(Context.Guild, user, time.Time, ctx.User.ToString() + " | " + msg).ConfigureAwait(false);
 | 
					                await _mute.TimedBan(Context.Guild, user, time.Time, ctx.User.ToString() + " | " + msg).ConfigureAwait(false);
 | 
				
			||||||
                var toSend = new EmbedBuilder().WithOkColor()
 | 
					                var toSend = _eb.Create().WithOkColor()
 | 
				
			||||||
                    .WithTitle("⛔️ " + GetText("banned_user"))
 | 
					                    .WithTitle("⛔️ " + GetText("banned_user"))
 | 
				
			||||||
                    .AddField(GetText("username"), user.ToString(), true)
 | 
					                    .AddField(GetText("username"), user.ToString(), true)
 | 
				
			||||||
                    .AddField("ID", user.Id.ToString(), true)
 | 
					                    .AddField("ID", user.Id.ToString(), true)
 | 
				
			||||||
@@ -470,7 +470,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
                {
 | 
					                {
 | 
				
			||||||
                    await ctx.Guild.AddBanAsync(userId, 7, ctx.User.ToString() + " | " + msg);
 | 
					                    await ctx.Guild.AddBanAsync(userId, 7, ctx.User.ToString() + " | " + msg);
 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
                    await ctx.Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
 | 
					                    await ctx.Channel.EmbedAsync(_eb.Create().WithOkColor()
 | 
				
			||||||
                            .WithTitle("⛔️ " + GetText("banned_user"))
 | 
					                            .WithTitle("⛔️ " + GetText("banned_user"))
 | 
				
			||||||
                            .AddField("ID", userId.ToString(), true))
 | 
					                            .AddField("ID", userId.ToString(), true))
 | 
				
			||||||
                        .ConfigureAwait(false);
 | 
					                        .ConfigureAwait(false);
 | 
				
			||||||
@@ -500,7 +500,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
                    if (embed is not null)
 | 
					                    if (embed is not null)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        var userChannel = await user.GetOrCreateDMChannelAsync();
 | 
					                        var userChannel = await user.GetOrCreateDMChannelAsync();
 | 
				
			||||||
                        await userChannel.EmbedAsync(embed);
 | 
					                        await userChannel.EmbedAsync(embed, _eb);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                catch
 | 
					                catch
 | 
				
			||||||
@@ -510,7 +510,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                await ctx.Guild.AddBanAsync(user, 7, ctx.User.ToString() + " | " + msg).ConfigureAwait(false);
 | 
					                await ctx.Guild.AddBanAsync(user, 7, ctx.User.ToString() + " | " + msg).ConfigureAwait(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var toSend = new EmbedBuilder().WithOkColor()
 | 
					                var toSend = _eb.Create().WithOkColor()
 | 
				
			||||||
                    .WithTitle("⛔️ " + GetText("banned_user"))
 | 
					                    .WithTitle("⛔️ " + GetText("banned_user"))
 | 
				
			||||||
                    .AddField(GetText("username"), user.ToString(), true)
 | 
					                    .AddField(GetText("username"), user.ToString(), true)
 | 
				
			||||||
                    .AddField("ID", user.Id.ToString(), true);
 | 
					                    .AddField("ID", user.Id.ToString(), true);
 | 
				
			||||||
@@ -539,7 +539,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
                        return;
 | 
					                        return;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    await Context.Channel.SendConfirmAsync(template);
 | 
					                    await SendConfirmAsync(template);
 | 
				
			||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
@@ -591,7 +591,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
                {
 | 
					                {
 | 
				
			||||||
                    try
 | 
					                    try
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        await dmChannel.EmbedAsync(crEmbed);
 | 
					                        await dmChannel.EmbedAsync(crEmbed, _eb);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    catch (Exception)
 | 
					                    catch (Exception)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
@@ -677,7 +677,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                try
 | 
					                try
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    await user.SendErrorAsync(GetText("sbdm", Format.Bold(ctx.Guild.Name), msg)).ConfigureAwait(false);
 | 
					                    await user.SendErrorAsync(_eb, GetText("sbdm", Format.Bold(ctx.Guild.Name), msg)).ConfigureAwait(false);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                    catch
 | 
					                    catch
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
@@ -688,7 +688,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
                try { await ctx.Guild.RemoveBanAsync(user).ConfigureAwait(false); }
 | 
					                try { await ctx.Guild.RemoveBanAsync(user).ConfigureAwait(false); }
 | 
				
			||||||
                catch { await ctx.Guild.RemoveBanAsync(user).ConfigureAwait(false); }
 | 
					                catch { await ctx.Guild.RemoveBanAsync(user).ConfigureAwait(false); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var toSend = new EmbedBuilder().WithOkColor()
 | 
					                var toSend = _eb.Create().WithOkColor()
 | 
				
			||||||
                    .WithTitle("☣ " + GetText("sb_user"))
 | 
					                    .WithTitle("☣ " + GetText("sb_user"))
 | 
				
			||||||
                    .AddField(GetText("username"), user.ToString(), true)
 | 
					                    .AddField(GetText("username"), user.ToString(), true)
 | 
				
			||||||
                    .AddField("ID", user.Id.ToString(), true);
 | 
					                    .AddField("ID", user.Id.ToString(), true);
 | 
				
			||||||
@@ -733,7 +733,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                try
 | 
					                try
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    await user.SendErrorAsync(GetText("kickdm", Format.Bold(ctx.Guild.Name), msg))
 | 
					                    await user.SendErrorAsync(_eb, GetText("kickdm", Format.Bold(ctx.Guild.Name), msg))
 | 
				
			||||||
                        .ConfigureAwait(false);
 | 
					                        .ConfigureAwait(false);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                catch
 | 
					                catch
 | 
				
			||||||
@@ -743,7 +743,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
            
 | 
					            
 | 
				
			||||||
                await user.KickAsync(ctx.User.ToString() + " | " + msg).ConfigureAwait(false);
 | 
					                await user.KickAsync(ctx.User.ToString() + " | " + msg).ConfigureAwait(false);
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                var toSend = new EmbedBuilder().WithOkColor()
 | 
					                var toSend = _eb.Create().WithOkColor()
 | 
				
			||||||
                    .WithTitle(GetText("kicked_user"))
 | 
					                    .WithTitle(GetText("kicked_user"))
 | 
				
			||||||
                    .AddField(GetText("username"), user.ToString(), true)
 | 
					                    .AddField(GetText("username"), user.ToString(), true)
 | 
				
			||||||
                    .AddField("ID", user.Id.ToString(), true);
 | 
					                    .AddField("ID", user.Id.ToString(), true);
 | 
				
			||||||
@@ -774,7 +774,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
                    missStr = "-";
 | 
					                    missStr = "-";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                //send a message but don't wait for it
 | 
					                //send a message but don't wait for it
 | 
				
			||||||
                var banningMessageTask = ctx.Channel.EmbedAsync(new EmbedBuilder()
 | 
					                var banningMessageTask = ctx.Channel.EmbedAsync(_eb.Create()
 | 
				
			||||||
                    .WithDescription(GetText("mass_kill_in_progress", bans.Count()))
 | 
					                    .WithDescription(GetText("mass_kill_in_progress", bans.Count()))
 | 
				
			||||||
                    .AddField(GetText("invalid", missing), missStr)
 | 
					                    .AddField(GetText("invalid", missing), missStr)
 | 
				
			||||||
                    .WithOkColor());
 | 
					                    .WithOkColor());
 | 
				
			||||||
@@ -791,7 +791,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
                //wait for the message and edit it
 | 
					                //wait for the message and edit it
 | 
				
			||||||
                var banningMessage = await banningMessageTask.ConfigureAwait(false);
 | 
					                var banningMessage = await banningMessageTask.ConfigureAwait(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                await banningMessage.ModifyAsync(x => x.Embed = new EmbedBuilder()
 | 
					                await banningMessage.ModifyAsync(x => x.Embed = _eb.Create()
 | 
				
			||||||
                    .WithDescription(GetText("mass_kill_completed", bans.Count()))
 | 
					                    .WithDescription(GetText("mass_kill_completed", bans.Count()))
 | 
				
			||||||
                    .AddField(GetText("invalid", missing), missStr)
 | 
					                    .AddField(GetText("invalid", missing), missStr)
 | 
				
			||||||
                    .WithOkColor()
 | 
					                    .WithOkColor()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -83,7 +83,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
                {
 | 
					                {
 | 
				
			||||||
                    text = GetText("no_vcroles");
 | 
					                    text = GetText("no_vcroles");
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                await ctx.Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
 | 
					                await ctx.Channel.EmbedAsync(_eb.Create().WithOkColor()
 | 
				
			||||||
                        .WithTitle(GetText("vc_role_list"))
 | 
					                        .WithTitle(GetText("vc_role_list"))
 | 
				
			||||||
                        .WithDescription(text))
 | 
					                        .WithDescription(text))
 | 
				
			||||||
                    .ConfigureAwait(false);
 | 
					                    .ConfigureAwait(false);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -41,7 +41,7 @@ namespace NadekoBot.Modules.CustomReactions
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            var cr = await _service.AddAsync(ctx.Guild?.Id, key, message);
 | 
					            var cr = await _service.AddAsync(ctx.Guild?.Id, key, message);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            await ctx.Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
 | 
					            await ctx.Channel.EmbedAsync(_eb.Create().WithOkColor()
 | 
				
			||||||
                .WithTitle(GetText("new_cust_react"))
 | 
					                .WithTitle(GetText("new_cust_react"))
 | 
				
			||||||
                .WithDescription($"#{(kwum)cr.Id}")
 | 
					                .WithDescription($"#{(kwum)cr.Id}")
 | 
				
			||||||
                .AddField(GetText("trigger"), key)
 | 
					                .AddField(GetText("trigger"), key)
 | 
				
			||||||
@@ -65,7 +65,7 @@ namespace NadekoBot.Modules.CustomReactions
 | 
				
			|||||||
            var cr = await _service.EditAsync(ctx.Guild?.Id, (int)id, message).ConfigureAwait(false);
 | 
					            var cr = await _service.EditAsync(ctx.Guild?.Id, (int)id, message).ConfigureAwait(false);
 | 
				
			||||||
            if (cr != null)
 | 
					            if (cr != null)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                await ctx.Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
 | 
					                await ctx.Channel.EmbedAsync(_eb.Create().WithOkColor()
 | 
				
			||||||
                    .WithTitle(GetText("edited_cust_react"))
 | 
					                    .WithTitle(GetText("edited_cust_react"))
 | 
				
			||||||
                    .WithDescription($"#{id}")
 | 
					                    .WithDescription($"#{id}")
 | 
				
			||||||
                    .AddField(GetText("trigger"), cr.Trigger)
 | 
					                    .AddField(GetText("trigger"), cr.Trigger)
 | 
				
			||||||
@@ -107,7 +107,7 @@ namespace NadekoBot.Modules.CustomReactions
 | 
				
			|||||||
                                      : " // " + string.Join(" ", cr.GetReactions())))
 | 
					                                      : " // " + string.Join(" ", cr.GetReactions())))
 | 
				
			||||||
                    .JoinWith('\n');
 | 
					                    .JoinWith('\n');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                return new EmbedBuilder().WithOkColor()
 | 
					                return _eb.Create().WithOkColor()
 | 
				
			||||||
                    .WithTitle(GetText("custom_reactions"))
 | 
					                    .WithTitle(GetText("custom_reactions"))
 | 
				
			||||||
                    .WithDescription(desc);
 | 
					                    .WithDescription(desc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -146,7 +146,7 @@ namespace NadekoBot.Modules.CustomReactions
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                await ctx.Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
 | 
					                await ctx.Channel.EmbedAsync(_eb.Create().WithOkColor()
 | 
				
			||||||
                    .WithDescription($"#{id}")
 | 
					                    .WithDescription($"#{id}")
 | 
				
			||||||
                    .AddField(GetText("trigger"), found.Trigger.TrimTo(1024))
 | 
					                    .AddField(GetText("trigger"), found.Trigger.TrimTo(1024))
 | 
				
			||||||
                    .AddField(GetText("response"), (found.Response + "\n```css\n" + found.Response).TrimTo(1020) + "```")
 | 
					                    .AddField(GetText("response"), (found.Response + "\n```css\n" + found.Response).TrimTo(1020) + "```")
 | 
				
			||||||
@@ -167,7 +167,7 @@ namespace NadekoBot.Modules.CustomReactions
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            if (cr != null)
 | 
					            if (cr != null)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                await ctx.Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
 | 
					                await ctx.Channel.EmbedAsync(_eb.Create().WithOkColor()
 | 
				
			||||||
                    .WithTitle(GetText("deleted"))
 | 
					                    .WithTitle(GetText("deleted"))
 | 
				
			||||||
                    .WithDescription($"#{id}")
 | 
					                    .WithDescription($"#{id}")
 | 
				
			||||||
                    .AddField(GetText("trigger"), cr.Trigger.TrimTo(1024))
 | 
					                    .AddField(GetText("trigger"), cr.Trigger.TrimTo(1024))
 | 
				
			||||||
@@ -289,7 +289,7 @@ namespace NadekoBot.Modules.CustomReactions
 | 
				
			|||||||
        [UserPerm(GuildPerm.Administrator)]
 | 
					        [UserPerm(GuildPerm.Administrator)]
 | 
				
			||||||
        public async Task CrClear()
 | 
					        public async Task CrClear()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (await PromptUserConfirmAsync(new EmbedBuilder()
 | 
					            if (await PromptUserConfirmAsync(_eb.Create()
 | 
				
			||||||
                .WithTitle("Custom reaction clear")
 | 
					                .WithTitle("Custom reaction clear")
 | 
				
			||||||
                .WithDescription("This will delete all custom reactions on this server.")).ConfigureAwait(false))
 | 
					                .WithDescription("This will delete all custom reactions on this server.")).ConfigureAwait(false))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,6 +12,7 @@ using System.Linq;
 | 
				
			|||||||
using System.Runtime.CompilerServices;
 | 
					using System.Runtime.CompilerServices;
 | 
				
			||||||
using System.Text.RegularExpressions;
 | 
					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
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -95,7 +96,7 @@ namespace NadekoBot.Modules.CustomReactions.Extensions
 | 
				
			|||||||
                containsAnywhere);
 | 
					                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, bool sanitize)
 | 
					            DiscordSocketClient client, IEmbedBuilderService eb, bool sanitize)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var channel = cr.DmResponse
 | 
					            var channel = cr.DmResponse
 | 
				
			||||||
                ? await ctx.Author.GetOrCreateDMChannelAsync().ConfigureAwait(false)
 | 
					                ? await ctx.Author.GetOrCreateDMChannelAsync().ConfigureAwait(false)
 | 
				
			||||||
@@ -127,7 +128,7 @@ namespace NadekoBot.Modules.CustomReactions.Extensions
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                rep.Replace(crembed);
 | 
					                rep.Replace(crembed);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                return await channel.EmbedAsync(crembed, sanitize).ConfigureAwait(false);
 | 
					                return await channel.EmbedAsync(crembed, eb, sanitize).ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return await channel
 | 
					            return await channel
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -59,11 +59,12 @@ namespace NadekoBot.Modules.CustomReactions.Services
 | 
				
			|||||||
        private readonly GlobalPermissionService _gperm;
 | 
					        private readonly GlobalPermissionService _gperm;
 | 
				
			||||||
        private readonly CmdCdService _cmdCds;
 | 
					        private readonly CmdCdService _cmdCds;
 | 
				
			||||||
        private readonly IPubSub _pubSub;
 | 
					        private readonly IPubSub _pubSub;
 | 
				
			||||||
 | 
					        private readonly IEmbedBuilderService _eb;
 | 
				
			||||||
        private readonly Random _rng;
 | 
					        private readonly Random _rng;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public CustomReactionsService(PermissionService perms, DbService db, IBotStrings strings, Bot bot,
 | 
					        public CustomReactionsService(PermissionService perms, DbService db, IBotStrings strings, Bot bot,
 | 
				
			||||||
            DiscordSocketClient client, CommandHandler cmd, GlobalPermissionService gperm, CmdCdService cmdCds,
 | 
					            DiscordSocketClient client, CommandHandler cmd, GlobalPermissionService gperm, CmdCdService cmdCds,
 | 
				
			||||||
            IPubSub pubSub)
 | 
					            IPubSub pubSub, IEmbedBuilderService eb)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _db = db;
 | 
					            _db = db;
 | 
				
			||||||
            _client = client;
 | 
					            _client = client;
 | 
				
			||||||
@@ -74,6 +75,7 @@ namespace NadekoBot.Modules.CustomReactions.Services
 | 
				
			|||||||
            _gperm = gperm;
 | 
					            _gperm = gperm;
 | 
				
			||||||
            _cmdCds = cmdCds;
 | 
					            _cmdCds = cmdCds;
 | 
				
			||||||
            _pubSub = pubSub;
 | 
					            _pubSub = pubSub;
 | 
				
			||||||
 | 
					            _eb = eb;
 | 
				
			||||||
            _rng = new NadekoRandom();
 | 
					            _rng = new NadekoRandom();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            _pubSub.Sub(_crsReloadedKey, OnCrsShouldReload);
 | 
					            _pubSub.Sub(_crsReloadedKey, OnCrsShouldReload);
 | 
				
			||||||
@@ -414,7 +416,7 @@ namespace NadekoBot.Modules.CustomReactions.Services
 | 
				
			|||||||
                                Format.Bold(pc.Permissions[index].GetCommand(_cmd.GetPrefix(guild), sg)));
 | 
					                                Format.Bold(pc.Permissions[index].GetCommand(_cmd.GetPrefix(guild), sg)));
 | 
				
			||||||
                            try
 | 
					                            try
 | 
				
			||||||
                            {
 | 
					                            {
 | 
				
			||||||
                                await msg.Channel.SendErrorAsync(returnMsg).ConfigureAwait(false);
 | 
					                                await msg.Channel.SendErrorAsync(_eb, returnMsg).ConfigureAwait(false);
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                            catch
 | 
					                            catch
 | 
				
			||||||
                            {
 | 
					                            {
 | 
				
			||||||
@@ -427,7 +429,7 @@ namespace NadekoBot.Modules.CustomReactions.Services
 | 
				
			|||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var sentMsg = await cr.Send(msg, _client, false).ConfigureAwait(false);
 | 
					                var sentMsg = await cr.Send(msg, _client, _eb, false).ConfigureAwait(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var reactions = cr.GetReactions();
 | 
					                var reactions = cr.GetReactions();
 | 
				
			||||||
                foreach (var reaction in reactions)
 | 
					                foreach (var reaction in reactions)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -45,7 +45,7 @@ namespace NadekoBot.Modules.Gambling
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                var ar = new AnimalRace(options, _cs, _gamesConf.Data.RaceAnimals.Shuffle());
 | 
					                var ar = new AnimalRace(options, _cs, _gamesConf.Data.RaceAnimals.Shuffle());
 | 
				
			||||||
                if (!_service.AnimalRaces.TryAdd(ctx.Guild.Id, ar))
 | 
					                if (!_service.AnimalRaces.TryAdd(ctx.Guild.Id, ar))
 | 
				
			||||||
                    return ctx.Channel.SendErrorAsync(GetText("animal_race"), GetText("animal_race_already_started"));
 | 
					                    return SendErrorAsync(GetText("animal_race"), GetText("animal_race_already_started"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                ar.Initialize();
 | 
					                ar.Initialize();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -76,13 +76,13 @@ namespace NadekoBot.Modules.Gambling
 | 
				
			|||||||
                    var winner = race.FinishedUsers[0];
 | 
					                    var winner = race.FinishedUsers[0];
 | 
				
			||||||
                    if (race.FinishedUsers[0].Bet > 0)
 | 
					                    if (race.FinishedUsers[0].Bet > 0)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        return ctx.Channel.SendConfirmAsync(GetText("animal_race"),
 | 
					                        return SendConfirmAsync(GetText("animal_race"),
 | 
				
			||||||
                                            GetText("animal_race_won_money", Format.Bold(winner.Username),
 | 
					                                            GetText("animal_race_won_money", Format.Bold(winner.Username),
 | 
				
			||||||
                                                winner.Animal.Icon, (race.FinishedUsers[0].Bet * (race.Users.Count - 1)) + CurrencySign));
 | 
					                                                winner.Animal.Icon, (race.FinishedUsers[0].Bet * (race.Users.Count - 1)) + CurrencySign));
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    else
 | 
					                    else
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        return ctx.Channel.SendConfirmAsync(GetText("animal_race"),
 | 
					                        return SendConfirmAsync(GetText("animal_race"),
 | 
				
			||||||
                            GetText("animal_race_won", Format.Bold(winner.Username), winner.Animal.Icon));
 | 
					                            GetText("animal_race_won", Format.Bold(winner.Username), winner.Animal.Icon));
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@@ -93,16 +93,16 @@ namespace NadekoBot.Modules.Gambling
 | 
				
			|||||||
                ar.OnStarted += Ar_OnStarted;
 | 
					                ar.OnStarted += Ar_OnStarted;
 | 
				
			||||||
                _client.MessageReceived += _client_MessageReceived;
 | 
					                _client.MessageReceived += _client_MessageReceived;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                return ctx.Channel.SendConfirmAsync(GetText("animal_race"), GetText("animal_race_starting", options.StartTime),
 | 
					                return SendConfirmAsync(GetText("animal_race"), GetText("animal_race_starting", options.StartTime),
 | 
				
			||||||
                                    footer: GetText("animal_race_join_instr", Prefix));
 | 
					                                    footer: GetText("animal_race_join_instr", Prefix));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            private Task Ar_OnStarted(AnimalRace race)
 | 
					            private Task Ar_OnStarted(AnimalRace race)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                if (race.Users.Count == race.MaxUsers)
 | 
					                if (race.Users.Count == race.MaxUsers)
 | 
				
			||||||
                    return ctx.Channel.SendConfirmAsync(GetText("animal_race"), GetText("animal_race_full"));
 | 
					                    return SendConfirmAsync(GetText("animal_race"), GetText("animal_race_full"));
 | 
				
			||||||
                else
 | 
					                else
 | 
				
			||||||
                    return ctx.Channel.SendConfirmAsync(GetText("animal_race"), GetText("animal_race_starting_with_x", race.Users.Count));
 | 
					                    return SendConfirmAsync(GetText("animal_race"), GetText("animal_race_starting_with_x", race.Users.Count));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            private async Task Ar_OnStateUpdate(AnimalRace race)
 | 
					            private async Task Ar_OnStateUpdate(AnimalRace race)
 | 
				
			||||||
@@ -119,10 +119,10 @@ namespace NadekoBot.Modules.Gambling
 | 
				
			|||||||
                var msg = raceMessage;
 | 
					                var msg = raceMessage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (msg is null)
 | 
					                if (msg is null)
 | 
				
			||||||
                    raceMessage = await ctx.Channel.SendConfirmAsync(text)
 | 
					                    raceMessage = await SendConfirmAsync(text)
 | 
				
			||||||
                        .ConfigureAwait(false);
 | 
					                        .ConfigureAwait(false);
 | 
				
			||||||
                else
 | 
					                else
 | 
				
			||||||
                    await msg.ModifyAsync(x => x.Embed = new EmbedBuilder()
 | 
					                    await msg.ModifyAsync(x => x.Embed = _eb.Create()
 | 
				
			||||||
                        .WithTitle(GetText("animal_race"))
 | 
					                        .WithTitle(GetText("animal_race"))
 | 
				
			||||||
                        .WithDescription(text)
 | 
					                        .WithDescription(text)
 | 
				
			||||||
                        .WithOkColor()
 | 
					                        .WithOkColor()
 | 
				
			||||||
@@ -153,9 +153,9 @@ namespace NadekoBot.Modules.Gambling
 | 
				
			|||||||
                    var user = await ar.JoinRace(ctx.User.Id, ctx.User.ToString(), amount)
 | 
					                    var user = await ar.JoinRace(ctx.User.Id, ctx.User.ToString(), amount)
 | 
				
			||||||
                        .ConfigureAwait(false);
 | 
					                        .ConfigureAwait(false);
 | 
				
			||||||
                    if (amount > 0)
 | 
					                    if (amount > 0)
 | 
				
			||||||
                        await ctx.Channel.SendConfirmAsync(GetText("animal_race_join_bet", ctx.User.Mention, user.Animal.Icon, amount + CurrencySign)).ConfigureAwait(false);
 | 
					                        await SendConfirmAsync(GetText("animal_race_join_bet", ctx.User.Mention, user.Animal.Icon, amount + CurrencySign)).ConfigureAwait(false);
 | 
				
			||||||
                    else
 | 
					                    else
 | 
				
			||||||
                        await ctx.Channel.SendConfirmAsync(GetText("animal_race_join", ctx.User.Mention, user.Animal.Icon)).ConfigureAwait(false);
 | 
					                        await SendConfirmAsync(GetText("animal_race_join", ctx.User.Mention, user.Animal.Icon)).ConfigureAwait(false);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                catch (ArgumentOutOfRangeException)
 | 
					                catch (ArgumentOutOfRangeException)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
@@ -171,12 +171,12 @@ namespace NadekoBot.Modules.Gambling
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
                catch (AnimalRaceFullException)
 | 
					                catch (AnimalRaceFullException)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    await ctx.Channel.SendConfirmAsync(GetText("animal_race"), GetText("animal_race_full"))
 | 
					                    await SendConfirmAsync(GetText("animal_race"), GetText("animal_race_full"))
 | 
				
			||||||
                        .ConfigureAwait(false);
 | 
					                        .ConfigureAwait(false);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                catch (NotEnoughFundsException)
 | 
					                catch (NotEnoughFundsException)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    await ctx.Channel.SendErrorAsync(GetText("not_enough", CurrencySign)).ConfigureAwait(false);
 | 
					                    await SendErrorAsync(GetText("not_enough", CurrencySign)).ConfigureAwait(false);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -100,7 +100,7 @@ namespace NadekoBot.Modules.Gambling
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                    var cStr = string.Concat(c.Select(x => x.Substring(0, x.Length - 1) + " "));
 | 
					                    var cStr = string.Concat(c.Select(x => x.Substring(0, x.Length - 1) + " "));
 | 
				
			||||||
                    cStr += "\n" + string.Concat(c.Select(x => x.Last() + " "));
 | 
					                    cStr += "\n" + string.Concat(c.Select(x => x.Last() + " "));
 | 
				
			||||||
                    var embed = new EmbedBuilder()
 | 
					                    var embed = _eb.Create()
 | 
				
			||||||
                        .WithOkColor()
 | 
					                        .WithOkColor()
 | 
				
			||||||
                        .WithTitle("BlackJack")
 | 
					                        .WithTitle("BlackJack")
 | 
				
			||||||
                        .AddField($"{dealerIcon} Dealer's Hand | Value: {bj.Dealer.GetHandValue()}", cStr);
 | 
					                        .AddField($"{dealerIcon} Dealer's Hand | Value: {bj.Dealer.GetHandValue()}", cStr);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,7 +27,7 @@ namespace NadekoBot.Modules.Gambling.Common.Events
 | 
				
			|||||||
        public bool Stopped { get; private set; }
 | 
					        public bool Stopped { get; private set; }
 | 
				
			||||||
        public bool PotEmptied { get; private set; } = false;
 | 
					        public bool PotEmptied { get; private set; } = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private readonly Func<CurrencyEvent.Type, EventOptions, long, EmbedBuilder> _embedFunc;
 | 
					        private readonly Func<CurrencyEvent.Type, EventOptions, long, IEmbedBuilder> _embedFunc;
 | 
				
			||||||
        private readonly bool _isPotLimited;
 | 
					        private readonly bool _isPotLimited;
 | 
				
			||||||
        private readonly ITextChannel _channel;
 | 
					        private readonly ITextChannel _channel;
 | 
				
			||||||
        private readonly ConcurrentHashSet<ulong> _awardedUsers = new ConcurrentHashSet<ulong>();
 | 
					        private readonly ConcurrentHashSet<ulong> _awardedUsers = new ConcurrentHashSet<ulong>();
 | 
				
			||||||
@@ -47,7 +47,7 @@ namespace NadekoBot.Modules.Gambling.Common.Events
 | 
				
			|||||||
            .ToArray();
 | 
					            .ToArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public GameStatusEvent(DiscordSocketClient client, ICurrencyService cs,SocketGuild g, ITextChannel ch,
 | 
					        public GameStatusEvent(DiscordSocketClient client, ICurrencyService cs,SocketGuild g, ITextChannel ch,
 | 
				
			||||||
            EventOptions opt, Func<CurrencyEvent.Type, EventOptions, long, EmbedBuilder> embedFunc)
 | 
					            EventOptions opt, Func<CurrencyEvent.Type, EventOptions, long, IEmbedBuilder> embedFunc)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _client = client;
 | 
					            _client = client;
 | 
				
			||||||
            _guild = g;
 | 
					            _guild = g;
 | 
				
			||||||
@@ -126,7 +126,7 @@ namespace NadekoBot.Modules.Gambling.Common.Events
 | 
				
			|||||||
            _t.Change(TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(2));
 | 
					            _t.Change(TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(2));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private EmbedBuilder GetEmbed(long pot)
 | 
					        private IEmbedBuilder GetEmbed(long pot)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return _embedFunc(CurrencyEvent.Type.GameStatus, _opts, pot);
 | 
					            return _embedFunc(CurrencyEvent.Type.GameStatus, _opts, pot);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,7 +29,7 @@ namespace NadekoBot.Modules.Gambling.Common.Events
 | 
				
			|||||||
        public bool Stopped { get; private set; }
 | 
					        public bool Stopped { get; private set; }
 | 
				
			||||||
        public bool PotEmptied { get; private set; } = false;
 | 
					        public bool PotEmptied { get; private set; } = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private readonly Func<CurrencyEvent.Type, EventOptions, long, EmbedBuilder> _embedFunc;
 | 
					        private readonly Func<CurrencyEvent.Type, EventOptions, long, IEmbedBuilder> _embedFunc;
 | 
				
			||||||
        private readonly bool _isPotLimited;
 | 
					        private readonly bool _isPotLimited;
 | 
				
			||||||
        private readonly ITextChannel _channel;
 | 
					        private readonly ITextChannel _channel;
 | 
				
			||||||
        private readonly ConcurrentHashSet<ulong> _awardedUsers = new ConcurrentHashSet<ulong>();
 | 
					        private readonly ConcurrentHashSet<ulong> _awardedUsers = new ConcurrentHashSet<ulong>();
 | 
				
			||||||
@@ -44,7 +44,7 @@ namespace NadekoBot.Modules.Gambling.Common.Events
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        public ReactionEvent(DiscordSocketClient client, ICurrencyService cs,
 | 
					        public ReactionEvent(DiscordSocketClient client, ICurrencyService cs,
 | 
				
			||||||
            SocketGuild g, ITextChannel ch, EventOptions opt, GamblingConfig config,
 | 
					            SocketGuild g, ITextChannel ch, EventOptions opt, GamblingConfig config,
 | 
				
			||||||
            Func<CurrencyEvent.Type, EventOptions, long, EmbedBuilder> embedFunc)
 | 
					            Func<CurrencyEvent.Type, EventOptions, long, IEmbedBuilder> embedFunc)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _client = client;
 | 
					            _client = client;
 | 
				
			||||||
            _guild = g;
 | 
					            _guild = g;
 | 
				
			||||||
@@ -130,7 +130,7 @@ namespace NadekoBot.Modules.Gambling.Common.Events
 | 
				
			|||||||
            _t.Change(TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(2));
 | 
					            _t.Change(TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(2));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private EmbedBuilder GetEmbed(long pot)
 | 
					        private IEmbedBuilder GetEmbed(long pot)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return _embedFunc(CurrencyEvent.Type.Reaction, _opts, pot);
 | 
					            return _embedFunc(CurrencyEvent.Type.Reaction, _opts, pot);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -138,7 +138,7 @@ namespace NadekoBot.Modules.Gambling
 | 
				
			|||||||
                    else
 | 
					                    else
 | 
				
			||||||
                        title = GetText("connect4_draw");
 | 
					                        title = GetText("connect4_draw");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    return msg.ModifyAsync(x => x.Embed = new EmbedBuilder()
 | 
					                    return msg.ModifyAsync(x => x.Embed = _eb.Create()
 | 
				
			||||||
                        .WithTitle(title)
 | 
					                        .WithTitle(title)
 | 
				
			||||||
                        .WithDescription(GetGameStateText(game))
 | 
					                        .WithDescription(GetGameStateText(game))
 | 
				
			||||||
                        .WithOkColor()
 | 
					                        .WithOkColor()
 | 
				
			||||||
@@ -162,7 +162,7 @@ namespace NadekoBot.Modules.Gambling
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            private async Task Game_OnGameStateUpdated(Connect4Game game)
 | 
					            private async Task Game_OnGameStateUpdated(Connect4Game game)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var embed = new EmbedBuilder()
 | 
					                var embed = _eb.Create()
 | 
				
			||||||
                    .WithTitle($"{game.CurrentPlayer.Username} vs {game.OtherPlayer.Username}")
 | 
					                    .WithTitle($"{game.CurrentPlayer.Username} vs {game.OtherPlayer.Username}")
 | 
				
			||||||
                    .WithDescription(GetGameStateText(game))
 | 
					                    .WithDescription(GetGameStateText(game))
 | 
				
			||||||
                    .WithOkColor();
 | 
					                    .WithOkColor();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -45,18 +45,18 @@ namespace NadekoBot.Modules.Gambling
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            private EmbedBuilder GetEmbed(CurrencyEvent.Type type, EventOptions opts, long currentPot)
 | 
					            private IEmbedBuilder GetEmbed(CurrencyEvent.Type type, EventOptions opts, long currentPot)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                switch (type)
 | 
					                switch (type)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    case CurrencyEvent.Type.Reaction:
 | 
					                    case CurrencyEvent.Type.Reaction:
 | 
				
			||||||
                        return new EmbedBuilder()
 | 
					                        return _eb.Create()
 | 
				
			||||||
                            .WithOkColor()
 | 
					                            .WithOkColor()
 | 
				
			||||||
                            .WithTitle(GetText("event_title", type.ToString()))
 | 
					                            .WithTitle(GetText("event_title", type.ToString()))
 | 
				
			||||||
                            .WithDescription(GetReactionDescription(opts.Amount, currentPot))
 | 
					                            .WithDescription(GetReactionDescription(opts.Amount, currentPot))
 | 
				
			||||||
                            .WithFooter(GetText("event_duration_footer", opts.Hours));
 | 
					                            .WithFooter(GetText("event_duration_footer", opts.Hours));
 | 
				
			||||||
                    case CurrencyEvent.Type.GameStatus:
 | 
					                    case CurrencyEvent.Type.GameStatus:
 | 
				
			||||||
                        return new EmbedBuilder()
 | 
					                        return _eb.Create()
 | 
				
			||||||
                            .WithOkColor()
 | 
					                            .WithOkColor()
 | 
				
			||||||
                            .WithTitle(GetText("event_title", type.ToString()))
 | 
					                            .WithTitle(GetText("event_title", type.ToString()))
 | 
				
			||||||
                            .WithDescription(GetGameStatusDescription(opts.Amount, currentPot))
 | 
					                            .WithDescription(GetGameStatusDescription(opts.Amount, currentPot))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,7 +35,7 @@ namespace NadekoBot.Modules.Gambling
 | 
				
			|||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                async Task OnEnded(IUser arg, long won)
 | 
					                async Task OnEnded(IUser arg, long won)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    await ctx.Channel.SendConfirmAsync(GetText("rafflecur_ended", CurrencyName, Format.Bold(arg.ToString()), won + CurrencySign)).ConfigureAwait(false);
 | 
					                    await SendConfirmAsync(GetText("rafflecur_ended", CurrencyName, Format.Bold(arg.ToString()), won + CurrencySign)).ConfigureAwait(false);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                var res = await _service.JoinOrCreateGame(ctx.Channel.Id,
 | 
					                var res = await _service.JoinOrCreateGame(ctx.Channel.Id,
 | 
				
			||||||
                    ctx.User, amount, mixed, OnEnded)
 | 
					                    ctx.User, amount, mixed, OnEnded)
 | 
				
			||||||
@@ -43,7 +43,7 @@ namespace NadekoBot.Modules.Gambling
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                if (res.Item1 != null)
 | 
					                if (res.Item1 != null)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    await ctx.Channel.SendConfirmAsync(GetText("rafflecur", res.Item1.GameType.ToString()),
 | 
					                    await SendConfirmAsync(GetText("rafflecur", res.Item1.GameType.ToString()),
 | 
				
			||||||
                        string.Join("\n", res.Item1.Users.Select(x => $"{x.DiscordUser} ({x.Amount})")),
 | 
					                        string.Join("\n", res.Item1.Users.Select(x => $"{x.DiscordUser} ({x.Amount})")),
 | 
				
			||||||
                        footer: GetText("rafflecur_joined", ctx.User.ToString())).ConfigureAwait(false);
 | 
					                        footer: GetText("rafflecur_joined", ctx.User.ToString())).ConfigureAwait(false);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -150,9 +150,11 @@ namespace NadekoBot.Modules.Gambling
 | 
				
			|||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        rolls.Add(_fateRolls[rng.Next(0, _fateRolls.Length)]);
 | 
					                        rolls.Add(_fateRolls[rng.Next(0, _fateRolls.Length)]);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    var embed = new EmbedBuilder().WithOkColor().WithDescription(ctx.User.Mention + " " + GetText("dice_rolled_num", Format.Bold(n1.ToString())))
 | 
					                    var embed = _eb.Create()
 | 
				
			||||||
                        .AddField(efb => efb.WithName(Format.Bold("Result"))
 | 
					                        .WithOkColor()
 | 
				
			||||||
                            .WithValue(string.Join(" ", rolls.Select(c => Format.Code($"[{c}]")))));
 | 
					                        .WithDescription(ctx.User.Mention + " " + GetText("dice_rolled_num", Format.Bold(n1.ToString())))
 | 
				
			||||||
 | 
					                        .AddField(Format.Bold("Result"), string.Join(" ", rolls.Select(c => Format.Code($"[{c}]"))));
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
                    await ctx.Channel.EmbedAsync(embed).ConfigureAwait(false);
 | 
					                    await ctx.Channel.EmbedAsync(embed).ConfigureAwait(false);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else if ((match = dndRegex.Match(arg)).Length != 0)
 | 
					                else if ((match = dndRegex.Match(arg)).Length != 0)
 | 
				
			||||||
@@ -174,11 +176,13 @@ namespace NadekoBot.Modules.Gambling
 | 
				
			|||||||
                        }
 | 
					                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        var sum = arr.Sum();
 | 
					                        var sum = arr.Sum();
 | 
				
			||||||
                        var embed = new EmbedBuilder().WithOkColor().WithDescription(ctx.User.Mention + " " + GetText("dice_rolled_num", n1) + $"`1 - {n2}`")
 | 
					                        var embed = _eb.Create().WithOkColor()
 | 
				
			||||||
                        .AddField(efb => efb.WithName(Format.Bold("Rolls"))
 | 
					                            .WithDescription(ctx.User.Mention + " " + GetText("dice_rolled_num", n1) + $"`1 - {n2}`")
 | 
				
			||||||
                            .WithValue(string.Join(" ", (ordered ? arr.OrderBy(x => x).AsEnumerable() : arr).Select(x => Format.Code(x.ToString())))))
 | 
					                            .AddField(Format.Bold("Rolls"), string.Join(" ",
 | 
				
			||||||
                        .AddField(efb => efb.WithName(Format.Bold("Sum"))
 | 
					                                (ordered ? arr.OrderBy(x => x).AsEnumerable() : arr).Select(x =>
 | 
				
			||||||
                            .WithValue(sum + " + " + add + " - " + sub + " = " + (sum + add - sub)));
 | 
					                                    Format.Code(x.ToString()))))
 | 
				
			||||||
 | 
					                            .AddField(Format.Bold("Sum"),
 | 
				
			||||||
 | 
					                                sum + " + " + add + " - " + sub + " = " + (sum + add - sub));
 | 
				
			||||||
                        await ctx.Channel.EmbedAsync(embed).ConfigureAwait(false);
 | 
					                        await ctx.Channel.EmbedAsync(embed).ConfigureAwait(false);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -123,7 +123,7 @@ namespace NadekoBot.Modules.Gambling
 | 
				
			|||||||
                    str = ctx.User.ToString() + " " + GetText("better_luck");
 | 
					                    str = ctx.User.ToString() + " " + GetText("better_luck");
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                await ctx.Channel.EmbedAsync(new EmbedBuilder()
 | 
					                await ctx.Channel.EmbedAsync(_eb.Create()
 | 
				
			||||||
                    .WithDescription(str)
 | 
					                    .WithDescription(str)
 | 
				
			||||||
                    .WithOkColor()
 | 
					                    .WithOkColor()
 | 
				
			||||||
                    .WithImageUrl(imageToSend.ToString())).ConfigureAwait(false);
 | 
					                    .WithImageUrl(imageToSend.ToString())).ConfigureAwait(false);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -64,7 +64,7 @@ namespace NadekoBot.Modules.Gambling
 | 
				
			|||||||
                onePercent = ec.OnePercent / (ec.Cash-ec.Bot); // This stops the top 1% from owning more than 100% of the money
 | 
					                onePercent = ec.OnePercent / (ec.Cash-ec.Bot); // This stops the top 1% from owning more than 100% of the money
 | 
				
			||||||
                // [21:03] Bob Page: Kinda remids me of US economy
 | 
					                // [21:03] Bob Page: Kinda remids me of US economy
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            var embed = new EmbedBuilder()
 | 
					            var embed = _eb.Create()
 | 
				
			||||||
                .WithTitle(GetText("economy_state"))
 | 
					                .WithTitle(GetText("economy_state"))
 | 
				
			||||||
                .AddField(GetText("currency_owned"), ((BigInteger)(ec.Cash - ec.Bot)) + CurrencySign)
 | 
					                .AddField(GetText("currency_owned"), ((BigInteger)(ec.Cash - ec.Bot)) + CurrencySign)
 | 
				
			||||||
                .AddField(GetText("currency_one_percent"), (onePercent * 100).ToString("F2") + "%")
 | 
					                .AddField(GetText("currency_one_percent"), (onePercent * 100).ToString("F2") + "%")
 | 
				
			||||||
@@ -140,7 +140,7 @@ namespace NadekoBot.Modules.Gambling
 | 
				
			|||||||
                return;
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            var usr = membersArray[new NadekoRandom().Next(0, membersArray.Length)];
 | 
					            var usr = membersArray[new NadekoRandom().Next(0, membersArray.Length)];
 | 
				
			||||||
            await ctx.Channel.SendConfirmAsync("🎟 " + GetText("raffled_user"), $"**{usr.Username}#{usr.Discriminator}**", footer: $"ID: {usr.Id}").ConfigureAwait(false);
 | 
					            await SendConfirmAsync("🎟 " + GetText("raffled_user"), $"**{usr.Username}#{usr.Discriminator}**", footer: $"ID: {usr.Id}").ConfigureAwait(false);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [NadekoCommand, Aliases]
 | 
					        [NadekoCommand, Aliases]
 | 
				
			||||||
@@ -156,7 +156,7 @@ namespace NadekoBot.Modules.Gambling
 | 
				
			|||||||
                return;
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            var usr = membersArray[new NadekoRandom().Next(0, membersArray.Length)];
 | 
					            var usr = membersArray[new NadekoRandom().Next(0, membersArray.Length)];
 | 
				
			||||||
            await ctx.Channel.SendConfirmAsync("🎟 " + GetText("raffled_user"), $"**{usr.Username}#{usr.Discriminator}**", footer: $"ID: {usr.Id}").ConfigureAwait(false);
 | 
					            await SendConfirmAsync("🎟 " + GetText("raffled_user"), $"**{usr.Username}#{usr.Discriminator}**", footer: $"ID: {usr.Id}").ConfigureAwait(false);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [NadekoCommand, Aliases]
 | 
					        [NadekoCommand, Aliases]
 | 
				
			||||||
@@ -195,7 +195,7 @@ namespace NadekoBot.Modules.Gambling
 | 
				
			|||||||
                trs = uow.CurrencyTransactions.GetPageFor(userId, page);
 | 
					                trs = uow.CurrencyTransactions.GetPageFor(userId, page);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var embed = new EmbedBuilder()
 | 
					            var embed = _eb.Create()
 | 
				
			||||||
                .WithTitle(GetText("transactions",
 | 
					                .WithTitle(GetText("transactions",
 | 
				
			||||||
                    ((SocketGuild)ctx.Guild)?.GetUser(userId)?.ToString() ?? $"{userId}"))
 | 
					                    ((SocketGuild)ctx.Guild)?.GetUser(userId)?.ToString() ?? $"{userId}"))
 | 
				
			||||||
                .WithOkColor();
 | 
					                .WithOkColor();
 | 
				
			||||||
@@ -373,10 +373,12 @@ namespace NadekoBot.Modules.Gambling
 | 
				
			|||||||
            if (amount <= 0)
 | 
					            if (amount <= 0)
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var embed = new EmbedBuilder()
 | 
					            var embed = _eb.Create()
 | 
				
			||||||
                    .WithOkColor()
 | 
					                    .WithOkColor()
 | 
				
			||||||
                    .WithTitle(GetText("roll_duel"));
 | 
					                    .WithTitle(GetText("roll_duel"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var description = string.Empty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var game = new RollDuelGame(_cs, _client.CurrentUser.Id, ctx.User.Id, u.Id, amount);
 | 
					            var game = new RollDuelGame(_cs, _client.CurrentUser.Id, ctx.User.Id, u.Id, amount);
 | 
				
			||||||
            //means challenge is just created
 | 
					            //means challenge is just created
 | 
				
			||||||
            if (_service.Duels.TryGetValue((ctx.User.Id, u.Id), out var other))
 | 
					            if (_service.Duels.TryGetValue((ctx.User.Id, u.Id), out var other))
 | 
				
			||||||
@@ -406,10 +408,11 @@ namespace NadekoBot.Modules.Gambling
 | 
				
			|||||||
            async Task Game_OnGameTick(RollDuelGame arg)
 | 
					            async Task Game_OnGameTick(RollDuelGame arg)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var rolls = arg.Rolls.Last();
 | 
					                var rolls = arg.Rolls.Last();
 | 
				
			||||||
                embed.Description += $@"{Format.Bold(ctx.User.ToString())} rolled **{rolls.Item1}**
 | 
					                description += $@"{Format.Bold(ctx.User.ToString())} rolled **{rolls.Item1}**
 | 
				
			||||||
{Format.Bold(u.ToString())} rolled **{rolls.Item2}**
 | 
					{Format.Bold(u.ToString())} rolled **{rolls.Item2}**
 | 
				
			||||||
--
 | 
					--
 | 
				
			||||||
";
 | 
					";
 | 
				
			||||||
 | 
					                embed = embed.WithDescription(description);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (rdMsg is null)
 | 
					                if (rdMsg is null)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
@@ -434,7 +437,10 @@ namespace NadekoBot.Modules.Gambling
 | 
				
			|||||||
                        var winner = rdGame.Winner == rdGame.P1
 | 
					                        var winner = rdGame.Winner == rdGame.P1
 | 
				
			||||||
                            ? ctx.User
 | 
					                            ? ctx.User
 | 
				
			||||||
                            : u;
 | 
					                            : u;
 | 
				
			||||||
                        embed.Description += $"\n**{winner}** Won {n(((long)(rdGame.Amount * 2 * 0.98))) + CurrencySign}";
 | 
					                        description += $"\n**{winner}** Won {n(((long)(rdGame.Amount * 2 * 0.98))) + CurrencySign}";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        embed = embed.WithDescription(description);
 | 
				
			||||||
 | 
					                        
 | 
				
			||||||
                        await rdMsg.ModifyAsync(x => x.Embed = embed.Build())
 | 
					                        await rdMsg.ModifyAsync(x => x.Embed = embed.Build())
 | 
				
			||||||
                            .ConfigureAwait(false);
 | 
					                            .ConfigureAwait(false);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
@@ -485,7 +491,7 @@ namespace NadekoBot.Modules.Gambling
 | 
				
			|||||||
                str += GetText("better_luck");
 | 
					                str += GetText("better_luck");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            await ctx.Channel.SendConfirmAsync(str).ConfigureAwait(false);
 | 
					            await SendConfirmAsync(str).ConfigureAwait(false);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [NadekoCommand, Aliases]
 | 
					        [NadekoCommand, Aliases]
 | 
				
			||||||
@@ -541,7 +547,7 @@ namespace NadekoBot.Modules.Gambling
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            await Context.SendPaginatedConfirmAsync(page, curPage =>
 | 
					            await Context.SendPaginatedConfirmAsync(page, curPage =>
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var embed = new EmbedBuilder()
 | 
					                var embed = _eb.Create()
 | 
				
			||||||
                   .WithOkColor()
 | 
					                   .WithOkColor()
 | 
				
			||||||
                   .WithTitle(CurrencySign + " " + GetText("leaderboard"));
 | 
					                   .WithTitle(CurrencySign + " " + GetText("leaderboard"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -615,7 +621,7 @@ namespace NadekoBot.Modules.Gambling
 | 
				
			|||||||
                        return "✂️";
 | 
					                        return "✂️";
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            var embed = new EmbedBuilder();
 | 
					            var embed = _eb.Create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var nadekoPick = (RpsPick)new NadekoRandom().Next(0, 3);
 | 
					            var nadekoPick = (RpsPick)new NadekoRandom().Next(0, 3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -88,7 +88,7 @@ namespace NadekoBot.Modules.Gambling.Services
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public async Task<bool> TryCreateEventAsync(ulong guildId, ulong channelId, CurrencyEvent.Type type,
 | 
					        public async Task<bool> TryCreateEventAsync(ulong guildId, ulong channelId, CurrencyEvent.Type type,
 | 
				
			||||||
            EventOptions opts, Func<CurrencyEvent.Type, EventOptions, long, EmbedBuilder> embed)
 | 
					            EventOptions opts, Func<CurrencyEvent.Type, EventOptions, long, IEmbedBuilder> embed)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            SocketGuild g = _client.GetGuild(guildId);
 | 
					            SocketGuild g = _client.GetGuild(guildId);
 | 
				
			||||||
            SocketTextChannel ch = g?.GetChannel(channelId) as SocketTextChannel;
 | 
					            SocketTextChannel ch = g?.GetChannel(channelId) as SocketTextChannel;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -59,9 +59,9 @@ namespace NadekoBot.Modules.Gambling
 | 
				
			|||||||
                    var theseEntries = entries.Skip(curPage * 9).Take(9).ToArray();
 | 
					                    var theseEntries = entries.Skip(curPage * 9).Take(9).ToArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if (!theseEntries.Any())
 | 
					                    if (!theseEntries.Any())
 | 
				
			||||||
                        return new EmbedBuilder().WithErrorColor()
 | 
					                        return _eb.Create().WithErrorColor()
 | 
				
			||||||
                            .WithDescription(GetText("shop_none"));
 | 
					                            .WithDescription(GetText("shop_none"));
 | 
				
			||||||
                    var embed = new EmbedBuilder().WithOkColor()
 | 
					                    var embed = _eb.Create().WithOkColor()
 | 
				
			||||||
                        .WithTitle(GetText("shop", CurrencySign));
 | 
					                        .WithTitle(GetText("shop", CurrencySign));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    for (int i = 0; i < theseEntries.Length; i++)
 | 
					                    for (int i = 0; i < theseEntries.Length; i++)
 | 
				
			||||||
@@ -172,7 +172,7 @@ namespace NadekoBot.Modules.Gambling
 | 
				
			|||||||
                        try
 | 
					                        try
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            await (await ctx.User.GetOrCreateDMChannelAsync().ConfigureAwait(false))
 | 
					                            await (await ctx.User.GetOrCreateDMChannelAsync().ConfigureAwait(false))
 | 
				
			||||||
                                .EmbedAsync(new EmbedBuilder().WithOkColor()
 | 
					                                .EmbedAsync(_eb.Create().WithOkColor()
 | 
				
			||||||
                                .WithTitle(GetText("shop_purchase", ctx.Guild.Name))
 | 
					                                .WithTitle(GetText("shop_purchase", ctx.Guild.Name))
 | 
				
			||||||
                                .AddField(GetText("item"), item.Text, false)
 | 
					                                .AddField(GetText("item"), item.Text, false)
 | 
				
			||||||
                                .AddField(GetText("price"), entry.Price.ToString(), true)
 | 
					                                .AddField(GetText("price"), entry.Price.ToString(), true)
 | 
				
			||||||
@@ -428,9 +428,9 @@ namespace NadekoBot.Modules.Gambling
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            public EmbedBuilder EntryToEmbed(ShopEntry entry)
 | 
					            public IEmbedBuilder EntryToEmbed(ShopEntry entry)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var embed = new EmbedBuilder().WithOkColor();
 | 
					                var embed = _eb.Create().WithOkColor();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (entry.Type == ShopEntryType.Role)
 | 
					                if (entry.Type == ShopEntryType.Role)
 | 
				
			||||||
                    return embed.AddField(GetText("name"), GetText("shop_role", Format.Bold(ctx.Guild.GetRole(entry.RoleId)?.Name ?? "MISSING_ROLE")), true)
 | 
					                    return embed.AddField(GetText("name"), GetText("shop_role", Format.Bold(ctx.Guild.GetRole(entry.RoleId)?.Name ?? "MISSING_ROLE")), true)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -98,7 +98,7 @@ namespace NadekoBot.Modules.Gambling
 | 
				
			|||||||
                if (bet <= 0)
 | 
					                if (bet <= 0)
 | 
				
			||||||
                    bet = 1;
 | 
					                    bet = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var embed = new EmbedBuilder()
 | 
					                var embed = _eb.Create()
 | 
				
			||||||
                    .WithOkColor()
 | 
					                    .WithOkColor()
 | 
				
			||||||
                    .WithTitle("Slot Stats")
 | 
					                    .WithTitle("Slot Stats")
 | 
				
			||||||
                    .AddField("Total Bet", bet.ToString(), true)
 | 
					                    .AddField("Total Bet", bet.ToString(), true)
 | 
				
			||||||
@@ -133,7 +133,7 @@ namespace NadekoBot.Modules.Gambling
 | 
				
			|||||||
                    sb.AppendLine($"x{key} occured {dict[key]} times. {dict[key] * 1.0f / tests * 100}%");
 | 
					                    sb.AppendLine($"x{key} occured {dict[key]} times. {dict[key] * 1.0f / tests * 100}%");
 | 
				
			||||||
                    payout += key * dict[key];
 | 
					                    payout += key * dict[key];
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                await ctx.Channel.SendConfirmAsync("Slot Test Results", sb.ToString(),
 | 
					                await SendConfirmAsync("Slot Test Results", sb.ToString(),
 | 
				
			||||||
                    footer: $"Total Bet: {tests * bet} | Payout: {payout * bet} | {payout * 1.0f / tests * 100}%").ConfigureAwait(false);
 | 
					                    footer: $"Total Bet: {tests * bet} | Payout: {payout * bet} | {payout * 1.0f / tests * 100}%").ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,7 +25,7 @@ namespace NadekoBot.Modules.Gambling
 | 
				
			|||||||
            public async Task WaifuReset()
 | 
					            public async Task WaifuReset()
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var price = _service.GetResetPrice(ctx.User);
 | 
					                var price = _service.GetResetPrice(ctx.User);
 | 
				
			||||||
                var embed = new EmbedBuilder()
 | 
					                var embed = _eb.Create()
 | 
				
			||||||
                        .WithTitle(GetText("waifu_reset_confirm"))
 | 
					                        .WithTitle(GetText("waifu_reset_confirm"))
 | 
				
			||||||
                        .WithDescription(GetText("waifu_reset_price", Format.Bold(price + CurrencySign)));
 | 
					                        .WithDescription(GetText("waifu_reset_price", Format.Bold(price + CurrencySign)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -75,7 +75,7 @@ namespace NadekoBot.Modules.Gambling
 | 
				
			|||||||
                    msg += "\n" + GetText("waifu_fulfilled", target, w.Price + CurrencySign);
 | 
					                    msg += "\n" + GetText("waifu_fulfilled", target, w.Price + CurrencySign);
 | 
				
			||||||
                else
 | 
					                else
 | 
				
			||||||
                    msg = " " + msg;
 | 
					                    msg = " " + msg;
 | 
				
			||||||
                await ctx.Channel.SendConfirmAsync(ctx.User.Mention + msg);
 | 
					                await SendConfirmAsync(ctx.User.Mention + msg);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            [NadekoCommand, Aliases]
 | 
					            [NadekoCommand, Aliases]
 | 
				
			||||||
@@ -221,7 +221,7 @@ namespace NadekoBot.Modules.Gambling
 | 
				
			|||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var embed = new EmbedBuilder()
 | 
					                var embed = _eb.Create()
 | 
				
			||||||
                    .WithTitle(GetText("waifus_top_waifus"))
 | 
					                    .WithTitle(GetText("waifus_top_waifus"))
 | 
				
			||||||
                    .WithOkColor();
 | 
					                    .WithOkColor();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -282,7 +282,7 @@ namespace NadekoBot.Modules.Gambling
 | 
				
			|||||||
                if (string.IsNullOrWhiteSpace(fansStr))
 | 
					                if (string.IsNullOrWhiteSpace(fansStr))
 | 
				
			||||||
                    fansStr = "-";
 | 
					                    fansStr = "-";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var embed = new EmbedBuilder()
 | 
					                var embed = _eb.Create()
 | 
				
			||||||
                    .WithOkColor()
 | 
					                    .WithOkColor()
 | 
				
			||||||
                    .WithTitle(GetText("waifu") + " " + (wi.FullName ?? name ?? targetId.ToString()) + " - \"the " +
 | 
					                    .WithTitle(GetText("waifu") + " " + (wi.FullName ?? name ?? targetId.ToString()) + " - \"the " +
 | 
				
			||||||
                               _service.GetClaimTitle(wi.ClaimCount) + "\"")
 | 
					                               _service.GetClaimTitle(wi.ClaimCount) + "\"")
 | 
				
			||||||
@@ -312,7 +312,7 @@ namespace NadekoBot.Modules.Gambling
 | 
				
			|||||||
                var waifuItems = _service.GetWaifuItems();
 | 
					                var waifuItems = _service.GetWaifuItems();
 | 
				
			||||||
                await ctx.SendPaginatedConfirmAsync(page, (cur) =>
 | 
					                await ctx.SendPaginatedConfirmAsync(page, (cur) =>
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    var embed = new EmbedBuilder()
 | 
					                    var embed = _eb.Create()
 | 
				
			||||||
                        .WithTitle(GetText("waifu_gift_shop"))
 | 
					                        .WithTitle(GetText("waifu_gift_shop"))
 | 
				
			||||||
                        .WithOkColor();
 | 
					                        .WithOkColor();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -50,7 +50,7 @@ namespace NadekoBot.Modules.Gambling
 | 
				
			|||||||
                var result = await _service.WheelOfFortuneSpinAsync(ctx.User.Id, amount).ConfigureAwait(false);
 | 
					                var result = await _service.WheelOfFortuneSpinAsync(ctx.User.Id, amount).ConfigureAwait(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var wofMultipliers = _config.WheelOfFortune.Multipliers;
 | 
					                var wofMultipliers = _config.WheelOfFortune.Multipliers;
 | 
				
			||||||
                await ctx.Channel.SendConfirmAsync(
 | 
					                await SendConfirmAsync(
 | 
				
			||||||
Format.Bold($@"{ctx.User.ToString()} won: {result.Amount + CurrencySign}
 | 
					Format.Bold($@"{ctx.User.ToString()} won: {result.Amount + CurrencySign}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   『{wofMultipliers[1]}』   『{wofMultipliers[0]}』   『{wofMultipliers[7]}』
 | 
					   『{wofMultipliers[1]}』   『{wofMultipliers[0]}』   『{wofMultipliers[7]}』
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -80,7 +80,7 @@ namespace NadekoBot.Modules.Games
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            private Task Game_OnStarted(AcrophobiaGame game)
 | 
					            private Task Game_OnStarted(AcrophobiaGame game)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var embed = new EmbedBuilder().WithOkColor()
 | 
					                var embed = _eb.Create().WithOkColor()
 | 
				
			||||||
                        .WithTitle(GetText("acrophobia"))
 | 
					                        .WithTitle(GetText("acrophobia"))
 | 
				
			||||||
                        .WithDescription(GetText("acro_started", Format.Bold(string.Join(".", game.StartingLetters))))
 | 
					                        .WithDescription(GetText("acro_started", Format.Bold(string.Join(".", game.StartingLetters))))
 | 
				
			||||||
                        .WithFooter(GetText("acro_started_footer", game.Opts.SubmissionTime));
 | 
					                        .WithFooter(GetText("acro_started_footer", game.Opts.SubmissionTime));
 | 
				
			||||||
@@ -90,7 +90,7 @@ namespace NadekoBot.Modules.Games
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            private Task Game_OnUserVoted(string user)
 | 
					            private Task Game_OnUserVoted(string user)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                return ctx.Channel.SendConfirmAsync(
 | 
					                return SendConfirmAsync(
 | 
				
			||||||
                    GetText("acrophobia"),
 | 
					                    GetText("acrophobia"),
 | 
				
			||||||
                    GetText("acro_vote_cast", Format.Bold(user)));
 | 
					                    GetText("acro_vote_cast", Format.Bold(user)));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -99,12 +99,12 @@ namespace NadekoBot.Modules.Games
 | 
				
			|||||||
            {
 | 
					            {
 | 
				
			||||||
                if (submissions.Length == 0)
 | 
					                if (submissions.Length == 0)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    await ctx.Channel.SendErrorAsync(GetText("acrophobia"), GetText("acro_ended_no_sub")).ConfigureAwait(false);
 | 
					                    await SendErrorAsync(GetText("acrophobia"), GetText("acro_ended_no_sub")).ConfigureAwait(false);
 | 
				
			||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                if (submissions.Length == 1)
 | 
					                if (submissions.Length == 1)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    await ctx.Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
 | 
					                    await ctx.Channel.EmbedAsync(_eb.Create().WithOkColor()
 | 
				
			||||||
                            .WithDescription(
 | 
					                            .WithDescription(
 | 
				
			||||||
                                GetText("acro_winner_only",
 | 
					                                GetText("acro_winner_only",
 | 
				
			||||||
                                    Format.Bold(submissions.First().Key.UserName)))
 | 
					                                    Format.Bold(submissions.First().Key.UserName)))
 | 
				
			||||||
@@ -115,7 +115,7 @@ namespace NadekoBot.Modules.Games
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var i = 0;
 | 
					                var i = 0;
 | 
				
			||||||
                var embed = new EmbedBuilder()
 | 
					                var embed = _eb.Create()
 | 
				
			||||||
                        .WithOkColor()
 | 
					                        .WithOkColor()
 | 
				
			||||||
                        .WithTitle(GetText("acrophobia") + " - " + GetText("submissions_closed"))
 | 
					                        .WithTitle(GetText("acrophobia") + " - " + GetText("submissions_closed"))
 | 
				
			||||||
                        .WithDescription(GetText("acro_nym_was", Format.Bold(string.Join(".", game.StartingLetters)) + "\n" +
 | 
					                        .WithDescription(GetText("acro_nym_was", Format.Bold(string.Join(".", game.StartingLetters)) + "\n" +
 | 
				
			||||||
@@ -131,12 +131,12 @@ $@"--
 | 
				
			|||||||
            {
 | 
					            {
 | 
				
			||||||
                if (!votes.Any() || votes.All(x => x.Value == 0))
 | 
					                if (!votes.Any() || votes.All(x => x.Value == 0))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    await ctx.Channel.SendErrorAsync(GetText("acrophobia"), GetText("acro_no_votes_cast")).ConfigureAwait(false);
 | 
					                    await SendErrorAsync(GetText("acrophobia"), GetText("acro_no_votes_cast")).ConfigureAwait(false);
 | 
				
			||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                var table = votes.OrderByDescending(v => v.Value);
 | 
					                var table = votes.OrderByDescending(v => v.Value);
 | 
				
			||||||
                var winner = table.First();
 | 
					                var winner = table.First();
 | 
				
			||||||
                var embed = new EmbedBuilder().WithOkColor()
 | 
					                var embed = _eb.Create().WithOkColor()
 | 
				
			||||||
                    .WithTitle(GetText("acrophobia"))
 | 
					                    .WithTitle(GetText("acrophobia"))
 | 
				
			||||||
                    .WithDescription(GetText("acro_winner", Format.Bold(winner.Key.UserName),
 | 
					                    .WithDescription(GetText("acro_winner", Format.Bold(winner.Key.UserName),
 | 
				
			||||||
                        Format.Bold(winner.Value.ToString())))
 | 
					                        Format.Bold(winner.Value.ToString())))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -50,14 +50,16 @@ namespace NadekoBot.Modules.Games.Common
 | 
				
			|||||||
        private readonly IBotStrings _strings;
 | 
					        private readonly IBotStrings _strings;
 | 
				
			||||||
        private readonly DiscordSocketClient _client;
 | 
					        private readonly DiscordSocketClient _client;
 | 
				
			||||||
        private readonly Options _options;
 | 
					        private readonly Options _options;
 | 
				
			||||||
 | 
					        private readonly IEmbedBuilderService _eb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public TicTacToe(IBotStrings strings, DiscordSocketClient client, ITextChannel channel,
 | 
					        public TicTacToe(IBotStrings strings, DiscordSocketClient client, ITextChannel channel,
 | 
				
			||||||
            IGuildUser firstUser, Options options)
 | 
					            IGuildUser firstUser, Options options, IEmbedBuilderService eb)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _channel = channel;
 | 
					            _channel = channel;
 | 
				
			||||||
            _strings = strings;
 | 
					            _strings = strings;
 | 
				
			||||||
            _client = client;
 | 
					            _client = client;
 | 
				
			||||||
            _options = options;
 | 
					            _options = options;
 | 
				
			||||||
 | 
					            _eb = eb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            _users = new[] { firstUser, null };
 | 
					            _users = new[] { firstUser, null };
 | 
				
			||||||
            _state = new int?[,] {
 | 
					            _state = new int?[,] {
 | 
				
			||||||
@@ -91,9 +93,9 @@ namespace NadekoBot.Modules.Games.Common
 | 
				
			|||||||
            return sb.ToString();
 | 
					            return sb.ToString();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public EmbedBuilder GetEmbed(string title = null)
 | 
					        public IEmbedBuilder GetEmbed(string title = null)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var embed = new EmbedBuilder()
 | 
					            var embed = _eb.Create()
 | 
				
			||||||
                .WithOkColor()
 | 
					                .WithOkColor()
 | 
				
			||||||
                .WithDescription(Environment.NewLine + GetState())
 | 
					                .WithDescription(Environment.NewLine + GetState())
 | 
				
			||||||
                .WithAuthor(GetText("vs", _users[0], _users[1]));
 | 
					                .WithAuthor(GetText("vs", _users[0], _users[1]));
 | 
				
			||||||
@@ -135,12 +137,12 @@ namespace NadekoBot.Modules.Games.Common
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            if (_phase == Phase.Started || _phase == Phase.Ended)
 | 
					            if (_phase == Phase.Started || _phase == Phase.Ended)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                await _channel.SendErrorAsync(user.Mention + GetText("ttt_already_running")).ConfigureAwait(false);
 | 
					                await _channel.SendErrorAsync(_eb, user.Mention + GetText("ttt_already_running")).ConfigureAwait(false);
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else if (_users[0] == user)
 | 
					            else if (_users[0] == user)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                await _channel.SendErrorAsync(user.Mention + GetText("ttt_against_yourself")).ConfigureAwait(false);
 | 
					                await _channel.SendErrorAsync(_eb, user.Mention + GetText("ttt_against_yourself")).ConfigureAwait(false);
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -42,10 +42,11 @@ namespace NadekoBot.Modules.Games.Common.Trivia
 | 
				
			|||||||
        private readonly TriviaQuestionPool _questionPool;
 | 
					        private readonly TriviaQuestionPool _questionPool;
 | 
				
			||||||
        private int _timeoutCount = 0;
 | 
					        private int _timeoutCount = 0;
 | 
				
			||||||
        private readonly string _quitCommand;
 | 
					        private readonly string _quitCommand;
 | 
				
			||||||
 | 
					        private readonly IEmbedBuilderService _eb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public TriviaGame(IBotStrings strings, DiscordSocketClient client, GamesConfig config,
 | 
					        public TriviaGame(IBotStrings strings, DiscordSocketClient client, GamesConfig config,
 | 
				
			||||||
            IDataCache cache, ICurrencyService cs, IGuild guild, ITextChannel channel,
 | 
					            IDataCache cache, ICurrencyService cs, IGuild guild, ITextChannel channel,
 | 
				
			||||||
            TriviaOptions options, string quitCommand)
 | 
					            TriviaOptions options, string quitCommand, IEmbedBuilderService eb)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _cache = cache;
 | 
					            _cache = cache;
 | 
				
			||||||
            _questionPool = new TriviaQuestionPool(_cache);
 | 
					            _questionPool = new TriviaQuestionPool(_cache);
 | 
				
			||||||
@@ -55,6 +56,7 @@ namespace NadekoBot.Modules.Games.Common.Trivia
 | 
				
			|||||||
            _cs = cs;
 | 
					            _cs = cs;
 | 
				
			||||||
            _options = options;
 | 
					            _options = options;
 | 
				
			||||||
            _quitCommand = quitCommand;
 | 
					            _quitCommand = quitCommand;
 | 
				
			||||||
 | 
					            _eb = eb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Guild = guild;
 | 
					            Guild = guild;
 | 
				
			||||||
            Channel = channel;
 | 
					            Channel = channel;
 | 
				
			||||||
@@ -76,16 +78,16 @@ namespace NadekoBot.Modules.Games.Common.Trivia
 | 
				
			|||||||
                CurrentQuestion = _questionPool.GetRandomQuestion(OldQuestions, _options.IsPokemon);
 | 
					                CurrentQuestion = _questionPool.GetRandomQuestion(OldQuestions, _options.IsPokemon);
 | 
				
			||||||
                if (string.IsNullOrWhiteSpace(CurrentQuestion?.Answer) || string.IsNullOrWhiteSpace(CurrentQuestion.Question))
 | 
					                if (string.IsNullOrWhiteSpace(CurrentQuestion?.Answer) || string.IsNullOrWhiteSpace(CurrentQuestion.Question))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    await Channel.SendErrorAsync(GetText("trivia_game"), GetText("failed_loading_question")).ConfigureAwait(false);
 | 
					                    await Channel.SendErrorAsync(_eb, GetText("trivia_game"), GetText("failed_loading_question")).ConfigureAwait(false);
 | 
				
			||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                OldQuestions.Add(CurrentQuestion); //add it to exclusion list so it doesn't show up again
 | 
					                OldQuestions.Add(CurrentQuestion); //add it to exclusion list so it doesn't show up again
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                EmbedBuilder questionEmbed;
 | 
					                IEmbedBuilder questionEmbed;
 | 
				
			||||||
                IUserMessage questionMessage;
 | 
					                IUserMessage questionMessage;
 | 
				
			||||||
                try
 | 
					                try
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    questionEmbed = new EmbedBuilder().WithOkColor()
 | 
					                    questionEmbed = _eb.Create().WithOkColor()
 | 
				
			||||||
                        .WithTitle(GetText("trivia_game"))
 | 
					                        .WithTitle(GetText("trivia_game"))
 | 
				
			||||||
                        .AddField(GetText("category"), CurrentQuestion.Category)
 | 
					                        .AddField(GetText("category"), CurrentQuestion.Category)
 | 
				
			||||||
                        .AddField(GetText("question"), CurrentQuestion.Question);
 | 
					                        .AddField(GetText("question"), CurrentQuestion.Question);
 | 
				
			||||||
@@ -149,7 +151,7 @@ namespace NadekoBot.Modules.Games.Common.Trivia
 | 
				
			|||||||
                {
 | 
					                {
 | 
				
			||||||
                    try
 | 
					                    try
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        var embed = new EmbedBuilder().WithErrorColor()
 | 
					                        var embed = _eb.Create().WithErrorColor()
 | 
				
			||||||
                            .WithTitle(GetText("trivia_game"))
 | 
					                            .WithTitle(GetText("trivia_game"))
 | 
				
			||||||
                            .WithDescription(GetText("trivia_times_up", Format.Bold(CurrentQuestion.Answer)));
 | 
					                            .WithDescription(GetText("trivia_times_up", Format.Bold(CurrentQuestion.Answer)));
 | 
				
			||||||
                        if (Uri.IsWellFormedUriString(CurrentQuestion.AnswerImageUrl, UriKind.Absolute))
 | 
					                        if (Uri.IsWellFormedUriString(CurrentQuestion.AnswerImageUrl, UriKind.Absolute))
 | 
				
			||||||
@@ -173,7 +175,7 @@ namespace NadekoBot.Modules.Games.Common.Trivia
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            ShouldStopGame = true;
 | 
					            ShouldStopGame = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            await Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
 | 
					            await Channel.EmbedAsync(_eb.Create().WithOkColor()
 | 
				
			||||||
                    .WithAuthor("Trivia Game Ended")
 | 
					                    .WithAuthor("Trivia Game Ended")
 | 
				
			||||||
                    .WithTitle("Final Results")
 | 
					                    .WithTitle("Final Results")
 | 
				
			||||||
                    .WithDescription(GetLeaderboard())).ConfigureAwait(false);
 | 
					                    .WithDescription(GetLeaderboard())).ConfigureAwait(false);
 | 
				
			||||||
@@ -187,8 +189,9 @@ namespace NadekoBot.Modules.Games.Common.Trivia
 | 
				
			|||||||
            {
 | 
					            {
 | 
				
			||||||
                try
 | 
					                try
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    await Channel.SendConfirmAsync(GetText("trivia_game"), GetText("trivia_stopping"))
 | 
					                    await Channel.SendConfirmAsync(_eb,
 | 
				
			||||||
                        .ConfigureAwait(false);
 | 
					                        GetText("trivia_game"),
 | 
				
			||||||
 | 
					                        GetText("trivia_stopping"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                catch (Exception ex)
 | 
					                catch (Exception ex)
 | 
				
			||||||
@@ -235,7 +238,7 @@ namespace NadekoBot.Modules.Games.Common.Trivia
 | 
				
			|||||||
                        ShouldStopGame = true;
 | 
					                        ShouldStopGame = true;
 | 
				
			||||||
                        try
 | 
					                        try
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            var embedS = new EmbedBuilder().WithOkColor()
 | 
					                            var embedS = _eb.Create().WithOkColor()
 | 
				
			||||||
                                .WithTitle(GetText("trivia_game"))
 | 
					                                .WithTitle(GetText("trivia_game"))
 | 
				
			||||||
                                .WithDescription(GetText("trivia_win",
 | 
					                                .WithDescription(GetText("trivia_win",
 | 
				
			||||||
                                    guildUser.Mention,
 | 
					                                    guildUser.Mention,
 | 
				
			||||||
@@ -253,7 +256,7 @@ namespace NadekoBot.Modules.Games.Common.Trivia
 | 
				
			|||||||
                            await _cs.AddAsync(guildUser, "Won trivia", reward, true).ConfigureAwait(false);
 | 
					                            await _cs.AddAsync(guildUser, "Won trivia", reward, true).ConfigureAwait(false);
 | 
				
			||||||
                        return;
 | 
					                        return;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    var embed = new EmbedBuilder().WithOkColor()
 | 
					                    var embed = _eb.Create().WithOkColor()
 | 
				
			||||||
                        .WithTitle(GetText("trivia_game"))
 | 
					                        .WithTitle(GetText("trivia_game"))
 | 
				
			||||||
                        .WithDescription(GetText("trivia_guess", guildUser.Mention, Format.Bold(CurrentQuestion.Answer)));
 | 
					                        .WithDescription(GetText("trivia_guess", guildUser.Mention, Format.Bold(CurrentQuestion.Answer)));
 | 
				
			||||||
                    if (Uri.IsWellFormedUriString(CurrentQuestion.AnswerImageUrl, UriKind.Absolute))
 | 
					                    if (Uri.IsWellFormedUriString(CurrentQuestion.AnswerImageUrl, UriKind.Absolute))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,6 +9,7 @@ using NadekoBot.Common;
 | 
				
			|||||||
using NadekoBot.Extensions;
 | 
					using NadekoBot.Extensions;
 | 
				
			||||||
using NadekoBot.Modules.Games.Services;
 | 
					using NadekoBot.Modules.Games.Services;
 | 
				
			||||||
using CommandLine;
 | 
					using CommandLine;
 | 
				
			||||||
 | 
					using NadekoBot.Services;
 | 
				
			||||||
using Serilog;
 | 
					using Serilog;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace NadekoBot.Modules.Games.Common
 | 
					namespace NadekoBot.Modules.Games.Common
 | 
				
			||||||
@@ -37,14 +38,16 @@ namespace NadekoBot.Modules.Games.Common
 | 
				
			|||||||
        private readonly GamesService _games;
 | 
					        private readonly GamesService _games;
 | 
				
			||||||
        private readonly string _prefix;
 | 
					        private readonly string _prefix;
 | 
				
			||||||
        private readonly Options _options;
 | 
					        private readonly Options _options;
 | 
				
			||||||
 | 
					        private readonly IEmbedBuilderService _eb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public TypingGame(GamesService games, DiscordSocketClient client, ITextChannel channel, 
 | 
					        public TypingGame(GamesService games, DiscordSocketClient client, ITextChannel channel, 
 | 
				
			||||||
            string prefix, Options options)
 | 
					            string prefix, Options options, IEmbedBuilderService eb)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _games = games;
 | 
					            _games = games;
 | 
				
			||||||
            _client = client;
 | 
					            _client = client;
 | 
				
			||||||
            _prefix = prefix;
 | 
					            _prefix = prefix;
 | 
				
			||||||
            _options = options;
 | 
					            _options = options;
 | 
				
			||||||
 | 
					            _eb = eb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            this.Channel = channel;
 | 
					            this.Channel = channel;
 | 
				
			||||||
            IsActive = false;
 | 
					            IsActive = false;
 | 
				
			||||||
@@ -62,7 +65,7 @@ namespace NadekoBot.Modules.Games.Common
 | 
				
			|||||||
            sw.Reset();
 | 
					            sw.Reset();
 | 
				
			||||||
            try
 | 
					            try
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                await Channel.SendConfirmAsync("Typing contest stopped.").ConfigureAwait(false);
 | 
					                await Channel.SendConfirmAsync(_eb, "Typing contest stopped.");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            catch (Exception ex)
 | 
					            catch (Exception ex)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
@@ -80,7 +83,8 @@ namespace NadekoBot.Modules.Games.Common
 | 
				
			|||||||
            var i = (int)(CurrentSentence.Length / WORD_VALUE * 1.7f);
 | 
					            var i = (int)(CurrentSentence.Length / WORD_VALUE * 1.7f);
 | 
				
			||||||
            try
 | 
					            try
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                await Channel.SendConfirmAsync($@":clock2: Next contest will last for {i} seconds. Type the bolded text as fast as you can.").ConfigureAwait(false);
 | 
					                await Channel.SendConfirmAsync(_eb,
 | 
				
			||||||
 | 
					                    $@":clock2: Next contest will last for {i} seconds. Type the bolded text as fast as you can.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var time = _options.StartTime;
 | 
					                var time = _options.StartTime;
 | 
				
			||||||
@@ -156,7 +160,7 @@ namespace NadekoBot.Modules.Games.Common
 | 
				
			|||||||
                        var elapsed = sw.Elapsed;
 | 
					                        var elapsed = sw.Elapsed;
 | 
				
			||||||
                        var wpm = CurrentSentence.Length / WORD_VALUE / elapsed.TotalSeconds * 60;
 | 
					                        var wpm = CurrentSentence.Length / WORD_VALUE / elapsed.TotalSeconds * 60;
 | 
				
			||||||
                        finishedUserIds.Add(msg.Author.Id);
 | 
					                        finishedUserIds.Add(msg.Author.Id);
 | 
				
			||||||
                        await this.Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
 | 
					                        await this.Channel.EmbedAsync(_eb.Create().WithOkColor()
 | 
				
			||||||
                            .WithTitle($"{msg.Author} finished the race!")
 | 
					                            .WithTitle($"{msg.Author} finished the race!")
 | 
				
			||||||
                            .AddField("Place", $"#{finishedUserIds.Count}", true)
 | 
					                            .AddField("Place", $"#{finishedUserIds.Count}", true)
 | 
				
			||||||
                            .AddField("WPM", $"{wpm:F1} *[{elapsed.TotalSeconds:F2}sec]*", true)
 | 
					                            .AddField("WPM", $"{wpm:F1} *[{elapsed.TotalSeconds:F2}sec]*", true)
 | 
				
			||||||
@@ -164,7 +168,7 @@ namespace NadekoBot.Modules.Games.Common
 | 
				
			|||||||
                        
 | 
					                        
 | 
				
			||||||
                        if (finishedUserIds.Count % 4 == 0)
 | 
					                        if (finishedUserIds.Count % 4 == 0)
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            await this.Channel.SendConfirmAsync(
 | 
					                            await this.Channel.SendConfirmAsync(_eb,
 | 
				
			||||||
                                    $":exclamation: A lot of people finished, here is the text for those still typing:" +
 | 
					                                    $":exclamation: A lot of people finished, here is the text for those still typing:" +
 | 
				
			||||||
                                    $"\n\n**{Format.Sanitize(CurrentSentence.Replace(" ", " \x200B", StringComparison.InvariantCulture)).SanitizeMentions(true)}**")
 | 
					                                    $"\n\n**{Format.Sanitize(CurrentSentence.Replace(" ", " \x200B", StringComparison.InvariantCulture)).SanitizeMentions(true)}**")
 | 
				
			||||||
                                .ConfigureAwait(false);
 | 
					                                .ConfigureAwait(false);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -38,7 +38,7 @@ namespace NadekoBot.Modules.Games
 | 
				
			|||||||
            if (listArr.Length < 2)
 | 
					            if (listArr.Length < 2)
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
            var rng = new NadekoRandom();
 | 
					            var rng = new NadekoRandom();
 | 
				
			||||||
            await ctx.Channel.SendConfirmAsync("🤔", listArr[rng.Next(0, listArr.Length)]).ConfigureAwait(false);
 | 
					            await SendConfirmAsync("🤔", listArr[rng.Next(0, listArr.Length)]).ConfigureAwait(false);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [NadekoCommand, Aliases]
 | 
					        [NadekoCommand, Aliases]
 | 
				
			||||||
@@ -48,7 +48,7 @@ namespace NadekoBot.Modules.Games
 | 
				
			|||||||
                return;
 | 
					                return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var res = _service.GetEightballResponse(ctx.User.Id, question);
 | 
					            var res = _service.GetEightballResponse(ctx.User.Id, question);
 | 
				
			||||||
            await ctx.Channel.EmbedAsync(new EmbedBuilder().WithColor(Bot.OkColor)
 | 
					            await ctx.Channel.EmbedAsync(_eb.Create().WithOkColor()
 | 
				
			||||||
                .WithDescription(ctx.User.ToString())
 | 
					                .WithDescription(ctx.User.ToString())
 | 
				
			||||||
                .AddField("❓ " + GetText("question"), question, false)
 | 
					                .AddField("❓ " + GetText("question"), question, false)
 | 
				
			||||||
                .AddField("🎱 " + GetText("8ball"), res, false));
 | 
					                .AddField("🎱 " + GetText("8ball"), res, false));
 | 
				
			||||||
@@ -78,7 +78,7 @@ namespace NadekoBot.Modules.Games
 | 
				
			|||||||
                await ctx.Channel.SendFileAsync(stream: imgStream,
 | 
					                await ctx.Channel.SendFileAsync(stream: imgStream,
 | 
				
			||||||
                    filename: $"girl_{usr}.png",
 | 
					                    filename: $"girl_{usr}.png",
 | 
				
			||||||
                    text: Format.Bold($"{ctx.User.Mention} Girl Rating For {usr}"),
 | 
					                    text: Format.Bold($"{ctx.User.Mention} Girl Rating For {usr}"),
 | 
				
			||||||
                    embed: new EmbedBuilder()
 | 
					                    embed: _eb.Create()
 | 
				
			||||||
                        .WithOkColor()
 | 
					                        .WithOkColor()
 | 
				
			||||||
                        .AddField("Hot", gr.Hot.ToString("F2"), true)
 | 
					                        .AddField("Hot", gr.Hot.ToString("F2"), true)
 | 
				
			||||||
                        .AddField("Crazy", gr.Crazy.ToString("F2"), true)
 | 
					                        .AddField("Crazy", gr.Crazy.ToString("F2"), true)
 | 
				
			||||||
@@ -152,7 +152,7 @@ namespace NadekoBot.Modules.Games
 | 
				
			|||||||
        [NadekoCommand, Aliases]
 | 
					        [NadekoCommand, Aliases]
 | 
				
			||||||
        public async Task Linux(string guhnoo, string loonix)
 | 
					        public async Task Linux(string guhnoo, string loonix)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            await ctx.Channel.SendConfirmAsync(
 | 
					            await SendConfirmAsync(
 | 
				
			||||||
$@"I'd just like to interject for moment. What you're refering to as {loonix}, is in fact, {guhnoo}/{loonix}, or as I've recently taken to calling it, {guhnoo} plus {loonix}. {loonix} is not an operating system unto itself, but rather another free component of a fully functioning {guhnoo} system made useful by the {guhnoo} corelibs, shell utilities and vital system components comprising a full OS as defined by POSIX.
 | 
					$@"I'd just like to interject for moment. What you're refering to as {loonix}, is in fact, {guhnoo}/{loonix}, or as I've recently taken to calling it, {guhnoo} plus {loonix}. {loonix} is not an operating system unto itself, but rather another free component of a fully functioning {guhnoo} system made useful by the {guhnoo} corelibs, shell utilities and vital system components comprising a full OS as defined by POSIX.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Many computer users run a modified version of the {guhnoo} system every day, without realizing it. Through a peculiar turn of events, the version of {guhnoo} which is widely used today is often called {loonix}, and many of its users are not aware that it is basically the {guhnoo} system, developed by the {guhnoo} Project.
 | 
					Many computer users run a modified version of the {guhnoo} system every day, without realizing it. Through a peculiar turn of events, the version of {guhnoo} which is widely used today is often called {loonix}, and many of its users are not aware that it is basically the {guhnoo} system, developed by the {guhnoo} Project.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,7 +27,7 @@ namespace NadekoBot.Modules.Games
 | 
				
			|||||||
            [RequireContext(ContextType.Guild)]
 | 
					            [RequireContext(ContextType.Guild)]
 | 
				
			||||||
            public async Task Hangmanlist()
 | 
					            public async Task Hangmanlist()
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                await ctx.Channel.SendConfirmAsync(Format.Code(GetText("hangman_types", Prefix)) + "\n" + string.Join("\n", _service.TermPool.Data.Keys)).ConfigureAwait(false);
 | 
					                await SendConfirmAsync(Format.Code(GetText("hangman_types", Prefix)) + "\n" + string.Join("\n", _service.TermPool.Data.Keys)).ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            [NadekoCommand, Aliases]
 | 
					            [NadekoCommand, Aliases]
 | 
				
			||||||
@@ -58,7 +58,7 @@ namespace NadekoBot.Modules.Games
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                try
 | 
					                try
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    await ctx.Channel.SendConfirmAsync(GetText("hangman_game_started") + $" ({hm.TermType})",
 | 
					                    await SendConfirmAsync(GetText("hangman_game_started") + $" ({hm.TermType})",
 | 
				
			||||||
                        hm.ScrambledWord + "\n" + hm.GetHangman())
 | 
					                        hm.ScrambledWord + "\n" + hm.GetHangman())
 | 
				
			||||||
                        .ConfigureAwait(false);
 | 
					                        .ConfigureAwait(false);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@@ -87,7 +87,7 @@ namespace NadekoBot.Modules.Games
 | 
				
			|||||||
            {
 | 
					            {
 | 
				
			||||||
                if (winner is null)
 | 
					                if (winner is null)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    var loseEmbed = new EmbedBuilder().WithTitle($"Hangman Game ({game.TermType}) - Ended")
 | 
					                    var loseEmbed = _eb.Create().WithTitle($"Hangman Game ({game.TermType}) - Ended")
 | 
				
			||||||
                                             .WithDescription(Format.Bold("You lose."))
 | 
					                                             .WithDescription(Format.Bold("You lose."))
 | 
				
			||||||
                                             .AddField("It was", game.Term.GetWord())
 | 
					                                             .AddField("It was", game.Term.GetWord())
 | 
				
			||||||
                                             .WithFooter(string.Join(" ", game.PreviousGuesses))
 | 
					                                             .WithFooter(string.Join(" ", game.PreviousGuesses))
 | 
				
			||||||
@@ -99,7 +99,7 @@ namespace NadekoBot.Modules.Games
 | 
				
			|||||||
                    return ctx.Channel.EmbedAsync(loseEmbed);
 | 
					                    return ctx.Channel.EmbedAsync(loseEmbed);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var winEmbed = new EmbedBuilder().WithTitle($"Hangman Game ({game.TermType}) - Ended")
 | 
					                var winEmbed = _eb.Create().WithTitle($"Hangman Game ({game.TermType}) - Ended")
 | 
				
			||||||
                                             .WithDescription(Format.Bold($"{winner} Won."))
 | 
					                                             .WithDescription(Format.Bold($"{winner} Won."))
 | 
				
			||||||
                                             .AddField("It was", game.Term.GetWord())
 | 
					                                             .AddField("It was", game.Term.GetWord())
 | 
				
			||||||
                                             .WithFooter(string.Join(" ", game.PreviousGuesses))
 | 
					                                             .WithFooter(string.Join(" ", game.PreviousGuesses))
 | 
				
			||||||
@@ -113,19 +113,19 @@ namespace NadekoBot.Modules.Games
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            private Task Hm_OnLetterAlreadyUsed(Hangman game, string user, char guess)
 | 
					            private Task Hm_OnLetterAlreadyUsed(Hangman game, string user, char guess)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                return ctx.Channel.SendErrorAsync($"Hangman Game ({game.TermType})", $"{user} Letter `{guess}` has already been used. You can guess again in 3 seconds.\n" + game.ScrambledWord + "\n" + game.GetHangman(),
 | 
					                return SendErrorAsync($"Hangman Game ({game.TermType})", $"{user} Letter `{guess}` has already been used. You can guess again in 3 seconds.\n" + game.ScrambledWord + "\n" + game.GetHangman(),
 | 
				
			||||||
                                    footer: string.Join(" ", game.PreviousGuesses));
 | 
					                                    footer: string.Join(" ", game.PreviousGuesses));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            private Task Hm_OnGuessSucceeded(Hangman game, string user, char guess)
 | 
					            private Task Hm_OnGuessSucceeded(Hangman game, string user, char guess)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                return ctx.Channel.SendConfirmAsync($"Hangman Game ({game.TermType})", $"{user} guessed a letter `{guess}`!\n" + game.ScrambledWord + "\n" + game.GetHangman(),
 | 
					                return SendConfirmAsync($"Hangman Game ({game.TermType})", $"{user} guessed a letter `{guess}`!\n" + game.ScrambledWord + "\n" + game.GetHangman(),
 | 
				
			||||||
                    footer: string.Join(" ", game.PreviousGuesses));
 | 
					                    footer: string.Join(" ", game.PreviousGuesses));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            private Task Hm_OnGuessFailed(Hangman game, string user, char guess)
 | 
					            private Task Hm_OnGuessFailed(Hangman game, string user, char guess)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                return ctx.Channel.SendErrorAsync($"Hangman Game ({game.TermType})", $"{user} Letter `{guess}` does not exist. You can guess again in 3 seconds.\n" + game.ScrambledWord + "\n" + game.GetHangman(),
 | 
					                return SendErrorAsync($"Hangman Game ({game.TermType})", $"{user} Letter `{guess}` does not exist. You can guess again in 3 seconds.\n" + game.ScrambledWord + "\n" + game.GetHangman(),
 | 
				
			||||||
                                    footer: string.Join(" ", game.PreviousGuesses));
 | 
					                                    footer: string.Join(" ", game.PreviousGuesses));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -113,11 +113,11 @@ namespace NadekoBot.Modules.Games
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                    if (!items.Any())
 | 
					                    if (!items.Any())
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        return new EmbedBuilder().WithErrorColor()
 | 
					                        return _eb.Create().WithErrorColor()
 | 
				
			||||||
                            .WithDescription("-");
 | 
					                            .WithDescription("-");
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    return items.Aggregate(new EmbedBuilder().WithOkColor(),
 | 
					                    return items.Aggregate(_eb.Create().WithOkColor(),
 | 
				
			||||||
                        (eb, i) => eb.AddField(i.GuildId.ToString(), i.ChannelId));
 | 
					                        (eb, i) => eb.AddField(i.GuildId.ToString(), i.ChannelId));
 | 
				
			||||||
                }, enabledIn.Count(), 9);
 | 
					                }, enabledIn.Count(), 9);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -41,7 +41,7 @@ namespace NadekoBot.Modules.Games
 | 
				
			|||||||
                if (_service.StartPoll(poll))
 | 
					                if (_service.StartPoll(poll))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    await ctx.Channel
 | 
					                    await ctx.Channel
 | 
				
			||||||
                        .EmbedAsync(new EmbedBuilder()
 | 
					                        .EmbedAsync(_eb.Create()
 | 
				
			||||||
                            .WithOkColor()
 | 
					                            .WithOkColor()
 | 
				
			||||||
                            .WithTitle(GetText("poll_created", ctx.User.ToString()))
 | 
					                            .WithTitle(GetText("poll_created", ctx.User.ToString()))
 | 
				
			||||||
                            .WithDescription(
 | 
					                            .WithDescription(
 | 
				
			||||||
@@ -83,14 +83,14 @@ namespace NadekoBot.Modules.Games
 | 
				
			|||||||
                    .ConfigureAwait(false);
 | 
					                    .ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            public EmbedBuilder GetStats(Poll poll, string title)
 | 
					            public IEmbedBuilder GetStats(Poll poll, string title)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var results = poll.Votes.GroupBy(kvp => kvp.VoteIndex)
 | 
					                var results = poll.Votes.GroupBy(kvp => kvp.VoteIndex)
 | 
				
			||||||
                                    .ToDictionary(x => x.Key, x => x.Sum(kvp => 1));
 | 
					                                    .ToDictionary(x => x.Key, x => x.Sum(kvp => 1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var totalVotesCast = results.Sum(x => x.Value);
 | 
					                var totalVotesCast = results.Sum(x => x.Value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var eb = new EmbedBuilder().WithTitle(title);
 | 
					                var eb = _eb.Create().WithTitle(title);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var sb = new StringBuilder()
 | 
					                var sb = new StringBuilder()
 | 
				
			||||||
                    .AppendLine(Format.Bold(poll.Question))
 | 
					                    .AppendLine(Format.Bold(poll.Question))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,6 +22,7 @@ namespace NadekoBot.Modules.Games.Services
 | 
				
			|||||||
        private readonly CommandHandler _cmd;
 | 
					        private readonly CommandHandler _cmd;
 | 
				
			||||||
        private readonly IBotStrings _strings;
 | 
					        private readonly IBotStrings _strings;
 | 
				
			||||||
        private readonly IBotCredentials _creds;
 | 
					        private readonly IBotCredentials _creds;
 | 
				
			||||||
 | 
					        private readonly IEmbedBuilderService _eb;
 | 
				
			||||||
        private readonly IHttpClientFactory _httpFactory;
 | 
					        private readonly IHttpClientFactory _httpFactory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public ConcurrentDictionary<ulong, Lazy<IChatterBotSession>> ChatterBotGuilds { get; }
 | 
					        public ConcurrentDictionary<ulong, Lazy<IChatterBotSession>> ChatterBotGuilds { get; }
 | 
				
			||||||
@@ -30,13 +31,14 @@ namespace NadekoBot.Modules.Games.Services
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        public ChatterBotService(DiscordSocketClient client, PermissionService perms,
 | 
					        public ChatterBotService(DiscordSocketClient client, PermissionService perms,
 | 
				
			||||||
            Bot bot, CommandHandler cmd, IBotStrings strings, IHttpClientFactory factory,
 | 
					            Bot bot, CommandHandler cmd, IBotStrings strings, IHttpClientFactory factory,
 | 
				
			||||||
            IBotCredentials creds)
 | 
					            IBotCredentials creds, IEmbedBuilderService eb)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _client = client;
 | 
					            _client = client;
 | 
				
			||||||
            _perms = perms;
 | 
					            _perms = perms;
 | 
				
			||||||
            _cmd = cmd;
 | 
					            _cmd = cmd;
 | 
				
			||||||
            _strings = strings;
 | 
					            _strings = strings;
 | 
				
			||||||
            _creds = creds;
 | 
					            _creds = creds;
 | 
				
			||||||
 | 
					            _eb = eb;
 | 
				
			||||||
            _httpFactory = factory;
 | 
					            _httpFactory = factory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            ChatterBotGuilds = new ConcurrentDictionary<ulong, Lazy<IChatterBotSession>>(
 | 
					            ChatterBotGuilds = new ConcurrentDictionary<ulong, Lazy<IChatterBotSession>>(
 | 
				
			||||||
@@ -86,18 +88,18 @@ namespace NadekoBot.Modules.Games.Services
 | 
				
			|||||||
            return message;
 | 
					            return message;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public static async Task<bool> TryAsk(IChatterBotSession cleverbot, ITextChannel channel, string message)
 | 
					        public async Task<bool> TryAsk(IChatterBotSession cleverbot, ITextChannel channel, string message)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            await channel.TriggerTypingAsync().ConfigureAwait(false);
 | 
					            await channel.TriggerTypingAsync().ConfigureAwait(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var response = await cleverbot.Think(message).ConfigureAwait(false);
 | 
					            var response = await cleverbot.Think(message).ConfigureAwait(false);
 | 
				
			||||||
            try
 | 
					            try
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                await channel.SendConfirmAsync(response.SanitizeMentions(true)).ConfigureAwait(false);
 | 
					                await channel.SendConfirmAsync(_eb, response.SanitizeMentions(true)).ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            catch
 | 
					            catch
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                await channel.SendConfirmAsync(response.SanitizeMentions(true)).ConfigureAwait(false); // try twice :\
 | 
					                await channel.SendConfirmAsync(_eb, response.SanitizeMentions(true)).ConfigureAwait(false); // try twice :\
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -121,7 +123,7 @@ namespace NadekoBot.Modules.Games.Services
 | 
				
			|||||||
                    if (pc.Verbose)
 | 
					                    if (pc.Verbose)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        var returnMsg = _strings.GetText("trigger", guild.Id, index + 1, Format.Bold(pc.Permissions[index].GetCommand(_cmd.GetPrefix(guild), (SocketGuild)guild)));
 | 
					                        var returnMsg = _strings.GetText("trigger", guild.Id, index + 1, Format.Bold(pc.Permissions[index].GetCommand(_cmd.GetPrefix(guild), (SocketGuild)guild)));
 | 
				
			||||||
                        try { await usrMsg.Channel.SendErrorAsync(returnMsg).ConfigureAwait(false); } catch { }
 | 
					                        try { await usrMsg.Channel.SendErrorAsync(_eb, returnMsg).ConfigureAwait(false); } catch { }
 | 
				
			||||||
                        Log.Information(returnMsg);
 | 
					                        Log.Information(returnMsg);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    return true;
 | 
					                    return true;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,11 +23,13 @@ namespace NadekoBot.Modules.Games.Services
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        private readonly DbService _db;
 | 
					        private readonly DbService _db;
 | 
				
			||||||
        private readonly IBotStrings _strs;
 | 
					        private readonly IBotStrings _strs;
 | 
				
			||||||
 | 
					        private readonly IEmbedBuilderService _eb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public PollService(DbService db, IBotStrings strs)
 | 
					        public PollService(DbService db, IBotStrings strs, IEmbedBuilderService eb)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _db = db;
 | 
					            _db = db;
 | 
				
			||||||
            _strs = strs;
 | 
					            _strs = strs;
 | 
				
			||||||
 | 
					            _eb = eb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            using (var uow = db.GetDbContext())
 | 
					            using (var uow = db.GetDbContext())
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
@@ -97,7 +99,7 @@ namespace NadekoBot.Modules.Games.Services
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        private async Task Pr_OnVoted(IUserMessage msg, IGuildUser usr)
 | 
					        private async Task Pr_OnVoted(IUserMessage msg, IGuildUser usr)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var toDelete = await msg.Channel.SendConfirmAsync(_strs.GetText("poll_voted", 
 | 
					            var toDelete = await msg.Channel.SendConfirmAsync(_eb, _strs.GetText("poll_voted", 
 | 
				
			||||||
                    usr.Guild.Id, Format.Bold(usr.ToString())))
 | 
					                    usr.Guild.Id, Format.Bold(usr.ToString())))
 | 
				
			||||||
                .ConfigureAwait(false);
 | 
					                .ConfigureAwait(false);
 | 
				
			||||||
            toDelete.DeleteAfter(5);
 | 
					            toDelete.DeleteAfter(5);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,14 +35,11 @@ namespace NadekoBot.Modules.Games
 | 
				
			|||||||
                var (options, _) = OptionsParser.ParseFrom(new TypingGame.Options(), args);
 | 
					                var (options, _) = OptionsParser.ParseFrom(new TypingGame.Options(), args);
 | 
				
			||||||
                var channel = (ITextChannel)ctx.Channel;
 | 
					                var channel = (ITextChannel)ctx.Channel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var game = _service.RunningContests.GetOrAdd(channel.Guild.Id, id => new TypingGame(_games, _client, channel, Prefix, options));
 | 
					                var game = _service.RunningContests.GetOrAdd(ctx.Guild.Id, id => new TypingGame(_games, _client, channel, Prefix, options, _eb));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (game.IsActive)
 | 
					                if (game.IsActive)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    await channel.SendErrorAsync(
 | 
					                    await SendErrorAsync($"Contest already running in {game.Channel.Mention} channel.");
 | 
				
			||||||
                            $"Contest already running in " +
 | 
					 | 
				
			||||||
                            $"{game.Channel.Mention} channel.")
 | 
					 | 
				
			||||||
                                .ConfigureAwait(false);
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else
 | 
					                else
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
@@ -54,13 +51,13 @@ namespace NadekoBot.Modules.Games
 | 
				
			|||||||
            [RequireContext(ContextType.Guild)]
 | 
					            [RequireContext(ContextType.Guild)]
 | 
				
			||||||
            public async Task TypeStop()
 | 
					            public async Task TypeStop()
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var channel = (ITextChannel)ctx.Channel;
 | 
					                if (_service.RunningContests.TryRemove(ctx.Guild.Id, out TypingGame game))
 | 
				
			||||||
                if (_service.RunningContests.TryRemove(channel.Guild.Id, out TypingGame game))
 | 
					 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    await game.Stop().ConfigureAwait(false);
 | 
					                    await game.Stop().ConfigureAwait(false);
 | 
				
			||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                await channel.SendErrorAsync("No contest to stop on this channel.").ConfigureAwait(false);
 | 
					                
 | 
				
			||||||
 | 
					                await SendErrorAsync("No contest to stop on this channel.").ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -69,21 +66,18 @@ namespace NadekoBot.Modules.Games
 | 
				
			|||||||
            [OwnerOnly]
 | 
					            [OwnerOnly]
 | 
				
			||||||
            public async Task Typeadd([Leftover] string text)
 | 
					            public async Task Typeadd([Leftover] string text)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var channel = (ITextChannel)ctx.Channel;
 | 
					 | 
				
			||||||
                if (string.IsNullOrWhiteSpace(text))
 | 
					                if (string.IsNullOrWhiteSpace(text))
 | 
				
			||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                _games.AddTypingArticle(ctx.User, text);                
 | 
					                _games.AddTypingArticle(ctx.User, text);                
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                await channel.SendConfirmAsync("Added new article for typing game.").ConfigureAwait(false);
 | 
					                await SendConfirmAsync("Added new article for typing game.").ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            [NadekoCommand, Aliases]
 | 
					            [NadekoCommand, Aliases]
 | 
				
			||||||
            [RequireContext(ContextType.Guild)]
 | 
					            [RequireContext(ContextType.Guild)]
 | 
				
			||||||
            public async Task Typelist(int page = 1)
 | 
					            public async Task Typelist(int page = 1)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var channel = (ITextChannel)ctx.Channel;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if (page < 1)
 | 
					                if (page < 1)
 | 
				
			||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -91,11 +85,11 @@ namespace NadekoBot.Modules.Games
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                if (!articles.Any())
 | 
					                if (!articles.Any())
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    await channel.SendErrorAsync($"{ctx.User.Mention} `No articles found on that page.`").ConfigureAwait(false);
 | 
					                    await SendErrorAsync($"{ctx.User.Mention} `No articles found on that page.`").ConfigureAwait(false);
 | 
				
			||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                var i = (page - 1) * 15;
 | 
					                var i = (page - 1) * 15;
 | 
				
			||||||
                await channel.SendConfirmAsync("List of articles for Type Race", string.Join("\n", articles.Select(a => $"`#{++i}` - {a.Text.TrimTo(50)}")))
 | 
					                await SendConfirmAsync("List of articles for Type Race", string.Join("\n", articles.Select(a => $"`#{++i}` - {a.Text.TrimTo(50)}")))
 | 
				
			||||||
                             .ConfigureAwait(false);
 | 
					                             .ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -111,7 +105,7 @@ namespace NadekoBot.Modules.Games
 | 
				
			|||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var embed = new EmbedBuilder()
 | 
					                var embed = _eb.Create()
 | 
				
			||||||
                    .WithTitle($"Removed typing article #{index + 1}")
 | 
					                    .WithTitle($"Removed typing article #{index + 1}")
 | 
				
			||||||
                    .WithDescription(removed.Text.TrimTo(50))
 | 
					                    .WithDescription(removed.Text.TrimTo(50))
 | 
				
			||||||
                    .WithOkColor();
 | 
					                    .WithOkColor();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -42,7 +42,7 @@ namespace NadekoBot.Modules.Games
 | 
				
			|||||||
                        });
 | 
					                        });
 | 
				
			||||||
                        return;
 | 
					                        return;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    game = new TicTacToe(base.Strings, this._client, channel, (IGuildUser)ctx.User, options);
 | 
					                    game = new TicTacToe(base.Strings, this._client, channel, (IGuildUser)ctx.User, options, _eb);
 | 
				
			||||||
                    _service.TicTacToeGames.Add(channel.Id, game);
 | 
					                    _service.TicTacToeGames.Add(channel.Id, game);
 | 
				
			||||||
                    await ReplyConfirmLocalizedAsync("ttt_created").ConfigureAwait(false);
 | 
					                    await ReplyConfirmLocalizedAsync("ttt_created").ConfigureAwait(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -48,7 +48,9 @@ namespace NadekoBot.Modules.Games
 | 
				
			|||||||
                {
 | 
					                {
 | 
				
			||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                var trivia = new TriviaGame(Strings, _client, config, _cache, _cs, channel.Guild, channel, opts, Prefix + "tq");
 | 
					
 | 
				
			||||||
 | 
					                var trivia = new TriviaGame(Strings, _client, config, _cache, _cs, channel.Guild, channel, opts,
 | 
				
			||||||
 | 
					                    Prefix + "tq", _eb);
 | 
				
			||||||
                if (_service.RunningTrivias.TryAdd(channel.Guild.Id, trivia))
 | 
					                if (_service.RunningTrivias.TryAdd(channel.Guild.Id, trivia))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    try
 | 
					                    try
 | 
				
			||||||
@@ -63,7 +65,7 @@ namespace NadekoBot.Modules.Games
 | 
				
			|||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                await ctx.Channel.SendErrorAsync(GetText("trivia_already_running") + "\n" + trivia.CurrentQuestion)
 | 
					                await SendErrorAsync(GetText("trivia_already_running") + "\n" + trivia.CurrentQuestion)
 | 
				
			||||||
                    .ConfigureAwait(false);
 | 
					                    .ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -71,11 +73,9 @@ namespace NadekoBot.Modules.Games
 | 
				
			|||||||
            [RequireContext(ContextType.Guild)]
 | 
					            [RequireContext(ContextType.Guild)]
 | 
				
			||||||
            public async Task Tl()
 | 
					            public async Task Tl()
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var channel = (ITextChannel)ctx.Channel;
 | 
					                if (_service.RunningTrivias.TryGetValue(ctx.Guild.Id, out TriviaGame trivia))
 | 
				
			||||||
 | 
					 | 
				
			||||||
                if (_service.RunningTrivias.TryGetValue(channel.Guild.Id, out TriviaGame trivia))
 | 
					 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    await channel.SendConfirmAsync(GetText("leaderboard"), trivia.GetLeaderboard()).ConfigureAwait(false);
 | 
					                    await SendConfirmAsync(GetText("leaderboard"), trivia.GetLeaderboard()).ConfigureAwait(false);
 | 
				
			||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -49,7 +49,7 @@ namespace NadekoBot.Modules.Help
 | 
				
			|||||||
            _lazyClientId = new AsyncLazy<ulong>(async () => (await _client.GetApplicationInfoAsync()).Id);
 | 
					            _lazyClientId = new AsyncLazy<ulong>(async () => (await _client.GetApplicationInfoAsync()).Id);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public async Task<(string plainText, EmbedBuilder embed)> GetHelpStringEmbed()
 | 
					        public async Task<(string plainText, IEmbedBuilder embed)> GetHelpStringEmbed()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var botSettings = _bss.Data;
 | 
					            var botSettings = _bss.Data;
 | 
				
			||||||
            if (string.IsNullOrWhiteSpace(botSettings.HelpText) || botSettings.HelpText == "-")
 | 
					            if (string.IsNullOrWhiteSpace(botSettings.HelpText) || botSettings.HelpText == "-")
 | 
				
			||||||
@@ -68,14 +68,14 @@ namespace NadekoBot.Modules.Help
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            if (!CREmbed.TryParse(botSettings.HelpText, out var embed))
 | 
					            if (!CREmbed.TryParse(botSettings.HelpText, out var embed))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var eb = new EmbedBuilder().WithOkColor()
 | 
					                var eb = _eb.Create().WithOkColor()
 | 
				
			||||||
                    .WithDescription(String.Format(botSettings.HelpText, clientId, Prefix));
 | 
					                    .WithDescription(String.Format(botSettings.HelpText, clientId, Prefix));
 | 
				
			||||||
                return ("", eb);
 | 
					                return ("", eb);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            r.Replace(embed);
 | 
					            r.Replace(embed);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return (embed.PlainText, embed.ToEmbed());
 | 
					            return (embed.PlainText, embed.ToEmbed(_eb));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [NadekoCommand, Aliases]
 | 
					        [NadekoCommand, Aliases]
 | 
				
			||||||
@@ -91,7 +91,7 @@ namespace NadekoBot.Modules.Help
 | 
				
			|||||||
            
 | 
					            
 | 
				
			||||||
            await ctx.SendPaginatedConfirmAsync(page, cur =>
 | 
					            await ctx.SendPaginatedConfirmAsync(page, cur =>
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var embed = new EmbedBuilder().WithOkColor()
 | 
					                var embed = _eb.Create().WithOkColor()
 | 
				
			||||||
                    .WithTitle(GetText("list_of_modules"));
 | 
					                    .WithTitle(GetText("list_of_modules"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var localModules = topLevelModules.Skip(12 * cur)
 | 
					                var localModules = topLevelModules.Skip(12 * cur)
 | 
				
			||||||
@@ -207,7 +207,7 @@ namespace NadekoBot.Modules.Help
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            var i = 0;
 | 
					            var i = 0;
 | 
				
			||||||
            var groups = cmdsWithGroup.GroupBy(x => i++ / 48).ToArray();
 | 
					            var groups = cmdsWithGroup.GroupBy(x => i++ / 48).ToArray();
 | 
				
			||||||
            var embed = new EmbedBuilder().WithOkColor();
 | 
					            var embed = _eb.Create().WithOkColor();
 | 
				
			||||||
            foreach (var g in groups)
 | 
					            foreach (var g in groups)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var last = g.Count();
 | 
					                var last = g.Count();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,15 +22,20 @@ namespace NadekoBot.Modules.Help.Services
 | 
				
			|||||||
        private readonly IBotStrings _strings;
 | 
					        private readonly IBotStrings _strings;
 | 
				
			||||||
        private readonly DiscordPermOverrideService _dpos;
 | 
					        private readonly DiscordPermOverrideService _dpos;
 | 
				
			||||||
        private readonly BotConfigService _bss;
 | 
					        private readonly BotConfigService _bss;
 | 
				
			||||||
 | 
					        private readonly IEmbedBuilderService _eb;
 | 
				
			||||||
        private readonly Replacer _rep;
 | 
					        private readonly Replacer _rep;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public HelpService(CommandHandler ch, IBotStrings strings,
 | 
					        public HelpService(CommandHandler ch,
 | 
				
			||||||
            DiscordPermOverrideService dpos, BotConfigService bss)
 | 
					            IBotStrings strings,
 | 
				
			||||||
 | 
					            DiscordPermOverrideService dpos,
 | 
				
			||||||
 | 
					            BotConfigService bss,
 | 
				
			||||||
 | 
					            IEmbedBuilderService eb)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _ch = ch;
 | 
					            _ch = ch;
 | 
				
			||||||
            _strings = strings;
 | 
					            _strings = strings;
 | 
				
			||||||
            _dpos = dpos;
 | 
					            _dpos = dpos;
 | 
				
			||||||
            _bss = bss;
 | 
					            _bss = bss;
 | 
				
			||||||
 | 
					            _eb = eb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            _rep = new ReplacementBuilder()
 | 
					            _rep = new ReplacementBuilder()
 | 
				
			||||||
@@ -48,14 +53,14 @@ namespace NadekoBot.Modules.Help.Services
 | 
				
			|||||||
                    return Task.CompletedTask;
 | 
					                    return Task.CompletedTask;
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                if (CREmbed.TryParse(settings.DmHelpText, out var embed))
 | 
					                if (CREmbed.TryParse(settings.DmHelpText, out var embed))
 | 
				
			||||||
                    return msg.Channel.EmbedAsync(_rep.Replace(embed));
 | 
					                    return msg.Channel.EmbedAsync(_rep.Replace(embed), _eb);
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                return msg.Channel.SendMessageAsync(_rep.Replace(settings.DmHelpText));
 | 
					                return msg.Channel.SendMessageAsync(_rep.Replace(settings.DmHelpText));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            return Task.CompletedTask;
 | 
					            return Task.CompletedTask;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public EmbedBuilder GetCommandHelp(CommandInfo com, IGuild guild)
 | 
					        public IEmbedBuilder GetCommandHelp(CommandInfo com, IGuild guild)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var prefix = _ch.GetPrefix(guild);
 | 
					            var prefix = _ch.GetPrefix(guild);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -63,7 +68,7 @@ namespace NadekoBot.Modules.Help.Services
 | 
				
			|||||||
            var alias = com.Aliases.Skip(1).FirstOrDefault();
 | 
					            var alias = com.Aliases.Skip(1).FirstOrDefault();
 | 
				
			||||||
            if (alias != null)
 | 
					            if (alias != null)
 | 
				
			||||||
                str += $" **/ `{prefix + alias}`**";
 | 
					                str += $" **/ `{prefix + alias}`**";
 | 
				
			||||||
            var em = new EmbedBuilder()
 | 
					            var em = _eb.Create()
 | 
				
			||||||
                .AddField(str, $"{com.RealSummary(_strings, guild?.Id, prefix)}", true);
 | 
					                .AddField(str, $"{com.RealSummary(_strings, guild?.Id, prefix)}", true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            _dpos.TryGetOverrides(guild?.Id ?? 0, com.Name, out var overrides);
 | 
					            _dpos.TryGetOverrides(guild?.Id ?? 0, com.Name, out var overrides);
 | 
				
			||||||
@@ -79,7 +84,7 @@ namespace NadekoBot.Modules.Help.Services
 | 
				
			|||||||
                        arg => Format.Code(arg))),
 | 
					                        arg => Format.Code(arg))),
 | 
				
			||||||
                    false)
 | 
					                    false)
 | 
				
			||||||
                .WithFooter(GetText("module", guild, com.Module.GetTopLevelModule().Name))
 | 
					                .WithFooter(GetText("module", guild, com.Module.GetTopLevelModule().Name))
 | 
				
			||||||
                .WithColor(Bot.OkColor);
 | 
					                .WithOkColor();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var opt = ((NadekoOptionsAttribute)com.Attributes.FirstOrDefault(x => x is NadekoOptionsAttribute))?.OptionType;
 | 
					            var opt = ((NadekoOptionsAttribute)com.Attributes.FirstOrDefault(x => x is NadekoOptionsAttribute))?.OptionType;
 | 
				
			||||||
            if (opt != null)
 | 
					            if (opt != null)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -112,7 +112,7 @@ namespace NadekoBot.Modules.Music
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            try
 | 
					            try
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var embed = new EmbedBuilder()
 | 
					                var embed = _eb.Create()
 | 
				
			||||||
                    .WithOkColor()
 | 
					                    .WithOkColor()
 | 
				
			||||||
                    .WithAuthor(GetText("queued_song") + " #" + (index + 1), MusicIconUrl)
 | 
					                    .WithAuthor(GetText("queued_song") + " #" + (index + 1), MusicIconUrl)
 | 
				
			||||||
                    .WithDescription($"{trackInfo.PrettyName()}\n{GetText("queue")} ")
 | 
					                    .WithDescription($"{trackInfo.PrettyName()}\n{GetText("queue")} ")
 | 
				
			||||||
@@ -281,7 +281,7 @@ namespace NadekoBot.Modules.Music
 | 
				
			|||||||
                return;
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            EmbedBuilder printAction(int curPage)
 | 
					            IEmbedBuilder printAction(int curPage)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                string desc = string.Empty;
 | 
					                string desc = string.Empty;
 | 
				
			||||||
                var current = mp.GetCurrentTrack(out var currentIndex);
 | 
					                var current = mp.GetCurrentTrack(out var currentIndex);
 | 
				
			||||||
@@ -328,7 +328,7 @@ namespace NadekoBot.Modules.Music
 | 
				
			|||||||
                if (!string.IsNullOrWhiteSpace(add))
 | 
					                if (!string.IsNullOrWhiteSpace(add))
 | 
				
			||||||
                    desc = add + "\n" + desc;
 | 
					                    desc = add + "\n" + desc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var embed = new EmbedBuilder()
 | 
					                var embed = _eb.Create()
 | 
				
			||||||
                    .WithAuthor(GetText("player_queue", curPage + 1, (tracks.Count / LQ_ITEMS_PER_PAGE) + 1),
 | 
					                    .WithAuthor(GetText("player_queue", curPage + 1, (tracks.Count / LQ_ITEMS_PER_PAGE) + 1),
 | 
				
			||||||
                        MusicIconUrl)
 | 
					                        MusicIconUrl)
 | 
				
			||||||
                    .WithDescription(desc)
 | 
					                    .WithDescription(desc)
 | 
				
			||||||
@@ -365,7 +365,7 @@ namespace NadekoBot.Modules.Music
 | 
				
			|||||||
                .Select((x, i) => $"`{i + 1}.`\n\t{Format.Bold(x.Title)}\n\t{x.Url}")
 | 
					                .Select((x, i) => $"`{i + 1}.`\n\t{Format.Bold(x.Title)}\n\t{x.Url}")
 | 
				
			||||||
                .JoinWith('\n');
 | 
					                .JoinWith('\n');
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            var msg = await ctx.Channel.SendConfirmAsync(resultsString);
 | 
					            var msg = await SendConfirmAsync(resultsString);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            try
 | 
					            try
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
@@ -430,7 +430,7 @@ namespace NadekoBot.Modules.Music
 | 
				
			|||||||
                return;
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            var embed = new EmbedBuilder()
 | 
					            var embed = _eb.Create()
 | 
				
			||||||
                .WithAuthor(GetText("removed_song") + " #" + (index), MusicIconUrl)
 | 
					                .WithAuthor(GetText("removed_song") + " #" + (index), MusicIconUrl)
 | 
				
			||||||
                .WithDescription(song.PrettyName())
 | 
					                .WithDescription(song.PrettyName())
 | 
				
			||||||
                .WithFooter(song.PrettyInfo())
 | 
					                .WithFooter(song.PrettyInfo())
 | 
				
			||||||
@@ -613,12 +613,12 @@ namespace NadekoBot.Modules.Music
 | 
				
			|||||||
                 return;
 | 
					                 return;
 | 
				
			||||||
             }
 | 
					             }
 | 
				
			||||||
             
 | 
					             
 | 
				
			||||||
             var embed = new EmbedBuilder()
 | 
					             var embed = _eb.Create()
 | 
				
			||||||
                 .WithTitle(track.Title.TrimTo(65))
 | 
					                 .WithTitle(track.Title.TrimTo(65))
 | 
				
			||||||
                 .WithAuthor(GetText("song_moved"), MusicIconUrl)
 | 
					                 .WithAuthor(GetText("song_moved"), MusicIconUrl)
 | 
				
			||||||
                 .AddField(GetText("from_position"), $"#{from + 1}", true)
 | 
					                 .AddField(GetText("from_position"), $"#{from + 1}", true)
 | 
				
			||||||
                 .AddField(GetText("to_position"), $"#{to + 1}", true)
 | 
					                 .AddField(GetText("to_position"), $"#{to + 1}", true)
 | 
				
			||||||
                 .WithColor(Bot.OkColor);
 | 
					                 .WithOkColor();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
             if (Uri.IsWellFormedUriString(track.Url, UriKind.Absolute))
 | 
					             if (Uri.IsWellFormedUriString(track.Url, UriKind.Absolute))
 | 
				
			||||||
                 embed.WithUrl(track.Url);
 | 
					                 embed.WithUrl(track.Url);
 | 
				
			||||||
@@ -701,7 +701,7 @@ namespace NadekoBot.Modules.Music
 | 
				
			|||||||
             if (currentTrack is null)
 | 
					             if (currentTrack is null)
 | 
				
			||||||
                 return;
 | 
					                 return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
             var embed = new EmbedBuilder().WithOkColor()
 | 
					             var embed = _eb.Create().WithOkColor()
 | 
				
			||||||
                 .WithAuthor(GetText("now_playing"), MusicIconUrl)
 | 
					                 .WithAuthor(GetText("now_playing"), MusicIconUrl)
 | 
				
			||||||
                 .WithDescription(currentTrack.PrettyName())
 | 
					                 .WithDescription(currentTrack.PrettyName())
 | 
				
			||||||
                 .WithThumbnailUrl(currentTrack.Thumbnail)
 | 
					                 .WithThumbnailUrl(currentTrack.Thumbnail)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -61,11 +61,13 @@ namespace NadekoBot.Modules.Music
 | 
				
			|||||||
                    playlists = uow.MusicPlaylists.GetPlaylistsOnPage(num);
 | 
					                    playlists = uow.MusicPlaylists.GetPlaylistsOnPage(num);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var embed = new EmbedBuilder()
 | 
					                var embed = _eb
 | 
				
			||||||
 | 
					                    .Create(ctx)
 | 
				
			||||||
                    .WithAuthor(GetText("playlists_page", num), MusicIconUrl)
 | 
					                    .WithAuthor(GetText("playlists_page", num), MusicIconUrl)
 | 
				
			||||||
                    .WithDescription(string.Join("\n", playlists.Select(r =>
 | 
					                    .WithDescription(string.Join("\n", playlists.Select(r =>
 | 
				
			||||||
                        GetText("playlists", r.Id, r.Name, r.Author, r.Songs.Count))))
 | 
					                        GetText("playlists", r.Id, r.Name, r.Author, r.Songs.Count))))
 | 
				
			||||||
                    .WithOkColor();
 | 
					                    .WithOkColor();
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
                await ctx.Channel.EmbedAsync(embed).ConfigureAwait(false);
 | 
					                await ctx.Channel.EmbedAsync(embed).ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -122,7 +124,7 @@ namespace NadekoBot.Modules.Music
 | 
				
			|||||||
                        .Skip(cur * 20)
 | 
					                        .Skip(cur * 20)
 | 
				
			||||||
                        .Take(20)
 | 
					                        .Take(20)
 | 
				
			||||||
                        .Select(x => $"`{++i}.` [{x.Title.TrimTo(45)}]({x.Query}) `{x.Provider}`"));
 | 
					                        .Select(x => $"`{++i}.` [{x.Title.TrimTo(45)}]({x.Query}) `{x.Provider}`"));
 | 
				
			||||||
                    return new EmbedBuilder()
 | 
					                    return _eb.Create()
 | 
				
			||||||
                        .WithTitle($"\"{mpl.Name}\" by {mpl.Author}")
 | 
					                        .WithTitle($"\"{mpl.Name}\" by {mpl.Author}")
 | 
				
			||||||
                        .WithOkColor()
 | 
					                        .WithOkColor()
 | 
				
			||||||
                        .WithDescription(str);
 | 
					                        .WithDescription(str);
 | 
				
			||||||
@@ -162,7 +164,7 @@ namespace NadekoBot.Modules.Music
 | 
				
			|||||||
                    await uow.SaveChangesAsync();
 | 
					                    await uow.SaveChangesAsync();
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                await ctx.Channel.EmbedAsync(new EmbedBuilder()
 | 
					                await ctx.Channel.EmbedAsync(_eb.Create()
 | 
				
			||||||
                    .WithOkColor()
 | 
					                    .WithOkColor()
 | 
				
			||||||
                    .WithTitle(GetText("playlist_saved"))
 | 
					                    .WithTitle(GetText("playlist_saved"))
 | 
				
			||||||
                    .AddField(GetText("name"), name)
 | 
					                    .AddField(GetText("name"), name)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,7 +29,7 @@ namespace NadekoBot.Modules.Music.Services
 | 
				
			|||||||
        Task<int> EnqueueYoutubePlaylistAsync(IMusicPlayer mp, string playlistId, string queuer);
 | 
					        Task<int> EnqueueYoutubePlaylistAsync(IMusicPlayer mp, string playlistId, string queuer);
 | 
				
			||||||
        Task EnqueueDirectoryAsync(IMusicPlayer mp, string dirPath, string queuer);
 | 
					        Task EnqueueDirectoryAsync(IMusicPlayer mp, string dirPath, string queuer);
 | 
				
			||||||
        Task<int> EnqueueSoundcloudPlaylistAsync(IMusicPlayer mp, string playlist, string queuer);
 | 
					        Task<int> EnqueueSoundcloudPlaylistAsync(IMusicPlayer mp, string playlist, string queuer);
 | 
				
			||||||
        Task<IUserMessage?> SendToOutputAsync(ulong guildId, EmbedBuilder embed);
 | 
					        Task<IUserMessage?> SendToOutputAsync(ulong guildId, IEmbedBuilder embed);
 | 
				
			||||||
        Task<bool> PlayAsync(ulong guildId, ulong voiceChannelId);
 | 
					        Task<bool> PlayAsync(ulong guildId, ulong voiceChannelId);
 | 
				
			||||||
        Task<IList<(string Title, string Url)>> SearchVideosAsync(string query);
 | 
					        Task<IList<(string Title, string Url)>> SearchVideosAsync(string query);
 | 
				
			||||||
        Task<bool> SetMusicChannelAsync(ulong guildId, ulong? channelId);
 | 
					        Task<bool> SetMusicChannelAsync(ulong guildId, ulong? channelId);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,6 +29,7 @@ namespace NadekoBot.Modules.Music.Services
 | 
				
			|||||||
        private readonly IBotStrings _strings;
 | 
					        private readonly IBotStrings _strings;
 | 
				
			||||||
        private readonly IGoogleApiService _googleApiService;
 | 
					        private readonly IGoogleApiService _googleApiService;
 | 
				
			||||||
        private readonly YtLoader _ytLoader;
 | 
					        private readonly YtLoader _ytLoader;
 | 
				
			||||||
 | 
					        private readonly IEmbedBuilderService _eb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private readonly ConcurrentDictionary<ulong, IMusicPlayer> _players;
 | 
					        private readonly ConcurrentDictionary<ulong, IMusicPlayer> _players;
 | 
				
			||||||
        private readonly ConcurrentDictionary<ulong, (ITextChannel Default, ITextChannel? Override)> _outputChannels;
 | 
					        private readonly ConcurrentDictionary<ulong, (ITextChannel Default, ITextChannel? Override)> _outputChannels;
 | 
				
			||||||
@@ -36,7 +37,8 @@ namespace NadekoBot.Modules.Music.Services
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        public MusicService(AyuVoiceStateService voiceStateService, ITrackResolveProvider trackResolveProvider,
 | 
					        public MusicService(AyuVoiceStateService voiceStateService, ITrackResolveProvider trackResolveProvider,
 | 
				
			||||||
            DbService db, IYoutubeResolver ytResolver, ILocalTrackResolver localResolver, ISoundcloudResolver scResolver,
 | 
					            DbService db, IYoutubeResolver ytResolver, ILocalTrackResolver localResolver, ISoundcloudResolver scResolver,
 | 
				
			||||||
            DiscordSocketClient client, IBotStrings strings, IGoogleApiService googleApiService, YtLoader ytLoader)
 | 
					            DiscordSocketClient client, IBotStrings strings, IGoogleApiService googleApiService, YtLoader ytLoader,
 | 
				
			||||||
 | 
					            IEmbedBuilderService eb)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _voiceStateService = voiceStateService;
 | 
					            _voiceStateService = voiceStateService;
 | 
				
			||||||
            _trackResolveProvider = trackResolveProvider;
 | 
					            _trackResolveProvider = trackResolveProvider;
 | 
				
			||||||
@@ -48,6 +50,7 @@ namespace NadekoBot.Modules.Music.Services
 | 
				
			|||||||
            _strings = strings;
 | 
					            _strings = strings;
 | 
				
			||||||
            _googleApiService = googleApiService;
 | 
					            _googleApiService = googleApiService;
 | 
				
			||||||
            _ytLoader = ytLoader;
 | 
					            _ytLoader = ytLoader;
 | 
				
			||||||
 | 
					            _eb = eb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            _players = new ConcurrentDictionary<ulong, IMusicPlayer>();
 | 
					            _players = new ConcurrentDictionary<ulong, IMusicPlayer>();
 | 
				
			||||||
            _outputChannels = new ConcurrentDictionary<ulong, (ITextChannel, ITextChannel?)>();
 | 
					            _outputChannels = new ConcurrentDictionary<ulong, (ITextChannel, ITextChannel?)>();
 | 
				
			||||||
@@ -189,7 +192,7 @@ namespace NadekoBot.Modules.Music.Services
 | 
				
			|||||||
            return mp;
 | 
					            return mp;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public Task<IUserMessage?> SendToOutputAsync(ulong guildId, EmbedBuilder embed)
 | 
					        public Task<IUserMessage?> SendToOutputAsync(ulong guildId, IEmbedBuilder embed)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (_outputChannels.TryGetValue(guildId, out var chan))
 | 
					            if (_outputChannels.TryGetValue(guildId, out var chan))
 | 
				
			||||||
                return (chan.Default ?? chan.Override).EmbedAsync(embed);
 | 
					                return (chan.Default ?? chan.Override).EmbedAsync(embed);
 | 
				
			||||||
@@ -203,7 +206,7 @@ namespace NadekoBot.Modules.Music.Services
 | 
				
			|||||||
            return async (mp, trackInfo) =>
 | 
					            return async (mp, trackInfo) =>
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                _ = lastFinishedMessage?.DeleteAsync();
 | 
					                _ = lastFinishedMessage?.DeleteAsync();
 | 
				
			||||||
                var embed = new EmbedBuilder()
 | 
					                var embed = _eb.Create()
 | 
				
			||||||
                    .WithOkColor()
 | 
					                    .WithOkColor()
 | 
				
			||||||
                    .WithAuthor(GetText(guildId, "finished_song"), Music.MusicIconUrl)
 | 
					                    .WithAuthor(GetText(guildId, "finished_song"), Music.MusicIconUrl)
 | 
				
			||||||
                    .WithDescription(trackInfo.PrettyName())
 | 
					                    .WithDescription(trackInfo.PrettyName())
 | 
				
			||||||
@@ -219,7 +222,7 @@ namespace NadekoBot.Modules.Music.Services
 | 
				
			|||||||
            return async (mp, trackInfo, index) =>
 | 
					            return async (mp, trackInfo, index) =>
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                _ = lastPlayingMessage?.DeleteAsync();
 | 
					                _ = lastPlayingMessage?.DeleteAsync();
 | 
				
			||||||
                var embed = new EmbedBuilder().WithOkColor()
 | 
					                var embed = _eb.Create().WithOkColor()
 | 
				
			||||||
                    .WithAuthor(GetText(guildId, "playing_song", index + 1), Music.MusicIconUrl)
 | 
					                    .WithAuthor(GetText(guildId, "playing_song", index + 1), Music.MusicIconUrl)
 | 
				
			||||||
                    .WithDescription(trackInfo.PrettyName())
 | 
					                    .WithDescription(trackInfo.PrettyName())
 | 
				
			||||||
                    .WithFooter($"{mp.PrettyVolume()} | {trackInfo.PrettyInfo()}");
 | 
					                    .WithFooter($"{mp.PrettyVolume()} | {trackInfo.PrettyInfo()}");
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -63,13 +63,13 @@ namespace NadekoBot.Modules.NSFW
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            } while (img is null);
 | 
					            } while (img is null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            await channel.EmbedAsync(new EmbedBuilder().WithOkColor()
 | 
					            await channel.EmbedAsync(_eb.Create().WithOkColor()
 | 
				
			||||||
                .WithImageUrl(img.FileUrl)
 | 
					                .WithImageUrl(img.FileUrl)
 | 
				
			||||||
                .WithDescription($"[{GetText("tag")}: {tag}]({img})"))
 | 
					                .WithDescription($"[{GetText("tag")}: {tag}]({img})"))
 | 
				
			||||||
                .ConfigureAwait(false);
 | 
					                .ConfigureAwait(false);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private async Task InternalBoobs(IMessageChannel Channel)
 | 
					        private async Task InternalBoobs()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            try
 | 
					            try
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
@@ -78,11 +78,11 @@ namespace NadekoBot.Modules.NSFW
 | 
				
			|||||||
                {
 | 
					                {
 | 
				
			||||||
                    obj = JArray.Parse(await http.GetStringAsync($"http://api.oboobs.ru/boobs/{new NadekoRandom().Next(0, 10330)}").ConfigureAwait(false))[0];
 | 
					                    obj = JArray.Parse(await http.GetStringAsync($"http://api.oboobs.ru/boobs/{new NadekoRandom().Next(0, 10330)}").ConfigureAwait(false))[0];
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                await Channel.SendMessageAsync($"http://media.oboobs.ru/{obj["preview"]}").ConfigureAwait(false);
 | 
					                await ctx.Channel.SendMessageAsync($"http://media.oboobs.ru/{obj["preview"]}").ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            catch (Exception ex)
 | 
					            catch (Exception ex)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                await Channel.SendErrorAsync(ex.Message).ConfigureAwait(false);
 | 
					                await SendErrorAsync(ex.Message).ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        private async Task InternalButts(IMessageChannel Channel)
 | 
					        private async Task InternalButts(IMessageChannel Channel)
 | 
				
			||||||
@@ -98,7 +98,7 @@ namespace NadekoBot.Modules.NSFW
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            catch (Exception ex)
 | 
					            catch (Exception ex)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                await Channel.SendErrorAsync(ex.Message).ConfigureAwait(false);
 | 
					                await SendErrorAsync(ex.Message).ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -175,7 +175,7 @@ namespace NadekoBot.Modules.NSFW
 | 
				
			|||||||
            {
 | 
					            {
 | 
				
			||||||
                try
 | 
					                try
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    await InternalBoobs(ctx.Channel).ConfigureAwait(false);
 | 
					                    await InternalBoobs().ConfigureAwait(false);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                catch
 | 
					                catch
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
@@ -321,7 +321,7 @@ namespace NadekoBot.Modules.NSFW
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            catch (Exception ex)
 | 
					            catch (Exception ex)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                await ctx.Channel.SendErrorAsync(ex.Message).ConfigureAwait(false);
 | 
					                await SendErrorAsync(ex.Message).ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -340,7 +340,7 @@ namespace NadekoBot.Modules.NSFW
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            catch (Exception ex)
 | 
					            catch (Exception ex)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                await ctx.Channel.SendErrorAsync(ex.Message).ConfigureAwait(false);
 | 
					                await SendErrorAsync(ex.Message).ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -352,7 +352,7 @@ namespace NadekoBot.Modules.NSFW
 | 
				
			|||||||
            if (string.IsNullOrWhiteSpace(tag))
 | 
					            if (string.IsNullOrWhiteSpace(tag))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var blTags = _service.GetBlacklistedTags(ctx.Guild.Id);
 | 
					                var blTags = _service.GetBlacklistedTags(ctx.Guild.Id);
 | 
				
			||||||
                await ctx.Channel.SendConfirmAsync(GetText("blacklisted_tag_list"),
 | 
					                await SendConfirmAsync(GetText("blacklisted_tag_list"),
 | 
				
			||||||
                    blTags.Any()
 | 
					                    blTags.Any()
 | 
				
			||||||
                    ? string.Join(", ", blTags)
 | 
					                    ? string.Join(", ", blTags)
 | 
				
			||||||
                    : "-").ConfigureAwait(false);
 | 
					                    : "-").ConfigureAwait(false);
 | 
				
			||||||
@@ -419,7 +419,7 @@ namespace NadekoBot.Modules.NSFW
 | 
				
			|||||||
                .TakeWhile(tag => (count += tag.Length) < 1000)
 | 
					                .TakeWhile(tag => (count += tag.Length) < 1000)
 | 
				
			||||||
                .JoinWith(" ");
 | 
					                .JoinWith(" ");
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            var embed = new EmbedBuilder()
 | 
					            var embed = _eb.Create()
 | 
				
			||||||
                .WithTitle(g.Title)
 | 
					                .WithTitle(g.Title)
 | 
				
			||||||
                .WithDescription(g.FullTitle)
 | 
					                .WithDescription(g.FullTitle)
 | 
				
			||||||
                .WithImageUrl(g.Thumbnail)
 | 
					                .WithImageUrl(g.Thumbnail)
 | 
				
			||||||
@@ -443,7 +443,7 @@ namespace NadekoBot.Modules.NSFW
 | 
				
			|||||||
                await ReplyErrorLocalizedAsync("no_results").ConfigureAwait(false);
 | 
					                await ReplyErrorLocalizedAsync("no_results").ConfigureAwait(false);
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var embed = new EmbedBuilder().WithOkColor()
 | 
					                var embed = _eb.Create().WithOkColor()
 | 
				
			||||||
                    .WithDescription($"{ctx.User} [{tag ?? "url"}]({imgObj}) ")
 | 
					                    .WithDescription($"{ctx.User} [{tag ?? "url"}]({imgObj}) ")
 | 
				
			||||||
                    .WithFooter(type.ToString());
 | 
					                    .WithFooter(type.ToString());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -66,13 +66,13 @@ namespace NadekoBot.Modules.Permissions
 | 
				
			|||||||
                    
 | 
					                    
 | 
				
			||||||
                    if (pageItems.Count == 0)
 | 
					                    if (pageItems.Count == 0)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        return new EmbedBuilder()
 | 
					                        return _eb.Create()
 | 
				
			||||||
                            .WithOkColor()
 | 
					                            .WithOkColor()
 | 
				
			||||||
                            .WithTitle(title)
 | 
					                            .WithTitle(title)
 | 
				
			||||||
                            .WithDescription(GetText("empty_page"));
 | 
					                            .WithDescription(GetText("empty_page"));
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
                    return new EmbedBuilder()
 | 
					                    return _eb.Create()
 | 
				
			||||||
                        .WithTitle(title)
 | 
					                        .WithTitle(title)
 | 
				
			||||||
                        .WithDescription(pageItems.JoinWith('\n'))
 | 
					                        .WithDescription(pageItems.JoinWith('\n'))
 | 
				
			||||||
                        .WithOkColor();
 | 
					                        .WithOkColor();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -287,7 +287,7 @@ namespace NadekoBot.Modules.Permissions
 | 
				
			|||||||
                var fws = fwHash.ToArray();
 | 
					                var fws = fwHash.ToArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                await ctx.SendPaginatedConfirmAsync(page,
 | 
					                await ctx.SendPaginatedConfirmAsync(page,
 | 
				
			||||||
                    (curPage) => new EmbedBuilder()
 | 
					                    (curPage) => _eb.Create()
 | 
				
			||||||
                        .WithTitle(GetText("filter_word_list"))
 | 
					                        .WithTitle(GetText("filter_word_list"))
 | 
				
			||||||
                        .WithDescription(string.Join("\n", fws.Skip(curPage * 10).Take(10)))
 | 
					                        .WithDescription(string.Join("\n", fws.Skip(curPage * 10).Take(10)))
 | 
				
			||||||
                        .WithOkColor()
 | 
					                        .WithOkColor()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -36,7 +36,7 @@ namespace NadekoBot.Modules.Permissions
 | 
				
			|||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var embed = new EmbedBuilder().WithOkColor();
 | 
					                var embed = _eb.Create().WithOkColor();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (blockedModule.Any())
 | 
					                if (blockedModule.Any())
 | 
				
			||||||
                    embed.AddField(GetText("blocked_modules")
 | 
					                    embed.AddField(GetText("blocked_modules")
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,7 +12,6 @@ using NadekoBot.Modules.Permissions.Common;
 | 
				
			|||||||
using NadekoBot.Services;
 | 
					using NadekoBot.Services;
 | 
				
			||||||
using NadekoBot.Services.Database.Models;
 | 
					using NadekoBot.Services.Database.Models;
 | 
				
			||||||
using NadekoBot.Db;
 | 
					using NadekoBot.Db;
 | 
				
			||||||
using NadekoBot.Modules.Administration;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace NadekoBot.Modules.Permissions.Services
 | 
					namespace NadekoBot.Modules.Permissions.Services
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -23,20 +22,27 @@ namespace NadekoBot.Modules.Permissions.Services
 | 
				
			|||||||
        private readonly DbService _db;
 | 
					        private readonly DbService _db;
 | 
				
			||||||
        private readonly CommandHandler _cmd;
 | 
					        private readonly CommandHandler _cmd;
 | 
				
			||||||
        private readonly IBotStrings _strings;
 | 
					        private readonly IBotStrings _strings;
 | 
				
			||||||
 | 
					        private readonly IEmbedBuilderService _eb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //guildid, root permission
 | 
					        //guildid, root permission
 | 
				
			||||||
        public ConcurrentDictionary<ulong, PermissionCache> Cache { get; } =
 | 
					        public ConcurrentDictionary<ulong, PermissionCache> Cache { get; } =
 | 
				
			||||||
            new ConcurrentDictionary<ulong, PermissionCache>();
 | 
					            new ConcurrentDictionary<ulong, PermissionCache>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public PermissionService(DiscordSocketClient client, DbService db, CommandHandler cmd, IBotStrings strings)
 | 
					        public PermissionService(DiscordSocketClient client,
 | 
				
			||||||
 | 
					            DbService db,
 | 
				
			||||||
 | 
					            CommandHandler cmd,
 | 
				
			||||||
 | 
					            IBotStrings strings,
 | 
				
			||||||
 | 
					            IEmbedBuilderService eb)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _db = db;
 | 
					            _db = db;
 | 
				
			||||||
            _cmd = cmd;
 | 
					            _cmd = cmd;
 | 
				
			||||||
            _strings = strings;
 | 
					            _strings = strings;
 | 
				
			||||||
 | 
					            _eb = eb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            using (var uow = _db.GetDbContext())
 | 
					            using (var uow = _db.GetDbContext())
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                foreach (var x in uow.GuildConfigs.Permissionsv2ForAll(client.Guilds.ToArray().Select(x => x.Id).ToList()))
 | 
					                foreach (var x in uow.GuildConfigs.Permissionsv2ForAll(client.Guilds.ToArray().Select(x => x.Id)
 | 
				
			||||||
 | 
					                    .ToList()))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    Cache.TryAdd(x.GuildId, new PermissionCache()
 | 
					                    Cache.TryAdd(x.GuildId, new PermissionCache()
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
@@ -122,7 +128,8 @@ namespace NadekoBot.Modules.Permissions.Services
 | 
				
			|||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        try
 | 
					                        try
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            await channel.SendErrorAsync(_strings.GetText("perm_prevent", guild.Id, index + 1,
 | 
					                            await channel.SendErrorAsync(_eb, 
 | 
				
			||||||
 | 
					                                    _strings.GetText("perm_prevent", guild.Id, index + 1,
 | 
				
			||||||
                                    Format.Bold(pc.Permissions[index].GetCommand(_cmd.GetPrefix(guild), (SocketGuild) guild))))
 | 
					                                    Format.Bold(pc.Permissions[index].GetCommand(_cmd.GetPrefix(guild), (SocketGuild) guild))))
 | 
				
			||||||
                                .ConfigureAwait(false);
 | 
					                                .ConfigureAwait(false);
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
@@ -152,7 +159,7 @@ namespace NadekoBot.Modules.Permissions.Services
 | 
				
			|||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        returnMsg = $"You need Admin permissions in order to use permission commands.";
 | 
					                        returnMsg = $"You need Admin permissions in order to use permission commands.";
 | 
				
			||||||
                        if (pc.Verbose)
 | 
					                        if (pc.Verbose)
 | 
				
			||||||
                            try { await channel.SendErrorAsync(returnMsg).ConfigureAwait(false); } catch { }
 | 
					                            try { await channel.SendErrorAsync(_eb, returnMsg).ConfigureAwait(false); } catch { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        return true;
 | 
					                        return true;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
@@ -160,7 +167,7 @@ namespace NadekoBot.Modules.Permissions.Services
 | 
				
			|||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        returnMsg = $"You need the {Format.Bold(role.Name)} role in order to use permission commands.";
 | 
					                        returnMsg = $"You need the {Format.Bold(role.Name)} role in order to use permission commands.";
 | 
				
			||||||
                        if (pc.Verbose)
 | 
					                        if (pc.Verbose)
 | 
				
			||||||
                            try { await channel.SendErrorAsync(returnMsg).ConfigureAwait(false); } catch { }
 | 
					                            try { await channel.SendErrorAsync(_eb, returnMsg).ConfigureAwait(false); } catch { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        return true;
 | 
					                        return true;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,7 +30,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var embed = new EmbedBuilder()
 | 
					                var embed = _eb.Create()
 | 
				
			||||||
                    .WithOkColor()
 | 
					                    .WithOkColor()
 | 
				
			||||||
                    .WithDescription(novelData.Description.Replace("<br>", Environment.NewLine, StringComparison.InvariantCulture))
 | 
					                    .WithDescription(novelData.Description.Replace("<br>", Environment.NewLine, StringComparison.InvariantCulture))
 | 
				
			||||||
                    .WithTitle(novelData.Title)
 | 
					                    .WithTitle(novelData.Title)
 | 
				
			||||||
@@ -81,7 +81,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
                        .Select(x => x.TextContent.Split(':').Select(y => y.Trim()).ToArray())
 | 
					                        .Select(x => x.TextContent.Split(':').Select(y => y.Trim()).ToArray())
 | 
				
			||||||
                        .ToArray();
 | 
					                        .ToArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    var embed = new EmbedBuilder()
 | 
					                    var embed = _eb.Create()
 | 
				
			||||||
                        .WithOkColor()
 | 
					                        .WithOkColor()
 | 
				
			||||||
                        .WithTitle(GetText("mal_profile", name))
 | 
					                        .WithTitle(GetText("mal_profile", name))
 | 
				
			||||||
                        .AddField("💚 " + GetText("watching"), stats[0], true)
 | 
					                        .AddField("💚 " + GetText("watching"), stats[0], true)
 | 
				
			||||||
@@ -150,7 +150,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var embed = new EmbedBuilder()
 | 
					                var embed = _eb.Create()
 | 
				
			||||||
                    .WithOkColor()
 | 
					                    .WithOkColor()
 | 
				
			||||||
                    .WithDescription(animeData.Synopsis.Replace("<br>", Environment.NewLine, StringComparison.InvariantCulture))
 | 
					                    .WithDescription(animeData.Synopsis.Replace("<br>", Environment.NewLine, StringComparison.InvariantCulture))
 | 
				
			||||||
                    .WithTitle(animeData.TitleEnglish)
 | 
					                    .WithTitle(animeData.TitleEnglish)
 | 
				
			||||||
@@ -178,7 +178,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var embed = new EmbedBuilder()
 | 
					                var embed = _eb.Create()
 | 
				
			||||||
                    .WithOkColor()
 | 
					                    .WithOkColor()
 | 
				
			||||||
                    .WithDescription(mangaData.Synopsis.Replace("<br>", Environment.NewLine, StringComparison.InvariantCulture))
 | 
					                    .WithDescription(mangaData.Synopsis.Replace("<br>", Environment.NewLine, StringComparison.InvariantCulture))
 | 
				
			||||||
                    .WithTitle(mangaData.TitleEnglish)
 | 
					                    .WithTitle(mangaData.TitleEnglish)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,7 +22,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                if (nearest != null)
 | 
					                if (nearest != null)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    var embed = new EmbedBuilder()
 | 
					                    var embed = _eb.Create()
 | 
				
			||||||
                            .WithTitle(GetText("crypto_not_found"))
 | 
					                            .WithTitle(GetText("crypto_not_found"))
 | 
				
			||||||
                            .WithDescription(GetText("did_you_mean", Format.Bold($"{nearest.Name} ({nearest.Symbol})")));
 | 
					                            .WithDescription(GetText("did_you_mean", Format.Bold($"{nearest.Name} ({nearest.Symbol})")));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -46,7 +46,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
                        ? ld.ToString("F2")
 | 
					                        ? ld.ToString("F2")
 | 
				
			||||||
                        : crypto.Quote.Usd.Percent_Change_24h;
 | 
					                        : crypto.Quote.Usd.Percent_Change_24h;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                await ctx.Channel.EmbedAsync(new EmbedBuilder()
 | 
					                await ctx.Channel.EmbedAsync(_eb.Create()
 | 
				
			||||||
                    .WithOkColor()
 | 
					                    .WithOkColor()
 | 
				
			||||||
                    .WithTitle($"{crypto.Name} ({crypto.Symbol})")
 | 
					                    .WithTitle($"{crypto.Name} ({crypto.Symbol})")
 | 
				
			||||||
                    .WithUrl($"https://coinmarketcap.com/currencies/{crypto.Slug}/")
 | 
					                    .WithUrl($"https://coinmarketcap.com/currencies/{crypto.Slug}/")
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -71,7 +71,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                if (!feeds.Any())
 | 
					                if (!feeds.Any())
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    await ctx.Channel.EmbedAsync(new EmbedBuilder()
 | 
					                    await ctx.Channel.EmbedAsync(_eb.Create()
 | 
				
			||||||
                        .WithOkColor()
 | 
					                        .WithOkColor()
 | 
				
			||||||
                        .WithDescription(GetText("feed_no_feed")))
 | 
					                        .WithDescription(GetText("feed_no_feed")))
 | 
				
			||||||
                        .ConfigureAwait(false);
 | 
					                        .ConfigureAwait(false);
 | 
				
			||||||
@@ -80,7 +80,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                await ctx.SendPaginatedConfirmAsync(0, (cur) =>
 | 
					                await ctx.SendPaginatedConfirmAsync(0, (cur) =>
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    var embed = new EmbedBuilder()
 | 
					                    var embed = _eb.Create()
 | 
				
			||||||
                       .WithOkColor();
 | 
					                       .WithOkColor();
 | 
				
			||||||
                    var i = 0;
 | 
					                    var i = 0;
 | 
				
			||||||
                    var fs = string.Join("\n", feeds.Skip(cur * 10)
 | 
					                    var fs = string.Join("\n", feeds.Skip(cur * 10)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,20 +17,20 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
            [NadekoCommand, Aliases]
 | 
					            [NadekoCommand, Aliases]
 | 
				
			||||||
            public async Task Yomama()
 | 
					            public async Task Yomama()
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                await ctx.Channel.SendConfirmAsync(await _service.GetYomamaJoke().ConfigureAwait(false)).ConfigureAwait(false);
 | 
					                await SendConfirmAsync(await _service.GetYomamaJoke().ConfigureAwait(false)).ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            [NadekoCommand, Aliases]
 | 
					            [NadekoCommand, Aliases]
 | 
				
			||||||
            public async Task Randjoke()
 | 
					            public async Task Randjoke()
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var (setup, punchline) = await _service.GetRandomJoke().ConfigureAwait(false);
 | 
					                var (setup, punchline) = await _service.GetRandomJoke().ConfigureAwait(false);
 | 
				
			||||||
                await ctx.Channel.SendConfirmAsync(setup, punchline).ConfigureAwait(false);
 | 
					                await SendConfirmAsync(setup, punchline).ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            [NadekoCommand, Aliases]
 | 
					            [NadekoCommand, Aliases]
 | 
				
			||||||
            public async Task ChuckNorris()
 | 
					            public async Task ChuckNorris()
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                await ctx.Channel.SendConfirmAsync(await _service.GetChuckNorrisJoke().ConfigureAwait(false)).ConfigureAwait(false);
 | 
					                await SendConfirmAsync(await _service.GetChuckNorrisJoke().ConfigureAwait(false)).ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            [NadekoCommand, Aliases]
 | 
					            [NadekoCommand, Aliases]
 | 
				
			||||||
@@ -42,7 +42,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                var joke = _service.WowJokes[new NadekoRandom().Next(0, _service.WowJokes.Count)];
 | 
					                var joke = _service.WowJokes[new NadekoRandom().Next(0, _service.WowJokes.Count)];
 | 
				
			||||||
                await ctx.Channel.SendConfirmAsync(joke.Question, joke.Answer).ConfigureAwait(false);
 | 
					                await SendConfirmAsync(joke.Question, joke.Answer).ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            [NadekoCommand, Aliases]
 | 
					            [NadekoCommand, Aliases]
 | 
				
			||||||
@@ -55,7 +55,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
                var item = _service.MagicItems[new NadekoRandom().Next(0, _service.MagicItems.Count)];
 | 
					                var item = _service.MagicItems[new NadekoRandom().Next(0, _service.MagicItems.Count)];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                await ctx.Channel.SendConfirmAsync("✨" + item.Name, item.Description).ConfigureAwait(false);
 | 
					                await SendConfirmAsync("✨" + item.Name, item.Description).ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -63,7 +63,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            templates += $"**{template.Name}:**\n key: `{template.Id}`\n";
 | 
					                            templates += $"**{template.Name}:**\n key: `{template.Id}`\n";
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        var embed = new EmbedBuilder()
 | 
					                        var embed = _eb.Create()
 | 
				
			||||||
                            .WithOkColor()
 | 
					                            .WithOkColor()
 | 
				
			||||||
                            .WithDescription(templates);
 | 
					                            .WithDescription(templates);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -64,7 +64,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
                        var obj = objs[0];
 | 
					                        var obj = objs[0];
 | 
				
			||||||
                        var userId = obj.UserId;
 | 
					                        var userId = obj.UserId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        await ctx.Channel.EmbedAsync(new EmbedBuilder()
 | 
					                        await ctx.Channel.EmbedAsync(_eb.Create()
 | 
				
			||||||
                            .WithOkColor()
 | 
					                            .WithOkColor()
 | 
				
			||||||
                            .WithTitle($"osu! {smode} profile for {user}")
 | 
					                            .WithTitle($"osu! {smode} profile for {user}")
 | 
				
			||||||
                            .WithThumbnailUrl($"https://a.ppy.sh/{userId}")
 | 
					                            .WithThumbnailUrl($"https://a.ppy.sh/{userId}")
 | 
				
			||||||
@@ -116,7 +116,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
                    var userData = JsonConvert.DeserializeObject<GatariUserResponse>(usrResString).Users[0];
 | 
					                    var userData = JsonConvert.DeserializeObject<GatariUserResponse>(usrResString).Users[0];
 | 
				
			||||||
                    var userStats = statsResponse.Stats;
 | 
					                    var userStats = statsResponse.Stats;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    var embed = new EmbedBuilder()
 | 
					                    var embed = _eb.Create()
 | 
				
			||||||
                        .WithOkColor()
 | 
					                        .WithOkColor()
 | 
				
			||||||
                        .WithTitle($"osu!Gatari {modeStr} profile for {user}")
 | 
					                        .WithTitle($"osu!Gatari {modeStr} profile for {user}")
 | 
				
			||||||
                        .WithThumbnailUrl($"https://a.gatari.pw/{userStats.Id}")
 | 
					                        .WithThumbnailUrl($"https://a.gatari.pw/{userStats.Id}")
 | 
				
			||||||
@@ -134,17 +134,16 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            [NadekoCommand, Aliases]
 | 
					            [NadekoCommand, Aliases]
 | 
				
			||||||
            public async Task Osu5(string user, [Leftover] string mode = null)
 | 
					            public async Task Osu5(string user, [Leftover] string mode = null)
 | 
				
			||||||
            {
 | 
					            {;
 | 
				
			||||||
                var channel = (ITextChannel) ctx.Channel;
 | 
					 | 
				
			||||||
                if (string.IsNullOrWhiteSpace(_creds.OsuApiKey))
 | 
					                if (string.IsNullOrWhiteSpace(_creds.OsuApiKey))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    await channel.SendErrorAsync("An osu! API key is required.").ConfigureAwait(false);
 | 
					                    await SendErrorAsync("An osu! API key is required.").ConfigureAwait(false);
 | 
				
			||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (string.IsNullOrWhiteSpace(user))
 | 
					                if (string.IsNullOrWhiteSpace(user))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    await channel.SendErrorAsync("Please provide a username.").ConfigureAwait(false);
 | 
					                    await SendErrorAsync("Please provide a username.").ConfigureAwait(false);
 | 
				
			||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -192,17 +191,17 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
                        return (title, desc);
 | 
					                        return (title, desc);
 | 
				
			||||||
                    });
 | 
					                    });
 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
                    var eb = new EmbedBuilder()
 | 
					                    var eb = _eb.Create()
 | 
				
			||||||
                        .WithOkColor()
 | 
					                        .WithOkColor()
 | 
				
			||||||
                        .WithTitle($"Top 5 plays for {user}");
 | 
					                        .WithTitle($"Top 5 plays for {user}");
 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
                    var mapData = await Task.WhenAll(mapTasks);
 | 
					                    var mapData = await Task.WhenAll(mapTasks);
 | 
				
			||||||
                    foreach (var (title, desc) in mapData.Where(x => x != default))
 | 
					                    foreach (var (title, desc) in mapData.Where(x => x != default))
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        eb.AddField(title, desc, inline: false);
 | 
					                        eb.AddField(title, desc, false);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    await channel.EmbedAsync(eb).ConfigureAwait(false);
 | 
					                    await ctx.Channel.EmbedAsync(eb).ConfigureAwait(false);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -43,7 +43,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                if (string.IsNullOrWhiteSpace(usr))
 | 
					                if (string.IsNullOrWhiteSpace(usr))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    await ctx.Channel.SendErrorAsync("Please provide an account name.").ConfigureAwait(false);
 | 
					                    await SendErrorAsync("Please provide an account name.").ConfigureAwait(false);
 | 
				
			||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -59,7 +59,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
                catch
 | 
					                catch
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    var embed = new EmbedBuilder()
 | 
					                    var embed = _eb.Create()
 | 
				
			||||||
                                    .WithDescription(GetText("account_not_found"))
 | 
					                                    .WithDescription(GetText("account_not_found"))
 | 
				
			||||||
                                    .WithErrorColor();
 | 
					                                    .WithErrorColor();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -74,7 +74,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                await ctx.SendPaginatedConfirmAsync(page, (curPage) =>
 | 
					                await ctx.SendPaginatedConfirmAsync(page, (curPage) =>
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    var embed = new EmbedBuilder()
 | 
					                    var embed = _eb.Create()
 | 
				
			||||||
                        .WithAuthor($"Characters on {usr}'s account",
 | 
					                        .WithAuthor($"Characters on {usr}'s account",
 | 
				
			||||||
                            "https://web.poecdn.com/image/favicon/ogimage.png",
 | 
					                            "https://web.poecdn.com/image/favicon/ogimage.png",
 | 
				
			||||||
                            $"{_profileURL}{usr}")
 | 
					                            $"{_profileURL}{usr}")
 | 
				
			||||||
@@ -120,7 +120,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
                catch
 | 
					                catch
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    var eembed = new EmbedBuilder()
 | 
					                    var eembed = _eb.Create()
 | 
				
			||||||
                        .WithDescription(GetText("leagues_not_found"))
 | 
					                        .WithDescription(GetText("leagues_not_found"))
 | 
				
			||||||
                        .WithErrorColor();
 | 
					                        .WithErrorColor();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -128,7 +128,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var embed = new EmbedBuilder()
 | 
					                var embed = _eb.Create()
 | 
				
			||||||
                    .WithAuthor($"Path of Exile Leagues",
 | 
					                    .WithAuthor($"Path of Exile Leagues",
 | 
				
			||||||
                        "https://web.poecdn.com/image/favicon/ogimage.png",
 | 
					                        "https://web.poecdn.com/image/favicon/ogimage.png",
 | 
				
			||||||
                        "https://www.pathofexile.com")
 | 
					                        "https://www.pathofexile.com")
 | 
				
			||||||
@@ -154,12 +154,12 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
            {
 | 
					            {
 | 
				
			||||||
                if (string.IsNullOrWhiteSpace(leagueName))
 | 
					                if (string.IsNullOrWhiteSpace(leagueName))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    await ctx.Channel.SendErrorAsync("Please provide league name.").ConfigureAwait(false);
 | 
					                    await SendErrorAsync("Please provide league name.").ConfigureAwait(false);
 | 
				
			||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                if (string.IsNullOrWhiteSpace(currencyName))
 | 
					                if (string.IsNullOrWhiteSpace(currencyName))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    await ctx.Channel.SendErrorAsync("Please provide currency name.").ConfigureAwait(false);
 | 
					                    await SendErrorAsync("Please provide currency name.").ConfigureAwait(false);
 | 
				
			||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -201,7 +201,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
                            conversionEquivalent = float.Parse(currencyOutput["chaosEquivalent"].ToString(), System.Globalization.CultureInfo.InvariantCulture);
 | 
					                            conversionEquivalent = float.Parse(currencyOutput["chaosEquivalent"].ToString(), System.Globalization.CultureInfo.InvariantCulture);
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        var embed = new EmbedBuilder()
 | 
					                        var embed = _eb.Create()
 | 
				
			||||||
                            .WithAuthor($"{leagueName} Currency Exchange",
 | 
					                            .WithAuthor($"{leagueName} Currency Exchange",
 | 
				
			||||||
                                "https://web.poecdn.com/image/favicon/ogimage.png",
 | 
					                                "https://web.poecdn.com/image/favicon/ogimage.png",
 | 
				
			||||||
                                "http://poe.ninja")
 | 
					                                "http://poe.ninja")
 | 
				
			||||||
@@ -214,7 +214,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
                catch
 | 
					                catch
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    var embed = new EmbedBuilder()
 | 
					                    var embed = _eb.Create()
 | 
				
			||||||
                        .WithDescription(GetText("ninja_not_found"))
 | 
					                        .WithDescription(GetText("ninja_not_found"))
 | 
				
			||||||
                        .WithErrorColor();
 | 
					                        .WithErrorColor();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,7 +30,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
            [NadekoCommand, Aliases]
 | 
					            [NadekoCommand, Aliases]
 | 
				
			||||||
            public async Task Placelist()
 | 
					            public async Task Placelist()
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                await ctx.Channel.SendConfirmAsync(GetText("list_of_place_tags", Prefix), 
 | 
					                await SendConfirmAsync(GetText("list_of_place_tags", Prefix), 
 | 
				
			||||||
                    _typesStr)
 | 
					                    _typesStr)
 | 
				
			||||||
                             .ConfigureAwait(false);
 | 
					                             .ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,7 +39,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
                    if (kvp.Key.ToUpperInvariant() == pokemon.ToUpperInvariant())
 | 
					                    if (kvp.Key.ToUpperInvariant() == pokemon.ToUpperInvariant())
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        var p = kvp.Value;
 | 
					                        var p = kvp.Value;
 | 
				
			||||||
                        await ctx.Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
 | 
					                        await ctx.Channel.EmbedAsync(_eb.Create().WithOkColor()
 | 
				
			||||||
                            .WithTitle(kvp.Key.ToTitleCase())
 | 
					                            .WithTitle(kvp.Key.ToTitleCase())
 | 
				
			||||||
                            .WithDescription(p.BaseStats.ToString())
 | 
					                            .WithDescription(p.BaseStats.ToString())
 | 
				
			||||||
                            .WithThumbnailUrl($"https://assets.pokemon.com/assets/cms2/img/pokedex/detail/{p.Id.ToString("000")}.png")
 | 
					                            .WithThumbnailUrl($"https://assets.pokemon.com/assets/cms2/img/pokedex/detail/{p.Id.ToString("000")}.png")
 | 
				
			||||||
@@ -62,7 +62,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
                {
 | 
					                {
 | 
				
			||||||
                    if (kvp.Key.ToUpperInvariant() == ability)
 | 
					                    if (kvp.Key.ToUpperInvariant() == ability)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        await ctx.Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
 | 
					                        await ctx.Channel.EmbedAsync(_eb.Create().WithOkColor()
 | 
				
			||||||
                            .WithTitle(kvp.Value.Name)
 | 
					                            .WithTitle(kvp.Value.Name)
 | 
				
			||||||
                            .WithDescription(string.IsNullOrWhiteSpace(kvp.Value.Desc)
 | 
					                            .WithDescription(string.IsNullOrWhiteSpace(kvp.Value.Desc)
 | 
				
			||||||
                                ? kvp.Value.ShortDesc
 | 
					                                ? kvp.Value.ShortDesc
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -68,7 +68,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
            if (!await ValidateQuery(ctx.Channel, query).ConfigureAwait(false))
 | 
					            if (!await ValidateQuery(ctx.Channel, query).ConfigureAwait(false))
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var embed = new EmbedBuilder();
 | 
					            var embed = _eb.Create();
 | 
				
			||||||
            var data = await _service.GetWeatherDataAsync(query).ConfigureAwait(false);
 | 
					            var data = await _service.GetWeatherDataAsync(query).ConfigureAwait(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (data is null)
 | 
					            if (data is null)
 | 
				
			||||||
@@ -140,12 +140,12 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
                return;
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var eb = new EmbedBuilder()
 | 
					            var eb = _eb.Create()
 | 
				
			||||||
                .WithOkColor()
 | 
					                .WithOkColor()
 | 
				
			||||||
                .WithTitle(GetText("time_new"))
 | 
					                .WithTitle(GetText("time_new"))
 | 
				
			||||||
                .WithDescription(Format.Code(data.Time.ToString()))
 | 
					                .WithDescription(Format.Code(data.Time.ToString()))
 | 
				
			||||||
                .AddField(GetText("location"), string.Join('\n', data.Address.Split(", ")), inline: true)
 | 
					                .AddField(GetText("location"), string.Join('\n', data.Address.Split(", ")), true)
 | 
				
			||||||
                .AddField(GetText("timezone"), data.TimeZoneName, inline: true);
 | 
					                .AddField(GetText("timezone"), data.TimeZoneName, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            await ctx.Channel.SendMessageAsync(embed: eb.Build()).ConfigureAwait(false);
 | 
					            await ctx.Channel.SendMessageAsync(embed: eb.Build()).ConfigureAwait(false);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -180,7 +180,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
                await ReplyErrorLocalizedAsync("imdb_fail").ConfigureAwait(false);
 | 
					                await ReplyErrorLocalizedAsync("imdb_fail").ConfigureAwait(false);
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            await ctx.Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
 | 
					            await ctx.Channel.EmbedAsync(_eb.Create().WithOkColor()
 | 
				
			||||||
                .WithTitle(movie.Title)
 | 
					                .WithTitle(movie.Title)
 | 
				
			||||||
                .WithUrl($"http://www.imdb.com/title/{movie.ImdbId}/")
 | 
					                .WithUrl($"http://www.imdb.com/title/{movie.ImdbId}/")
 | 
				
			||||||
                .WithDescription(movie.Plot.TrimTo(1000))
 | 
					                .WithDescription(movie.Plot.TrimTo(1000))
 | 
				
			||||||
@@ -205,7 +205,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
        private Task InternalRandomImage(SearchesService.ImageTag tag)
 | 
					        private Task InternalRandomImage(SearchesService.ImageTag tag)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var url = _service.GetRandomImageUrl(tag);
 | 
					            var url = _service.GetRandomImageUrl(tag);
 | 
				
			||||||
            return ctx.Channel.EmbedAsync(new EmbedBuilder()
 | 
					            return ctx.Channel.EmbedAsync(_eb.Create()
 | 
				
			||||||
                .WithOkColor()
 | 
					                .WithOkColor()
 | 
				
			||||||
                .WithImageUrl(url));
 | 
					                .WithImageUrl(url));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -220,7 +220,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
            try
 | 
					            try
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var res = await _google.GetImageAsync(oterms).ConfigureAwait(false);
 | 
					                var res = await _google.GetImageAsync(oterms).ConfigureAwait(false);
 | 
				
			||||||
                var embed = new EmbedBuilder()
 | 
					                var embed = _eb.Create()
 | 
				
			||||||
                    .WithOkColor()
 | 
					                    .WithOkColor()
 | 
				
			||||||
                    .WithAuthor(GetText("image_search_for") + " " + oterms.TrimTo(50),
 | 
					                    .WithAuthor(GetText("image_search_for") + " " + oterms.TrimTo(50),
 | 
				
			||||||
                        "http://i.imgur.com/G46fm8J.png",
 | 
					                        "http://i.imgur.com/G46fm8J.png",
 | 
				
			||||||
@@ -250,7 +250,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                    var source = img.Source.Replace("b.", ".", StringComparison.InvariantCulture);
 | 
					                    var source = img.Source.Replace("b.", ".", StringComparison.InvariantCulture);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    var embed = new EmbedBuilder()
 | 
					                    var embed = _eb.Create()
 | 
				
			||||||
                        .WithOkColor()
 | 
					                        .WithOkColor()
 | 
				
			||||||
                        .WithAuthor(GetText("image_search_for") + " " + oterms.TrimTo(50),
 | 
					                        .WithAuthor(GetText("image_search_for") + " " + oterms.TrimTo(50),
 | 
				
			||||||
                            "http://s.imgur.com/images/logo-1200-630.jpg?",
 | 
					                            "http://s.imgur.com/images/logo-1200-630.jpg?",
 | 
				
			||||||
@@ -269,8 +269,8 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
            if (!await ValidateQuery(ctx.Channel, ffs).ConfigureAwait(false))
 | 
					            if (!await ValidateQuery(ctx.Channel, ffs).ConfigureAwait(false))
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            await ctx.Channel.SendConfirmAsync("<" + await _google.ShortenUrl($"http://lmgtfy.com/?q={ Uri.EscapeUriString(ffs) }").ConfigureAwait(false) + ">")
 | 
					            var shortenedUrl = await _google.ShortenUrl($"http://lmgtfy.com/?q={Uri.EscapeUriString(ffs)}");
 | 
				
			||||||
                           .ConfigureAwait(false);
 | 
					            await SendConfirmAsync($"<{shortenedUrl}>");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public class ShortenData
 | 
					        public class ShortenData
 | 
				
			||||||
@@ -322,8 +322,8 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            await ctx.Channel.EmbedAsync(new EmbedBuilder()
 | 
					            await ctx.Channel.EmbedAsync(_eb.Create()
 | 
				
			||||||
                .WithColor(Bot.OkColor)
 | 
					                .WithOkColor()
 | 
				
			||||||
                .AddField(GetText("original_url"), $"<{query}>")
 | 
					                .AddField(GetText("original_url"), $"<{query}>")
 | 
				
			||||||
                .AddField(GetText("short_url"), $"<{shortLink}>"));
 | 
					                .AddField(GetText("short_url"), $"<{shortLink}>"));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -350,7 +350,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            var descStr = string.Join("\n\n", desc);
 | 
					            var descStr = string.Join("\n\n", desc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var embed = new EmbedBuilder()
 | 
					            var embed = _eb.Create()
 | 
				
			||||||
                .WithAuthor(ctx.User.ToString(),
 | 
					                .WithAuthor(ctx.User.ToString(),
 | 
				
			||||||
                    iconUrl: "http://i.imgur.com/G46fm8J.png")
 | 
					                    iconUrl: "http://i.imgur.com/G46fm8J.png")
 | 
				
			||||||
                .WithTitle(ctx.User.ToString())
 | 
					                .WithTitle(ctx.User.ToString())
 | 
				
			||||||
@@ -383,7 +383,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            var descStr = string.Join("\n\n", desc);
 | 
					            var descStr = string.Join("\n\n", desc);
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            var embed = new EmbedBuilder()
 | 
					            var embed = _eb.Create()
 | 
				
			||||||
                .WithAuthor(ctx.User.ToString(),
 | 
					                .WithAuthor(ctx.User.ToString(),
 | 
				
			||||||
                    iconUrl: "https://upload.wikimedia.org/wikipedia/en/9/90/The_DuckDuckGo_Duck.png")
 | 
					                    iconUrl: "https://upload.wikimedia.org/wikipedia/en/9/90/The_DuckDuckGo_Duck.png")
 | 
				
			||||||
                .WithDescription($"{GetText("search_for")} **{query}**\n\n" + descStr)
 | 
					                .WithDescription($"{GetText("search_for")} **{query}**\n\n" + descStr)
 | 
				
			||||||
@@ -407,7 +407,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
                return;
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var embed = new EmbedBuilder().WithOkColor()
 | 
					            var embed = _eb.Create().WithOkColor()
 | 
				
			||||||
                .WithTitle(card.Name)
 | 
					                .WithTitle(card.Name)
 | 
				
			||||||
                .WithDescription(card.Description)
 | 
					                .WithDescription(card.Description)
 | 
				
			||||||
                .WithImageUrl(card.ImageUrl)
 | 
					                .WithImageUrl(card.ImageUrl)
 | 
				
			||||||
@@ -439,7 +439,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
                await ReplyErrorLocalizedAsync("card_not_found").ConfigureAwait(false);
 | 
					                await ReplyErrorLocalizedAsync("card_not_found").ConfigureAwait(false);
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            var embed = new EmbedBuilder().WithOkColor()
 | 
					            var embed = _eb.Create().WithOkColor()
 | 
				
			||||||
                .WithImageUrl(card.Img);
 | 
					                .WithImageUrl(card.Img);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (!string.IsNullOrWhiteSpace(card.Flavor))
 | 
					            if (!string.IsNullOrWhiteSpace(card.Flavor))
 | 
				
			||||||
@@ -467,7 +467,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
                        await ctx.SendPaginatedConfirmAsync(0, (p) =>
 | 
					                        await ctx.SendPaginatedConfirmAsync(0, (p) =>
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            var item = items[p];
 | 
					                            var item = items[p];
 | 
				
			||||||
                            return new EmbedBuilder().WithOkColor()
 | 
					                            return _eb.Create().WithOkColor()
 | 
				
			||||||
                                         .WithUrl(item.Permalink)
 | 
					                                         .WithUrl(item.Permalink)
 | 
				
			||||||
                                         .WithAuthor(item.Word)
 | 
					                                         .WithAuthor(item.Word)
 | 
				
			||||||
                                         .WithDescription(item.Definition);
 | 
					                                         .WithDescription(item.Definition);
 | 
				
			||||||
@@ -529,10 +529,10 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
                    await ctx.SendPaginatedConfirmAsync(0, page =>
 | 
					                    await ctx.SendPaginatedConfirmAsync(0, page =>
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        var data = col.Skip(page).First();
 | 
					                        var data = col.Skip(page).First();
 | 
				
			||||||
                        var embed = new EmbedBuilder()
 | 
					                        var embed = _eb.Create()
 | 
				
			||||||
                            .WithDescription(ctx.User.Mention)
 | 
					                            .WithDescription(ctx.User.Mention)
 | 
				
			||||||
                            .AddField(GetText("word"), data.Word, inline: true)
 | 
					                            .AddField(GetText("word"), data.Word, true)
 | 
				
			||||||
                            .AddField(GetText("class"), data.WordType, inline: true)
 | 
					                            .AddField(GetText("class"), data.WordType, true)
 | 
				
			||||||
                            .AddField(GetText("definition"), data.Definition)
 | 
					                            .AddField(GetText("definition"), data.Definition)
 | 
				
			||||||
                            .WithOkColor();
 | 
					                            .WithOkColor();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -559,7 +559,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var fact = JObject.Parse(response)["fact"].ToString();
 | 
					                var fact = JObject.Parse(response)["fact"].ToString();
 | 
				
			||||||
                await ctx.Channel.SendConfirmAsync("🐈" + GetText("catfact"), fact).ConfigureAwait(false);
 | 
					                await SendConfirmAsync("🐈" + GetText("catfact"), fact).ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -575,7 +575,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
            if (av is null)
 | 
					            if (av is null)
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            await ctx.Channel.SendConfirmAsync($"https://images.google.com/searchbyimage?image_url={av}").ConfigureAwait(false);
 | 
					            await SendConfirmAsync($"https://images.google.com/searchbyimage?image_url={av}").ConfigureAwait(false);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //done in 3.0
 | 
					        //done in 3.0
 | 
				
			||||||
@@ -586,12 +586,12 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            if (string.IsNullOrWhiteSpace(imageLink))
 | 
					            if (string.IsNullOrWhiteSpace(imageLink))
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
            await ctx.Channel.SendConfirmAsync($"https://images.google.com/searchbyimage?image_url={imageLink}").ConfigureAwait(false);
 | 
					            await SendConfirmAsync($"https://images.google.com/searchbyimage?image_url={imageLink}").ConfigureAwait(false);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [NadekoCommand, Aliases]
 | 
					        [NadekoCommand, Aliases]
 | 
				
			||||||
        public Task Safebooru([Leftover] string tag = null)
 | 
					        public Task Safebooru([Leftover] string tag = null)
 | 
				
			||||||
            => InternalDapiCommand(ctx.Message, tag, DapiSearchType.Safebooru);
 | 
					            => InternalDapiCommand(tag, DapiSearchType.Safebooru);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [NadekoCommand, Aliases]
 | 
					        [NadekoCommand, Aliases]
 | 
				
			||||||
        public async Task Wiki([Leftover] string query = null)
 | 
					        public async Task Wiki([Leftover] string query = null)
 | 
				
			||||||
@@ -655,7 +655,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
                return;
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            await ctx.Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
 | 
					            await ctx.Channel.EmbedAsync(_eb.Create().WithOkColor()
 | 
				
			||||||
                .AddField("Username", usr.ToString(), false)
 | 
					                .AddField("Username", usr.ToString(), false)
 | 
				
			||||||
                .AddField("Avatar Url", avatarUrl, false)
 | 
					                .AddField("Avatar Url", avatarUrl, false)
 | 
				
			||||||
                .WithThumbnailUrl(avatarUrl.ToString()), ctx.User.Mention).ConfigureAwait(false);
 | 
					                .WithThumbnailUrl(avatarUrl.ToString()), ctx.User.Mention).ConfigureAwait(false);
 | 
				
			||||||
@@ -721,11 +721,11 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
            {
 | 
					            {
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            if (obj.Error != null || obj.Verses is null || obj.Verses.Length == 0)
 | 
					            if (obj.Error != null || obj.Verses is null || obj.Verses.Length == 0)
 | 
				
			||||||
                await ctx.Channel.SendErrorAsync(obj.Error ?? "No verse found.").ConfigureAwait(false);
 | 
					                await SendErrorAsync(obj.Error ?? "No verse found.").ConfigureAwait(false);
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var v = obj.Verses[0];
 | 
					                var v = obj.Verses[0];
 | 
				
			||||||
                await ctx.Channel.EmbedAsync(new EmbedBuilder()
 | 
					                await ctx.Channel.EmbedAsync(_eb.Create()
 | 
				
			||||||
                    .WithOkColor()
 | 
					                    .WithOkColor()
 | 
				
			||||||
                    .WithTitle($"{v.BookName} {v.Chapter}:{v.Verse}")
 | 
					                    .WithTitle($"{v.BookName} {v.Chapter}:{v.Verse}")
 | 
				
			||||||
                    .WithDescription(v.Text)).ConfigureAwait(false);
 | 
					                    .WithDescription(v.Text)).ConfigureAwait(false);
 | 
				
			||||||
@@ -747,7 +747,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
                return;
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //var embed = new EmbedBuilder()
 | 
					            //var embed = _eb.Create()
 | 
				
			||||||
            //    .WithOkColor()
 | 
					            //    .WithOkColor()
 | 
				
			||||||
            //    .WithDescription(gameData.ShortDescription)
 | 
					            //    .WithDescription(gameData.ShortDescription)
 | 
				
			||||||
            //    .WithTitle(gameData.Name)
 | 
					            //    .WithTitle(gameData.Name)
 | 
				
			||||||
@@ -760,19 +760,17 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
            await ctx.Channel.SendMessageAsync($"https://store.steampowered.com/app/{appId}").ConfigureAwait(false);
 | 
					            await ctx.Channel.SendMessageAsync($"https://store.steampowered.com/app/{appId}").ConfigureAwait(false);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public async Task InternalDapiCommand(IUserMessage umsg, string tag, DapiSearchType type)
 | 
					        public async Task InternalDapiCommand(string tag, DapiSearchType type)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var channel = umsg.Channel;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            tag = tag?.Trim() ?? "";
 | 
					            tag = tag?.Trim() ?? "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var imgObj = await _service.DapiSearch(tag, type, ctx.Guild?.Id).ConfigureAwait(false);
 | 
					            var imgObj = await _service.DapiSearch(tag, type, ctx.Guild?.Id).ConfigureAwait(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (imgObj is null)
 | 
					            if (imgObj is null)
 | 
				
			||||||
                await channel.SendErrorAsync(umsg.Author.Mention + " " + GetText("no_results")).ConfigureAwait(false);
 | 
					                await SendErrorAsync(ctx.User.Mention + " " + GetText("no_results")).ConfigureAwait(false);
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
                await channel.EmbedAsync(new EmbedBuilder().WithOkColor()
 | 
					                await ctx.Channel.EmbedAsync(_eb.Create().WithOkColor()
 | 
				
			||||||
                    .WithDescription($"{umsg.Author.Mention} [{tag ?? "url"}]({imgObj.FileUrl})")
 | 
					                    .WithDescription($"{ctx.User.Mention} [{tag ?? "url"}]({imgObj.FileUrl})")
 | 
				
			||||||
                    .WithImageUrl(imgObj.FileUrl)
 | 
					                    .WithImageUrl(imgObj.FileUrl)
 | 
				
			||||||
                    .WithFooter(type.ToString())).ConfigureAwait(false);
 | 
					                    .WithFooter(type.ToString())).ConfigureAwait(false);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,11 +20,12 @@ namespace NadekoBot.Modules.Searches.Services
 | 
				
			|||||||
        private readonly DbService _db;
 | 
					        private readonly DbService _db;
 | 
				
			||||||
        private readonly ConcurrentDictionary<string, HashSet<FeedSub>> _subs;
 | 
					        private readonly ConcurrentDictionary<string, HashSet<FeedSub>> _subs;
 | 
				
			||||||
        private readonly DiscordSocketClient _client;
 | 
					        private readonly DiscordSocketClient _client;
 | 
				
			||||||
 | 
					        private readonly IEmbedBuilderService _eb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private readonly ConcurrentDictionary<string, DateTime> _lastPosts =
 | 
					        private readonly ConcurrentDictionary<string, DateTime> _lastPosts =
 | 
				
			||||||
            new ConcurrentDictionary<string, DateTime>();
 | 
					            new ConcurrentDictionary<string, DateTime>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public FeedsService(Bot bot, DbService db, DiscordSocketClient client)
 | 
					        public FeedsService(Bot bot, DbService db, DiscordSocketClient client, IEmbedBuilderService eb)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _db = db;
 | 
					            _db = db;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -44,6 +45,7 @@ namespace NadekoBot.Modules.Searches.Services
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            _client = client;
 | 
					            _client = client;
 | 
				
			||||||
 | 
					            _eb = eb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var _ = Task.Run(TrackFeeds);
 | 
					            var _ = Task.Run(TrackFeeds);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -87,7 +89,7 @@ namespace NadekoBot.Modules.Searches.Services
 | 
				
			|||||||
                                continue;
 | 
					                                continue;
 | 
				
			||||||
                            }                            
 | 
					                            }                            
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                            var embed = new EmbedBuilder()
 | 
					                            var embed = _eb.Create()
 | 
				
			||||||
                                .WithFooter(rssUrl);
 | 
					                                .WithFooter(rssUrl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                            _lastPosts[kvp.Key] = itemUpdateDate;
 | 
					                            _lastPosts[kvp.Key] = itemUpdateDate;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -41,6 +41,7 @@ namespace NadekoBot.Modules.Searches.Services
 | 
				
			|||||||
        private readonly IDataCache _cache;
 | 
					        private readonly IDataCache _cache;
 | 
				
			||||||
        private readonly FontProvider _fonts;
 | 
					        private readonly FontProvider _fonts;
 | 
				
			||||||
        private readonly IBotCredentials _creds;
 | 
					        private readonly IBotCredentials _creds;
 | 
				
			||||||
 | 
					        private readonly IEmbedBuilderService _eb;
 | 
				
			||||||
        private readonly NadekoRandom _rng;
 | 
					        private readonly NadekoRandom _rng;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public ConcurrentDictionary<ulong, bool> TranslatedChannels { get; } = new ConcurrentDictionary<ulong, bool>();
 | 
					        public ConcurrentDictionary<ulong, bool> TranslatedChannels { get; } = new ConcurrentDictionary<ulong, bool>();
 | 
				
			||||||
@@ -61,7 +62,7 @@ namespace NadekoBot.Modules.Searches.Services
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        public SearchesService(DiscordSocketClient client, IGoogleApiService google,
 | 
					        public SearchesService(DiscordSocketClient client, IGoogleApiService google,
 | 
				
			||||||
            DbService db, Bot bot, IDataCache cache, IHttpClientFactory factory,
 | 
					            DbService db, Bot bot, IDataCache cache, IHttpClientFactory factory,
 | 
				
			||||||
            FontProvider fonts, IBotCredentials creds)
 | 
					            FontProvider fonts, IBotCredentials creds, IEmbedBuilderService eb)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _httpFactory = factory;
 | 
					            _httpFactory = factory;
 | 
				
			||||||
            _client = client;
 | 
					            _client = client;
 | 
				
			||||||
@@ -71,6 +72,7 @@ namespace NadekoBot.Modules.Searches.Services
 | 
				
			|||||||
            _cache = cache;
 | 
					            _cache = cache;
 | 
				
			||||||
            _fonts = fonts;
 | 
					            _fonts = fonts;
 | 
				
			||||||
            _creds = creds;
 | 
					            _creds = creds;
 | 
				
			||||||
 | 
					            _eb = eb;
 | 
				
			||||||
            _rng = new NadekoRandom();
 | 
					            _rng = new NadekoRandom();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            _blacklistedTags = new ConcurrentDictionary<ulong, HashSet<string>>(
 | 
					            _blacklistedTags = new ConcurrentDictionary<ulong, HashSet<string>>(
 | 
				
			||||||
@@ -100,7 +102,8 @@ namespace NadekoBot.Modules.Searches.Services
 | 
				
			|||||||
                                            .ConfigureAwait(false);
 | 
					                                            .ConfigureAwait(false);
 | 
				
			||||||
                        if (autoDelete)
 | 
					                        if (autoDelete)
 | 
				
			||||||
                            try { await umsg.DeleteAsync().ConfigureAwait(false); } catch { }
 | 
					                            try { await umsg.DeleteAsync().ConfigureAwait(false); } catch { }
 | 
				
			||||||
                        await umsg.Channel.SendConfirmAsync($"{umsg.Author.Mention} `:` "
 | 
					                        
 | 
				
			||||||
 | 
					                        await umsg.Channel.SendConfirmAsync(_eb, $"{umsg.Author.Mention} `:` "
 | 
				
			||||||
                            + text.Replace("<@ ", "<@", StringComparison.InvariantCulture)
 | 
					                            + text.Replace("<@ ", "<@", StringComparison.InvariantCulture)
 | 
				
			||||||
                                  .Replace("<@! ", "<@!", StringComparison.InvariantCulture)).ConfigureAwait(false);
 | 
					                                  .Replace("<@! ", "<@!", StringComparison.InvariantCulture)).ConfigureAwait(false);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -40,6 +40,7 @@ namespace NadekoBot.Modules.Searches.Services
 | 
				
			|||||||
        
 | 
					        
 | 
				
			||||||
        private readonly IBotCredentials _creds;
 | 
					        private readonly IBotCredentials _creds;
 | 
				
			||||||
        private readonly IPubSub _pubSub;
 | 
					        private readonly IPubSub _pubSub;
 | 
				
			||||||
 | 
					        private readonly IEmbedBuilderService _eb;
 | 
				
			||||||
        private readonly Timer _notifCleanupTimer;
 | 
					        private readonly Timer _notifCleanupTimer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private readonly TypedKey<List<StreamData>> _streamsOnlineKey;
 | 
					        private readonly TypedKey<List<StreamData>> _streamsOnlineKey;
 | 
				
			||||||
@@ -56,13 +57,15 @@ namespace NadekoBot.Modules.Searches.Services
 | 
				
			|||||||
            IBotCredentials creds,
 | 
					            IBotCredentials creds,
 | 
				
			||||||
            IHttpClientFactory httpFactory,
 | 
					            IHttpClientFactory httpFactory,
 | 
				
			||||||
            Bot bot,
 | 
					            Bot bot,
 | 
				
			||||||
            IPubSub pubSub)
 | 
					            IPubSub pubSub,
 | 
				
			||||||
 | 
					            IEmbedBuilderService eb)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _db = db;
 | 
					            _db = db;
 | 
				
			||||||
            _client = client;
 | 
					            _client = client;
 | 
				
			||||||
            _strings = strings;
 | 
					            _strings = strings;
 | 
				
			||||||
            _creds = creds;
 | 
					            _creds = creds;
 | 
				
			||||||
            _pubSub = pubSub;
 | 
					            _pubSub = pubSub;
 | 
				
			||||||
 | 
					            _eb = eb;
 | 
				
			||||||
            _streamTracker = new NotifChecker(httpFactory, redis, creds.RedisKey(), client.ShardId == 0);
 | 
					            _streamTracker = new NotifChecker(httpFactory, redis, creds.RedisKey(), client.ShardId == 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            _streamsOnlineKey = new("streams.online");
 | 
					            _streamsOnlineKey = new("streams.online");
 | 
				
			||||||
@@ -438,15 +441,19 @@ namespace NadekoBot.Modules.Searches.Services
 | 
				
			|||||||
            return data;
 | 
					            return data;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public EmbedBuilder GetEmbed(ulong guildId, StreamData status)
 | 
					        public IEmbedBuilder GetEmbed(ulong guildId, StreamData status)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var embed = new EmbedBuilder()
 | 
					            var embed = _eb.Create()
 | 
				
			||||||
                .WithTitle(status.Name)
 | 
					                .WithTitle(status.Name)
 | 
				
			||||||
                .WithUrl(status.StreamUrl)
 | 
					                .WithUrl(status.StreamUrl)
 | 
				
			||||||
                .WithDescription(status.StreamUrl)
 | 
					                .WithDescription(status.StreamUrl)
 | 
				
			||||||
                .AddField(GetText(guildId, "status"), status.IsLive ? "🟢 Online" : "🔴 Offline", true)
 | 
					                .AddField(GetText(guildId, "status"), status.IsLive ? "🟢 Online" : "🔴 Offline", true)
 | 
				
			||||||
                .AddField(GetText(guildId, "viewers"), status.IsLive ? status.Viewers.ToString() : "-", true)
 | 
					                .AddField(GetText(guildId, "viewers"), status.IsLive ? status.Viewers.ToString() : "-", true);
 | 
				
			||||||
                .WithColor(status.IsLive ? Bot.OkColor : Bot.ErrorColor);
 | 
					
 | 
				
			||||||
 | 
					            if (status.IsLive)
 | 
				
			||||||
 | 
					                embed = embed.WithOkColor();
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                embed = embed.WithErrorColor();
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            if (!string.IsNullOrWhiteSpace(status.Title))
 | 
					            if (!string.IsNullOrWhiteSpace(status.Title))
 | 
				
			||||||
                embed.WithAuthor(status.Title);
 | 
					                embed.WithAuthor(status.Title);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -117,12 +117,12 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                    if (elements.Count == 0)
 | 
					                    if (elements.Count == 0)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        return new EmbedBuilder()
 | 
					                        return _eb.Create()
 | 
				
			||||||
                            .WithDescription(GetText("streams_none"))
 | 
					                            .WithDescription(GetText("streams_none"))
 | 
				
			||||||
                            .WithErrorColor();
 | 
					                            .WithErrorColor();
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    var eb = new EmbedBuilder()
 | 
					                    var eb = _eb.Create()
 | 
				
			||||||
                        .WithTitle(GetText("streams_follow_title"))
 | 
					                        .WithTitle(GetText("streams_follow_title"))
 | 
				
			||||||
                        .WithOkColor();
 | 
					                        .WithOkColor();
 | 
				
			||||||
                    for (var index = 0; index < elements.Count; index++)
 | 
					                    for (var index = 0; index < elements.Count; index++)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,7 +30,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
                {
 | 
					                {
 | 
				
			||||||
                    await ctx.Channel.TriggerTypingAsync().ConfigureAwait(false);
 | 
					                    await ctx.Channel.TriggerTypingAsync().ConfigureAwait(false);
 | 
				
			||||||
                    var translation = await _searches.Translate(langs, text).ConfigureAwait(false);
 | 
					                    var translation = await _searches.Translate(langs, text).ConfigureAwait(false);
 | 
				
			||||||
                    await ctx.Channel.SendConfirmAsync(GetText("translation") + " " + langs, translation).ConfigureAwait(false);
 | 
					                    await SendConfirmAsync(GetText("translation") + " " + langs, translation).ConfigureAwait(false);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                catch
 | 
					                catch
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
@@ -46,7 +46,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
            //    foreach (var item in _google.Languages.Except(new[] { "en" }).Where(x => x.Length < 4))
 | 
					            //    foreach (var item in _google.Languages.Except(new[] { "en" }).Where(x => x.Length < 4))
 | 
				
			||||||
            //    {
 | 
					            //    {
 | 
				
			||||||
            //        var txt2 = await _searches.Translate(lastItem + ">" + item, txt);
 | 
					            //        var txt2 = await _searches.Translate(lastItem + ">" + item, txt);
 | 
				
			||||||
            //        await ctx.Channel.EmbedAsync(new EmbedBuilder()
 | 
					            //        await ctx.Channel.EmbedAsync(_eb.Create()
 | 
				
			||||||
            //            .WithOkColor()
 | 
					            //            .WithOkColor()
 | 
				
			||||||
            //            .WithTitle(lastItem + ">" + item)
 | 
					            //            .WithTitle(lastItem + ">" + item)
 | 
				
			||||||
            //            .AddField("Input", txt)
 | 
					            //            .AddField("Input", txt)
 | 
				
			||||||
@@ -56,7 +56,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
            //        lastItem = item;
 | 
					            //        lastItem = item;
 | 
				
			||||||
            //    }
 | 
					            //    }
 | 
				
			||||||
            //    txt = await _searches.Translate(lastItem + ">en", txt);
 | 
					            //    txt = await _searches.Translate(lastItem + ">en", txt);
 | 
				
			||||||
            //    await ctx.Channel.SendConfirmAsync("Final output:\n\n" + txt);
 | 
					            //    await SendConfirmAsync("Final output:\n\n" + txt);
 | 
				
			||||||
            //}
 | 
					            //}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            public enum AutoDeleteAutoTranslate
 | 
					            public enum AutoDeleteAutoTranslate
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -34,11 +34,11 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            var res = await http.GetStringAsync($"{_xkcdUrl}/info.0.json").ConfigureAwait(false);
 | 
					                            var res = await http.GetStringAsync($"{_xkcdUrl}/info.0.json").ConfigureAwait(false);
 | 
				
			||||||
                            var comic = JsonConvert.DeserializeObject<XkcdComic>(res);
 | 
					                            var comic = JsonConvert.DeserializeObject<XkcdComic>(res);
 | 
				
			||||||
                            var embed = new EmbedBuilder().WithColor(Bot.OkColor)
 | 
					                            var embed = _eb.Create().WithOkColor()
 | 
				
			||||||
                                                      .WithImageUrl(comic.ImageLink)
 | 
					                                .WithImageUrl(comic.ImageLink)
 | 
				
			||||||
                                                      .WithAuthor(comic.Title,"https://xkcd.com/s/919f27.ico", $"{_xkcdUrl}/{comic.Num}")
 | 
					                                .WithAuthor(comic.Title, "https://xkcd.com/s/919f27.ico", $"{_xkcdUrl}/{comic.Num}")
 | 
				
			||||||
                                                      .AddField(GetText("comic_number"), comic.Num.ToString(), true)
 | 
					                                .AddField(GetText("comic_number"), comic.Num.ToString(), true)
 | 
				
			||||||
                                                      .AddField(GetText("date"), $"{comic.Month}/{comic.Year}", true);
 | 
					                                .AddField(GetText("date"), $"{comic.Month}/{comic.Year}", true);
 | 
				
			||||||
                            var sent = await ctx.Channel.EmbedAsync(embed)
 | 
					                            var sent = await ctx.Channel.EmbedAsync(embed)
 | 
				
			||||||
                                         .ConfigureAwait(false);
 | 
					                                         .ConfigureAwait(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -69,8 +69,8 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
                        var res = await http.GetStringAsync($"{_xkcdUrl}/{num}/info.0.json").ConfigureAwait(false);
 | 
					                        var res = await http.GetStringAsync($"{_xkcdUrl}/{num}/info.0.json").ConfigureAwait(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        var comic = JsonConvert.DeserializeObject<XkcdComic>(res);
 | 
					                        var comic = JsonConvert.DeserializeObject<XkcdComic>(res);
 | 
				
			||||||
                        var embed = new EmbedBuilder()
 | 
					                        var embed = _eb.Create()
 | 
				
			||||||
                            .WithColor(Bot.OkColor)
 | 
					                            .WithOkColor()
 | 
				
			||||||
                            .WithImageUrl(comic.ImageLink)
 | 
					                            .WithImageUrl(comic.ImageLink)
 | 
				
			||||||
                            .WithAuthor(comic.Title, "https://xkcd.com/s/919f27.ico", $"{_xkcdUrl}/{num}")
 | 
					                            .WithAuthor(comic.Title, "https://xkcd.com/s/919f27.ico", $"{_xkcdUrl}/{num}")
 | 
				
			||||||
                            .AddField(GetText("comic_number"), comic.Num.ToString(), true)
 | 
					                            .AddField(GetText("comic_number"), comic.Num.ToString(), true)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,9 +21,9 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
                expr.EvaluateParameter += Expr_EvaluateParameter;
 | 
					                expr.EvaluateParameter += Expr_EvaluateParameter;
 | 
				
			||||||
                var result = expr.Evaluate();
 | 
					                var result = expr.Evaluate();
 | 
				
			||||||
                if (!expr.HasErrors())
 | 
					                if (!expr.HasErrors())
 | 
				
			||||||
                    await ctx.Channel.SendConfirmAsync("⚙ " + GetText("result"), result.ToString()).ConfigureAwait(false);
 | 
					                    await SendConfirmAsync("⚙ " + GetText("result"), result.ToString()).ConfigureAwait(false);
 | 
				
			||||||
                else
 | 
					                else
 | 
				
			||||||
                    await ctx.Channel.SendErrorAsync("⚙ " + GetText("error"), expr.Error).ConfigureAwait(false);
 | 
					                    await SendErrorAsync("⚙ " + GetText("error"), expr.Error).ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            private static void Expr_EvaluateParameter(string name, NCalc.ParameterArgs args)
 | 
					            private static void Expr_EvaluateParameter(string name, NCalc.ParameterArgs args)
 | 
				
			||||||
@@ -55,7 +55,7 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
                        "GetHashCode",
 | 
					                        "GetHashCode",
 | 
				
			||||||
                        "GetType"
 | 
					                        "GetType"
 | 
				
			||||||
                    });
 | 
					                    });
 | 
				
			||||||
                await ctx.Channel.SendConfirmAsync(GetText("calcops", Prefix), string.Join(", ", selection)).ConfigureAwait(false);
 | 
					                await SendConfirmAsync(GetText("calcops", Prefix), string.Join(", ", selection)).ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -137,7 +137,7 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                await ctx.SendPaginatedConfirmAsync(page, (curPage) =>
 | 
					                await ctx.SendPaginatedConfirmAsync(page, (curPage) =>
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    return new EmbedBuilder().WithOkColor()
 | 
					                    return _eb.Create().WithOkColor()
 | 
				
			||||||
                    .WithTitle(GetText("alias_list"))
 | 
					                    .WithTitle(GetText("alias_list"))
 | 
				
			||||||
                    .WithDescription(string.Join("\n",
 | 
					                    .WithDescription(string.Join("\n",
 | 
				
			||||||
                        arr.Skip(curPage * 10).Take(10).Select(x => $"`{x.Key}` => `{x.Value}`")));
 | 
					                        arr.Skip(curPage * 10).Take(10).Select(x => $"`{x.Key}` => `{x.Value}`")));
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -50,7 +50,7 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
                if (setting is null)
 | 
					                if (setting is null)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    var configNames = _settingServices.Select(x => x.Name);
 | 
					                    var configNames = _settingServices.Select(x => x.Name);
 | 
				
			||||||
                    var embed = new EmbedBuilder()
 | 
					                    var embed = _eb.Create()
 | 
				
			||||||
                        .WithErrorColor()
 | 
					                        .WithErrorColor()
 | 
				
			||||||
                        .WithDescription(GetText("config_not_found", Format.Code(name)))
 | 
					                        .WithDescription(GetText("config_not_found", Format.Code(name)))
 | 
				
			||||||
                        .AddField(GetText("config_list"), string.Join("\n", configNames));
 | 
					                        .AddField(GetText("config_list"), string.Join("\n", configNames));
 | 
				
			||||||
@@ -73,7 +73,7 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
                name = name?.ToLowerInvariant();
 | 
					                name = name?.ToLowerInvariant();
 | 
				
			||||||
                if (string.IsNullOrWhiteSpace(name))
 | 
					                if (string.IsNullOrWhiteSpace(name))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    var embed = new EmbedBuilder()
 | 
					                    var embed = _eb.Create()
 | 
				
			||||||
                        .WithOkColor()
 | 
					                        .WithOkColor()
 | 
				
			||||||
                        .WithTitle(GetText("config_list"))
 | 
					                        .WithTitle(GetText("config_list"))
 | 
				
			||||||
                        .WithDescription(string.Join("\n", configNames));
 | 
					                        .WithDescription(string.Join("\n", configNames));
 | 
				
			||||||
@@ -88,7 +88,7 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
                // if config name is not found, print error and the list of configs
 | 
					                // if config name is not found, print error and the list of configs
 | 
				
			||||||
                if (setting is null)
 | 
					                if (setting is null)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    var embed = new EmbedBuilder()
 | 
					                    var embed = _eb.Create()
 | 
				
			||||||
                        .WithErrorColor()
 | 
					                        .WithErrorColor()
 | 
				
			||||||
                        .WithDescription(GetText("config_not_found", Format.Code(name)))
 | 
					                        .WithDescription(GetText("config_not_found", Format.Code(name)))
 | 
				
			||||||
                        .AddField(GetText("config_list"), string.Join("\n", configNames));
 | 
					                        .AddField(GetText("config_list"), string.Join("\n", configNames));
 | 
				
			||||||
@@ -105,7 +105,7 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
                if (string.IsNullOrWhiteSpace(prop))
 | 
					                if (string.IsNullOrWhiteSpace(prop))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    var propStrings = GetPropsAndValuesString(setting, propNames);
 | 
					                    var propStrings = GetPropsAndValuesString(setting, propNames);
 | 
				
			||||||
                    var embed = new EmbedBuilder()
 | 
					                    var embed = _eb.Create()
 | 
				
			||||||
                        .WithOkColor()
 | 
					                        .WithOkColor()
 | 
				
			||||||
                        .WithTitle($"⚙️ {setting.Name}")
 | 
					                        .WithTitle($"⚙️ {setting.Name}")
 | 
				
			||||||
                        .WithDescription(propStrings);
 | 
					                        .WithDescription(propStrings);
 | 
				
			||||||
@@ -121,7 +121,7 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
                if (!exists)
 | 
					                if (!exists)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    var propStrings = GetPropsAndValuesString(setting, propNames);
 | 
					                    var propStrings = GetPropsAndValuesString(setting, propNames);
 | 
				
			||||||
                    var propErrorEmbed = new EmbedBuilder()
 | 
					                    var propErrorEmbed = _eb.Create()
 | 
				
			||||||
                        .WithErrorColor()
 | 
					                        .WithErrorColor()
 | 
				
			||||||
                        .WithDescription(GetText("config_prop_not_found", Format.Code(prop), Format.Code(name)))
 | 
					                        .WithDescription(GetText("config_prop_not_found", Format.Code(prop), Format.Code(name)))
 | 
				
			||||||
                        .AddField($"⚙️ {setting.Name}", propStrings);
 | 
					                        .AddField($"⚙️ {setting.Name}", propStrings);
 | 
				
			||||||
@@ -144,7 +144,7 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
                        value = Format.Code(Format.Sanitize(value?.TrimTo(1000)), "json");
 | 
					                        value = Format.Code(Format.Sanitize(value?.TrimTo(1000)), "json");
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    var embed = new EmbedBuilder()
 | 
					                    var embed = _eb.Create()
 | 
				
			||||||
                        .WithOkColor()
 | 
					                        .WithOkColor()
 | 
				
			||||||
                        .AddField("Config", Format.Code(setting.Name), true)
 | 
					                        .AddField("Config", Format.Code(setting.Name), true)
 | 
				
			||||||
                        .AddField("Prop", Format.Code(prop), true)
 | 
					                        .AddField("Prop", Format.Code(prop), true)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -46,7 +46,7 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
                var features = string.Join("\n", guild.Features);
 | 
					                var features = string.Join("\n", guild.Features);
 | 
				
			||||||
                if (string.IsNullOrWhiteSpace(features))
 | 
					                if (string.IsNullOrWhiteSpace(features))
 | 
				
			||||||
                    features = "-";
 | 
					                    features = "-";
 | 
				
			||||||
                var embed = new EmbedBuilder()
 | 
					                var embed = _eb.Create()
 | 
				
			||||||
                    .WithAuthor(GetText("server_info"))
 | 
					                    .WithAuthor(GetText("server_info"))
 | 
				
			||||||
                    .WithTitle(guild.Name)
 | 
					                    .WithTitle(guild.Name)
 | 
				
			||||||
                    .AddField(GetText("id"), guild.Id.ToString(), true)
 | 
					                    .AddField(GetText("id"), guild.Id.ToString(), true)
 | 
				
			||||||
@@ -58,7 +58,7 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
                    .AddField(GetText("region"), guild.VoiceRegionId.ToString(), true)
 | 
					                    .AddField(GetText("region"), guild.VoiceRegionId.ToString(), true)
 | 
				
			||||||
                    .AddField(GetText("roles"), (guild.Roles.Count - 1).ToString(), true)
 | 
					                    .AddField(GetText("roles"), (guild.Roles.Count - 1).ToString(), true)
 | 
				
			||||||
                    .AddField(GetText("features"), features, true)
 | 
					                    .AddField(GetText("features"), features, true)
 | 
				
			||||||
                    .WithColor(Bot.OkColor);
 | 
					                    .WithOkColor();
 | 
				
			||||||
                if (Uri.IsWellFormedUriString(guild.IconUrl, UriKind.Absolute))
 | 
					                if (Uri.IsWellFormedUriString(guild.IconUrl, UriKind.Absolute))
 | 
				
			||||||
                    embed.WithThumbnailUrl(guild.IconUrl);
 | 
					                    embed.WithThumbnailUrl(guild.IconUrl);
 | 
				
			||||||
                if (guild.Emotes.Any())
 | 
					                if (guild.Emotes.Any())
 | 
				
			||||||
@@ -82,13 +82,13 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                var createdAt = new DateTime(2015, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(ch.Id >> 22);
 | 
					                var createdAt = new DateTime(2015, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(ch.Id >> 22);
 | 
				
			||||||
                var usercount = (await ch.GetUsersAsync().FlattenAsync().ConfigureAwait(false)).Count();
 | 
					                var usercount = (await ch.GetUsersAsync().FlattenAsync().ConfigureAwait(false)).Count();
 | 
				
			||||||
                var embed = new EmbedBuilder()
 | 
					                var embed = _eb.Create()
 | 
				
			||||||
                    .WithTitle(ch.Name)
 | 
					                    .WithTitle(ch.Name)
 | 
				
			||||||
                    .WithDescription(ch.Topic?.SanitizeMentions(true))
 | 
					                    .WithDescription(ch.Topic?.SanitizeMentions(true))
 | 
				
			||||||
                    .AddField(GetText("id"), ch.Id.ToString(), true)
 | 
					                    .AddField(GetText("id"), ch.Id.ToString(), true)
 | 
				
			||||||
                    .AddField(GetText("created_at"), $"{createdAt:dd.MM.yyyy HH:mm}", true)
 | 
					                    .AddField(GetText("created_at"), $"{createdAt:dd.MM.yyyy HH:mm}", true)
 | 
				
			||||||
                    .AddField(GetText("users"), usercount.ToString(), true)
 | 
					                    .AddField(GetText("users"), usercount.ToString(), true)
 | 
				
			||||||
                    .WithColor(Bot.OkColor);
 | 
					                    .WithOkColor();
 | 
				
			||||||
                await ctx.Channel.EmbedAsync(embed).ConfigureAwait(false);
 | 
					                await ctx.Channel.EmbedAsync(embed).ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -101,7 +101,7 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
                if (user is null)
 | 
					                if (user is null)
 | 
				
			||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var embed = new EmbedBuilder()
 | 
					                var embed = _eb.Create()
 | 
				
			||||||
                    .AddField(GetText("name"), $"**{user.Username}**#{user.Discriminator}", true);
 | 
					                    .AddField(GetText("name"), $"**{user.Username}**#{user.Discriminator}", true);
 | 
				
			||||||
                if (!string.IsNullOrWhiteSpace(user.Nickname))
 | 
					                if (!string.IsNullOrWhiteSpace(user.Nickname))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
@@ -111,7 +111,7 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
                    .AddField(GetText("joined_server"), $"{user.JoinedAt?.ToString("dd.MM.yyyy HH:mm") ?? "?"}", true)
 | 
					                    .AddField(GetText("joined_server"), $"{user.JoinedAt?.ToString("dd.MM.yyyy HH:mm") ?? "?"}", true)
 | 
				
			||||||
                    .AddField(GetText("joined_discord"), $"{user.CreatedAt:dd.MM.yyyy HH:mm}", true)
 | 
					                    .AddField(GetText("joined_discord"), $"{user.CreatedAt:dd.MM.yyyy HH:mm}", true)
 | 
				
			||||||
                    .AddField(GetText("roles"), $"**({user.RoleIds.Count - 1})** - {string.Join("\n", user.GetRoles().Take(10).Where(r => r.Id != r.Guild.EveryoneRole.Id).Select(r => r.Name)).SanitizeMentions(true)}", true)
 | 
					                    .AddField(GetText("roles"), $"**({user.RoleIds.Count - 1})** - {string.Join("\n", user.GetRoles().Take(10).Where(r => r.Id != r.Guild.EveryoneRole.Id).Select(r => r.Name)).SanitizeMentions(true)}", true)
 | 
				
			||||||
                    .WithColor(Bot.OkColor);
 | 
					                    .WithOkColor();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var av = user.RealAvatarUrl();
 | 
					                var av = user.RealAvatarUrl();
 | 
				
			||||||
                if (av != null && av.IsAbsoluteUri)
 | 
					                if (av != null && av.IsAbsoluteUri)
 | 
				
			||||||
@@ -141,7 +141,7 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
                        kvp.Value / _stats.GetUptime().TotalSeconds, kvp.Value));
 | 
					                        kvp.Value / _stats.GetUptime().TotalSeconds, kvp.Value));
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                await ctx.Channel.EmbedAsync(new EmbedBuilder()
 | 
					                await ctx.Channel.EmbedAsync(_eb.Create()
 | 
				
			||||||
                    .WithTitle(GetText("activity_page", page + 1))
 | 
					                    .WithTitle(GetText("activity_page", page + 1))
 | 
				
			||||||
                    .WithOkColor()
 | 
					                    .WithOkColor()
 | 
				
			||||||
                    .WithFooter(GetText("activity_users_total", CmdHandler.UserMessagesSent.Count))
 | 
					                    .WithFooter(GetText("activity_users_total", CmdHandler.UserMessagesSent.Count))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,7 +29,7 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
                var ch = (ITextChannel)ctx.Channel;
 | 
					                var ch = (ITextChannel)ctx.Channel;
 | 
				
			||||||
                var invite = await ch.CreateInviteAsync(opts.Expire, opts.MaxUses, isTemporary: opts.Temporary, isUnique: opts.Unique).ConfigureAwait(false);
 | 
					                var invite = await ch.CreateInviteAsync(opts.Expire, opts.MaxUses, isTemporary: opts.Temporary, isUnique: opts.Unique).ConfigureAwait(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                await ctx.Channel.SendConfirmAsync($"{ctx.User.Mention} https://discord.gg/{invite.Code}").ConfigureAwait(false);
 | 
					                await SendConfirmAsync($"{ctx.User.Mention} https://discord.gg/{invite.Code}").ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            [NadekoCommand, Aliases]
 | 
					            [NadekoCommand, Aliases]
 | 
				
			||||||
@@ -54,12 +54,12 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
                    
 | 
					                    
 | 
				
			||||||
                    if (!invs.Any())
 | 
					                    if (!invs.Any())
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        return new EmbedBuilder()
 | 
					                        return _eb.Create()
 | 
				
			||||||
                            .WithErrorColor()
 | 
					                            .WithErrorColor()
 | 
				
			||||||
                            .WithDescription(GetText("no_invites"));
 | 
					                            .WithDescription(GetText("no_invites"));
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    var embed = new EmbedBuilder().WithOkColor();
 | 
					                    var embed = _eb.Create().WithOkColor();
 | 
				
			||||||
                    foreach (var inv in invites)
 | 
					                    foreach (var inv in invites)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        var expiryString = (inv.MaxAge is null || inv.MaxAge == 0 || inv.CreatedAt is null)
 | 
					                        var expiryString = (inv.MaxAge is null || inv.MaxAge == 0 || inv.CreatedAt is null)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -36,7 +36,7 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
                
 | 
					                
 | 
				
			||||||
                var rem = (_service.Interval - (DateTime.UtcNow - _service.LastUpdate));
 | 
					                var rem = (_service.Interval - (DateTime.UtcNow - _service.LastUpdate));
 | 
				
			||||||
                var helpcmd = Format.Code(Prefix + "donate");
 | 
					                var helpcmd = Format.Code(Prefix + "donate");
 | 
				
			||||||
                await ctx.Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
 | 
					                await ctx.Channel.EmbedAsync(_eb.Create().WithOkColor()
 | 
				
			||||||
                    .WithDescription(GetText("clpa_obsolete"))
 | 
					                    .WithDescription(GetText("clpa_obsolete"))
 | 
				
			||||||
                    .AddField(GetText("clpa_fail_already_title"), GetText("clpa_fail_already"))
 | 
					                    .AddField(GetText("clpa_fail_already_title"), GetText("clpa_fail_already"))
 | 
				
			||||||
                    .AddField(GetText("clpa_fail_wait_title"), GetText("clpa_fail_wait"))
 | 
					                    .AddField(GetText("clpa_fail_wait_title"), GetText("clpa_fail_wait"))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -48,7 +48,7 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (quotes.Any())
 | 
					                if (quotes.Any())
 | 
				
			||||||
                    await ctx.Channel.SendConfirmAsync(GetText("quotes_page", page + 1),
 | 
					                    await SendConfirmAsync(GetText("quotes_page", page + 1),
 | 
				
			||||||
                            string.Join("\n", quotes.Select(q => $"`#{q.Id}` {Format.Bold(q.Keyword.SanitizeAllMentions()),-20} by {q.AuthorName.SanitizeAllMentions()}")))
 | 
					                            string.Join("\n", quotes.Select(q => $"`#{q.Id}` {Format.Bold(q.Keyword.SanitizeAllMentions()),-20} by {q.AuthorName.SanitizeAllMentions()}")))
 | 
				
			||||||
                        .ConfigureAwait(false);
 | 
					                        .ConfigureAwait(false);
 | 
				
			||||||
                else
 | 
					                else
 | 
				
			||||||
@@ -85,7 +85,7 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
                if (CREmbed.TryParse(quote.Text, out var crembed))
 | 
					                if (CREmbed.TryParse(quote.Text, out var crembed))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    rep.Replace(crembed);
 | 
					                    rep.Replace(crembed);
 | 
				
			||||||
                    await ctx.Channel.EmbedAsync(crembed.ToEmbed(), $"`#{quote.Id}` 📣 " + crembed.PlainText?.SanitizeAllMentions() ?? "")
 | 
					                    await ctx.Channel.EmbedAsync(crembed.ToEmbed(_eb), $"`#{quote.Id}` 📣 " + crembed.PlainText?.SanitizeAllMentions() ?? "")
 | 
				
			||||||
                        .ConfigureAwait(false);
 | 
					                        .ConfigureAwait(false);
 | 
				
			||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@@ -115,7 +115,7 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            private async Task ShowQuoteData(Quote data)
 | 
					            private async Task ShowQuoteData(Quote data)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                await ctx.Channel.EmbedAsync(new EmbedBuilder()
 | 
					                await ctx.Channel.EmbedAsync(_eb.Create(ctx)
 | 
				
			||||||
                    .WithOkColor()
 | 
					                    .WithOkColor()
 | 
				
			||||||
                    .WithTitle(GetText("quote_id", $"#{data.Id}"))
 | 
					                    .WithTitle(GetText("quote_id", $"#{data.Id}"))
 | 
				
			||||||
                    .AddField(GetText("trigger"), data.Keyword)
 | 
					                    .AddField(GetText("trigger"), data.Keyword)
 | 
				
			||||||
@@ -168,7 +168,7 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                if (quote is null || quote.GuildId != ctx.Guild.Id)
 | 
					                if (quote is null || quote.GuildId != ctx.Guild.Id)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    await ctx.Channel.SendErrorAsync(GetText("quotes_notfound")).ConfigureAwait(false);
 | 
					                    await SendErrorAsync(GetText("quotes_notfound")).ConfigureAwait(false);
 | 
				
			||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -178,7 +178,7 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
                {
 | 
					                {
 | 
				
			||||||
                    rep.Replace(crembed);
 | 
					                    rep.Replace(crembed);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    await ctx.Channel.EmbedAsync(crembed.ToEmbed(), infoText + crembed.PlainText?.SanitizeAllMentions())
 | 
					                    await ctx.Channel.EmbedAsync(crembed.ToEmbed(_eb), infoText + crembed.PlainText?.SanitizeAllMentions())
 | 
				
			||||||
                        .ConfigureAwait(false);
 | 
					                        .ConfigureAwait(false);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else
 | 
					                else
 | 
				
			||||||
@@ -238,9 +238,9 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                if (success)
 | 
					                if (success)
 | 
				
			||||||
                    await ctx.Channel.SendConfirmAsync(response).ConfigureAwait(false);
 | 
					                    await SendConfirmAsync(response).ConfigureAwait(false);
 | 
				
			||||||
                else
 | 
					                else
 | 
				
			||||||
                    await ctx.Channel.SendErrorAsync(response).ConfigureAwait(false);
 | 
					                    await SendErrorAsync(response).ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            [NadekoCommand, Aliases]
 | 
					            [NadekoCommand, Aliases]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,10 +8,8 @@ using NadekoBot.Common.Attributes;
 | 
				
			|||||||
using NadekoBot.Services;
 | 
					using NadekoBot.Services;
 | 
				
			||||||
using NadekoBot.Services.Database.Models;
 | 
					using NadekoBot.Services.Database.Models;
 | 
				
			||||||
using NadekoBot.Db;
 | 
					using NadekoBot.Db;
 | 
				
			||||||
using NadekoBot.Db.Models;
 | 
					 | 
				
			||||||
using NadekoBot.Extensions;
 | 
					using NadekoBot.Extensions;
 | 
				
			||||||
using NadekoBot.Modules.Administration.Services;
 | 
					using NadekoBot.Modules.Administration.Services;
 | 
				
			||||||
using NadekoBot.Modules.Utility.Common;
 | 
					 | 
				
			||||||
using NadekoBot.Modules.Utility.Services;
 | 
					using NadekoBot.Modules.Utility.Services;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace NadekoBot.Modules.Utility
 | 
					namespace NadekoBot.Modules.Utility
 | 
				
			||||||
@@ -88,7 +86,7 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
                if (--page < 0)
 | 
					                if (--page < 0)
 | 
				
			||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var embed = new EmbedBuilder()
 | 
					                var embed = _eb.Create()
 | 
				
			||||||
                    .WithOkColor()
 | 
					                    .WithOkColor()
 | 
				
			||||||
                    .WithTitle(GetText("reminder_list"));
 | 
					                    .WithTitle(GetText("reminder_list"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -128,7 +126,7 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
                if (--index < 0)
 | 
					                if (--index < 0)
 | 
				
			||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var embed = new EmbedBuilder();
 | 
					                var embed = _eb.Create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                Reminder rem = null;
 | 
					                Reminder rem = null;
 | 
				
			||||||
                using (var uow = _db.GetDbContext())
 | 
					                using (var uow = _db.GetDbContext())
 | 
				
			||||||
@@ -191,7 +189,7 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
                    : TimeZoneInfo.ConvertTime(time, _tz.GetTimeZoneOrUtc(ctx.Guild.Id));
 | 
					                    : TimeZoneInfo.ConvertTime(time, _tz.GetTimeZoneOrUtc(ctx.Guild.Id));
 | 
				
			||||||
                try
 | 
					                try
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    await ctx.Channel.SendConfirmAsync(
 | 
					                    await SendConfirmAsync(
 | 
				
			||||||
                        "⏰ " + GetText("remind",
 | 
					                        "⏰ " + GetText("remind",
 | 
				
			||||||
                            Format.Bold(!isPrivate ? $"<#{targetId}>" : ctx.User.Username),
 | 
					                            Format.Bold(!isPrivate ? $"<#{targetId}>" : ctx.User.Username),
 | 
				
			||||||
                            Format.Bold(message),
 | 
					                            Format.Bold(message),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -48,7 +48,7 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                var description = GetRepeaterInfoString(removed);
 | 
					                var description = GetRepeaterInfoString(removed);
 | 
				
			||||||
                await ctx.Channel.EmbedAsync(new EmbedBuilder()
 | 
					                await ctx.Channel.EmbedAsync(_eb.Create()
 | 
				
			||||||
                    .WithOkColor()
 | 
					                    .WithOkColor()
 | 
				
			||||||
                    .WithTitle(GetText("repeater_removed", index + 1))
 | 
					                    .WithTitle(GetText("repeater_removed", index + 1))
 | 
				
			||||||
                    .WithDescription(description));
 | 
					                    .WithDescription(description));
 | 
				
			||||||
@@ -144,7 +144,7 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                var description = GetRepeaterInfoString(runner);
 | 
					                var description = GetRepeaterInfoString(runner);
 | 
				
			||||||
                await ctx.Channel.EmbedAsync(new EmbedBuilder()
 | 
					                await ctx.Channel.EmbedAsync(_eb.Create()
 | 
				
			||||||
                    .WithOkColor()
 | 
					                    .WithOkColor()
 | 
				
			||||||
                    .WithTitle(GetText("repeater_created"))
 | 
					                    .WithTitle(GetText("repeater_created"))
 | 
				
			||||||
                    .WithDescription(description));
 | 
					                    .WithDescription(description));
 | 
				
			||||||
@@ -162,7 +162,7 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
                var embed = new EmbedBuilder()
 | 
					                var embed = _eb.Create()
 | 
				
			||||||
                    .WithTitle(GetText("list_of_repeaters"))
 | 
					                    .WithTitle(GetText("list_of_repeaters"))
 | 
				
			||||||
                    .WithOkColor();
 | 
					                    .WithOkColor();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,14 +18,16 @@ namespace NadekoBot.Modules.Utility.Services
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    public class CommandMapService : IInputTransformer, INService
 | 
					    public class CommandMapService : IInputTransformer, INService
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        private readonly IEmbedBuilderService _eb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public ConcurrentDictionary<ulong, ConcurrentDictionary<string, string>> AliasMaps { get; } = new ConcurrentDictionary<ulong, ConcurrentDictionary<string, string>>();
 | 
					        public ConcurrentDictionary<ulong, ConcurrentDictionary<string, string>> AliasMaps { get; } = new ConcurrentDictionary<ulong, ConcurrentDictionary<string, string>>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private readonly DbService _db;
 | 
					        private readonly DbService _db;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //commandmap
 | 
					        //commandmap
 | 
				
			||||||
        public CommandMapService(DiscordSocketClient client, DbService db)
 | 
					        public CommandMapService(DiscordSocketClient client, DbService db, IEmbedBuilderService eb)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            _eb = eb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            using (var uow = db.GetDbContext())
 | 
					            using (var uow = db.GetDbContext())
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
@@ -87,7 +89,7 @@ namespace NadekoBot.Modules.Utility.Services
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                        try
 | 
					                        try
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            var toDelete = await channel.SendConfirmAsync($"{input} => {newInput}").ConfigureAwait(false);
 | 
					                            var toDelete = await channel.SendConfirmAsync(_eb, $"{input} => {newInput}").ConfigureAwait(false);
 | 
				
			||||||
                            var _ = Task.Run(async () =>
 | 
					                            var _ = Task.Run(async () =>
 | 
				
			||||||
                            {
 | 
					                            {
 | 
				
			||||||
                                await Task.Delay(1500).ConfigureAwait(false);
 | 
					                                await Task.Delay(1500).ConfigureAwait(false);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,12 +31,13 @@ namespace NadekoBot.Modules.Utility.Services
 | 
				
			|||||||
        private readonly ICurrencyService _currency;
 | 
					        private readonly ICurrencyService _currency;
 | 
				
			||||||
        private readonly GamblingConfigService _gamblingConfigService;
 | 
					        private readonly GamblingConfigService _gamblingConfigService;
 | 
				
			||||||
        private readonly IHttpClientFactory _httpFactory;
 | 
					        private readonly IHttpClientFactory _httpFactory;
 | 
				
			||||||
 | 
					        private readonly IEmbedBuilderService _eb;
 | 
				
			||||||
        private readonly DiscordSocketClient _client;
 | 
					        private readonly DiscordSocketClient _client;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public DateTime LastUpdate { get; private set; } = DateTime.UtcNow;
 | 
					        public DateTime LastUpdate { get; private set; } = DateTime.UtcNow;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public PatreonRewardsService(IBotCredentials creds, DbService db,
 | 
					        public PatreonRewardsService(IBotCredentials creds, DbService db,
 | 
				
			||||||
            ICurrencyService currency, IHttpClientFactory factory,
 | 
					            ICurrencyService currency, IHttpClientFactory factory, IEmbedBuilderService eb,
 | 
				
			||||||
            DiscordSocketClient client, GamblingConfigService gamblingConfigService)
 | 
					            DiscordSocketClient client, GamblingConfigService gamblingConfigService)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _creds = creds;
 | 
					            _creds = creds;
 | 
				
			||||||
@@ -44,6 +45,7 @@ namespace NadekoBot.Modules.Utility.Services
 | 
				
			|||||||
            _currency = currency;
 | 
					            _currency = currency;
 | 
				
			||||||
            _gamblingConfigService = gamblingConfigService;
 | 
					            _gamblingConfigService = gamblingConfigService;
 | 
				
			||||||
            _httpFactory = factory;
 | 
					            _httpFactory = factory;
 | 
				
			||||||
 | 
					            _eb = eb;
 | 
				
			||||||
            _client = client;
 | 
					            _client = client;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (client.ShardId == 0)
 | 
					            if (client.ShardId == 0)
 | 
				
			||||||
@@ -211,7 +213,7 @@ namespace NadekoBot.Modules.Utility.Services
 | 
				
			|||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                var channel = await user.GetOrCreateDMChannelAsync();
 | 
					                var channel = await user.GetOrCreateDMChannelAsync();
 | 
				
			||||||
                await channel.SendConfirmAsync(message);
 | 
					                await channel.SendConfirmAsync(_eb, message);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            catch
 | 
					            catch
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,12 +21,14 @@ namespace NadekoBot.Modules.Utility.Services
 | 
				
			|||||||
        private readonly DiscordSocketClient _client;
 | 
					        private readonly DiscordSocketClient _client;
 | 
				
			||||||
        private readonly DbService _db;
 | 
					        private readonly DbService _db;
 | 
				
			||||||
        private readonly IBotCredentials _creds;
 | 
					        private readonly IBotCredentials _creds;
 | 
				
			||||||
 | 
					        private readonly IEmbedBuilderService _eb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public RemindService(DiscordSocketClient client, DbService db, IBotCredentials creds)
 | 
					        public RemindService(DiscordSocketClient client, DbService db, IBotCredentials creds, IEmbedBuilderService eb)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _client = client;
 | 
					            _client = client;
 | 
				
			||||||
            _db = db;
 | 
					            _db = db;
 | 
				
			||||||
            _creds = creds;
 | 
					            _creds = creds;
 | 
				
			||||||
 | 
					            _eb = eb;
 | 
				
			||||||
            _ = StartReminderLoop();
 | 
					            _ = StartReminderLoop();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -167,7 +169,7 @@ namespace NadekoBot.Modules.Utility.Services
 | 
				
			|||||||
                if (ch is null)
 | 
					                if (ch is null)
 | 
				
			||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                await ch.EmbedAsync(new EmbedBuilder()
 | 
					                await ch.EmbedAsync(_eb.Create()
 | 
				
			||||||
                    .WithOkColor()
 | 
					                    .WithOkColor()
 | 
				
			||||||
                    .WithTitle("Reminder")
 | 
					                    .WithTitle("Reminder")
 | 
				
			||||||
                    .AddField("Created At", r.DateAdded.HasValue ? r.DateAdded.Value.ToLongDateString() : "?")
 | 
					                    .AddField("Created At", r.DateAdded.HasValue ? r.DateAdded.Value.ToLongDateString() : "?")
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,16 +26,18 @@ namespace NadekoBot.Modules.Utility.Services
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        private readonly DbService _db;
 | 
					        private readonly DbService _db;
 | 
				
			||||||
        private readonly IBotCredentials _creds;
 | 
					        private readonly IBotCredentials _creds;
 | 
				
			||||||
 | 
					        private readonly IEmbedBuilderService _eb;
 | 
				
			||||||
        private readonly DiscordSocketClient _client;
 | 
					        private readonly DiscordSocketClient _client;
 | 
				
			||||||
        private LinkedList<RunningRepeater> _repeaterQueue;
 | 
					        private LinkedList<RunningRepeater> _repeaterQueue;
 | 
				
			||||||
        private ConcurrentHashSet<int> _noRedundant;
 | 
					        private ConcurrentHashSet<int> _noRedundant;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private readonly object _queueLocker = new object();
 | 
					        private readonly object _queueLocker = new object();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public RepeaterService(DiscordSocketClient client, DbService db, IBotCredentials creds)
 | 
					        public RepeaterService(DiscordSocketClient client, DbService db, IBotCredentials creds, IEmbedBuilderService eb)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _db = db;
 | 
					            _db = db;
 | 
				
			||||||
            _creds = creds;
 | 
					            _creds = creds;
 | 
				
			||||||
 | 
					            _eb = eb;
 | 
				
			||||||
            _client = client;
 | 
					            _client = client;
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            var uow = _db.GetDbContext();
 | 
					            var uow = _db.GetDbContext();
 | 
				
			||||||
@@ -261,7 +263,7 @@ where ((guildid >> 22) % {_creds.TotalShards}) == {_client.ShardId};")
 | 
				
			|||||||
                if (CREmbed.TryParse(repeater.Message, out var crEmbed))
 | 
					                if (CREmbed.TryParse(repeater.Message, out var crEmbed))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    rep.Replace(crEmbed);
 | 
					                    rep.Replace(crEmbed);
 | 
				
			||||||
                    newMsg = await channel.EmbedAsync(crEmbed);
 | 
					                    newMsg = await channel.EmbedAsync(crEmbed, _eb);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else
 | 
					                else
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,7 +20,7 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
            {
 | 
					            {
 | 
				
			||||||
                var units = _service.Units;
 | 
					                var units = _service.Units;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var embed = new EmbedBuilder()
 | 
					                var embed = _eb.Create()
 | 
				
			||||||
                    .WithTitle(GetText("convertlist"))
 | 
					                    .WithTitle(GetText("convertlist"))
 | 
				
			||||||
                    .WithOkColor();
 | 
					                    .WithOkColor();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -89,7 +89,7 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
                res = Math.Round(res, 4);
 | 
					                res = Math.Round(res, 4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                await ctx.Channel.SendConfirmAsync(GetText("convert", value, originUnit.Triggers.Last(), res, targetUnit.Triggers.Last())).ConfigureAwait(false);
 | 
					                await SendConfirmAsync(GetText("convert", value, originUnit.Triggers.Last(), res, targetUnit.Triggers.Last())).ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -53,14 +53,14 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
            if (CREmbed.TryParse(message, out var embedData))
 | 
					            if (CREmbed.TryParse(message, out var embedData))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                rep.Replace(embedData);
 | 
					                rep.Replace(embedData);
 | 
				
			||||||
                await channel.EmbedAsync(embedData, sanitizeAll: !((IGuildUser)Context.User).GuildPermissions.MentionEveryone).ConfigureAwait(false);
 | 
					                await channel.EmbedAsync(embedData, _eb, sanitizeAll: !((IGuildUser)Context.User).GuildPermissions.MentionEveryone).ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var msg = rep.Replace(message);
 | 
					                var msg = rep.Replace(message);
 | 
				
			||||||
                if (!string.IsNullOrWhiteSpace(msg))
 | 
					                if (!string.IsNullOrWhiteSpace(msg))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    await channel.SendConfirmAsync(msg).ConfigureAwait(false);
 | 
					                    await channel.SendConfirmAsync(_eb, msg).ConfigureAwait(false);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -98,7 +98,7 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
                await ReplyErrorLocalizedAsync("nobody_playing_game").ConfigureAwait(false);
 | 
					                await ReplyErrorLocalizedAsync("nobody_playing_game").ConfigureAwait(false);
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                await ctx.Channel.SendConfirmAsync("```css\n" + string.Join("\n", arr.GroupBy(item => (i++) / 2)
 | 
					                await SendConfirmAsync("```css\n" + string.Join("\n", arr.GroupBy(item => (i++) / 2)
 | 
				
			||||||
                                                                                 .Select(ig => string.Concat(ig.Select(el => $"• {el,-27}")))) + "\n```")
 | 
					                                                                                 .Select(ig => string.Concat(ig.Select(el => $"• {el,-27}")))) + "\n```")
 | 
				
			||||||
                                                                                 .ConfigureAwait(false);
 | 
					                                                                                 .ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -128,9 +128,9 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
                    .ToList();
 | 
					                    .ToList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (pageUsers.Count == 0)
 | 
					                if (pageUsers.Count == 0)
 | 
				
			||||||
                    return new EmbedBuilder().WithOkColor().WithDescription(GetText("no_user_on_this_page"));
 | 
					                    return _eb.Create().WithOkColor().WithDescription(GetText("no_user_on_this_page"));
 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
                return new EmbedBuilder().WithOkColor()
 | 
					                return _eb.Create().WithOkColor()
 | 
				
			||||||
                    .WithTitle(GetText("inrole_list", Format.Bold(role?.Name ?? "No Role")) + $" - {roleUsers.Length}")
 | 
					                    .WithTitle(GetText("inrole_list", Format.Bold(role?.Name ?? "No Role")) + $" - {roleUsers.Length}")
 | 
				
			||||||
                    .WithDescription(string.Join("\n", pageUsers));
 | 
					                    .WithDescription(string.Join("\n", pageUsers));
 | 
				
			||||||
            }, roleUsers.Length, 20).ConfigureAwait(false);
 | 
					            }, roleUsers.Length, 20).ConfigureAwait(false);
 | 
				
			||||||
@@ -157,7 +157,7 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
            {
 | 
					            {
 | 
				
			||||||
                builder.AppendLine($"{p.Name} : {p.GetValue(perms, null)}");
 | 
					                builder.AppendLine($"{p.Name} : {p.GetValue(perms, null)}");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            await ctx.Channel.SendConfirmAsync(builder.ToString()).ConfigureAwait(false);
 | 
					            await SendConfirmAsync(builder.ToString()).ConfigureAwait(false);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [NadekoCommand, Aliases]
 | 
					        [NadekoCommand, Aliases]
 | 
				
			||||||
@@ -196,8 +196,7 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
        [RequireContext(ContextType.Guild)]
 | 
					        [RequireContext(ContextType.Guild)]
 | 
				
			||||||
        public async Task Roles(IGuildUser target, int page = 1)
 | 
					        public async Task Roles(IGuildUser target, int page = 1)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var channel = (ITextChannel)ctx.Channel;
 | 
					            var guild = ctx.Guild;
 | 
				
			||||||
            var guild = channel.Guild;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            const int rolesPerPage = 20;
 | 
					            const int rolesPerPage = 20;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -214,7 +213,7 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
                else
 | 
					                else
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    await channel.SendConfirmAsync(GetText("roles_page", page, Format.Bold(target.ToString())),
 | 
					                    await SendConfirmAsync(GetText("roles_page", page, Format.Bold(target.ToString())),
 | 
				
			||||||
                        "\n• " + string.Join("\n• ", (IEnumerable<IRole>)roles).SanitizeMentions(true)).ConfigureAwait(false);
 | 
					                        "\n• " + string.Join("\n• ", (IEnumerable<IRole>)roles).SanitizeMentions(true)).ConfigureAwait(false);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -227,7 +226,7 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
                else
 | 
					                else
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    await channel.SendConfirmAsync(GetText("roles_all_page", page),
 | 
					                    await SendConfirmAsync(GetText("roles_all_page", page),
 | 
				
			||||||
                        "\n• " + string.Join("\n• ", (IEnumerable<IRole>)roles).SanitizeMentions(true)).ConfigureAwait(false);
 | 
					                        "\n• " + string.Join("\n• ", (IEnumerable<IRole>)roles).SanitizeMentions(true)).ConfigureAwait(false);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -249,7 +248,7 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
            if (string.IsNullOrWhiteSpace(topic))
 | 
					            if (string.IsNullOrWhiteSpace(topic))
 | 
				
			||||||
                await ReplyErrorLocalizedAsync("no_topic_set").ConfigureAwait(false);
 | 
					                await ReplyErrorLocalizedAsync("no_topic_set").ConfigureAwait(false);
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
                await ctx.Channel.SendConfirmAsync(GetText("channel_topic"), topic).ConfigureAwait(false);
 | 
					                await SendConfirmAsync(GetText("channel_topic"), topic).ConfigureAwait(false);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [NadekoCommand, Aliases]
 | 
					        [NadekoCommand, Aliases]
 | 
				
			||||||
@@ -260,7 +259,7 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
                ownerIds = "-";
 | 
					                ownerIds = "-";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            await ctx.Channel.EmbedAsync(
 | 
					            await ctx.Channel.EmbedAsync(
 | 
				
			||||||
                    new EmbedBuilder().WithOkColor()
 | 
					                    _eb.Create().WithOkColor()
 | 
				
			||||||
                        .WithAuthor($"NadekoBot v{StatsService.BotVersion}",
 | 
					                        .WithAuthor($"NadekoBot v{StatsService.BotVersion}",
 | 
				
			||||||
                            "https://nadeko-pictures.nyc3.digitaloceanspaces.com/other/avatar.png",
 | 
					                            "https://nadeko-pictures.nyc3.digitaloceanspaces.com/other/avatar.png",
 | 
				
			||||||
                            "https://nadekobot.readthedocs.io/en/latest/")
 | 
					                            "https://nadekobot.readthedocs.io/en/latest/")
 | 
				
			||||||
@@ -309,7 +308,8 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
                return;
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var embed = new EmbedBuilder().WithOkColor();
 | 
					            var embed = _eb.Create()
 | 
				
			||||||
 | 
					                .WithOkColor();
 | 
				
			||||||
            foreach (var guild in guilds)
 | 
					            foreach (var guild in guilds)
 | 
				
			||||||
                embed.AddField(guild.Name,
 | 
					                embed.AddField(guild.Name,
 | 
				
			||||||
                    GetText("listservers", guild.Id, guild.MemberCount, guild.OwnerId),
 | 
					                    GetText("listservers", guild.Id, guild.MemberCount, guild.OwnerId),
 | 
				
			||||||
@@ -374,7 +374,7 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
                sw.Stop();
 | 
					                sw.Stop();
 | 
				
			||||||
                msg.DeleteAfter(0);
 | 
					                msg.DeleteAfter(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                await ctx.Channel.SendConfirmAsync($"{Format.Bold(ctx.User.ToString())} 🏓 {(int)sw.Elapsed.TotalMilliseconds}ms").ConfigureAwait(false);
 | 
					                await SendConfirmAsync($"{Format.Bold(ctx.User.ToString())} 🏓 {(int)sw.Elapsed.TotalMilliseconds}ms").ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            finally
 | 
					            finally
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
@@ -413,7 +413,7 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
        //
 | 
					        //
 | 
				
			||||||
        //     var inviteUsers = await _inviteService.GetInviteUsersAsync(ctx.Guild.Id);
 | 
					        //     var inviteUsers = await _inviteService.GetInviteUsersAsync(ctx.Guild.Id);
 | 
				
			||||||
        //     
 | 
					        //     
 | 
				
			||||||
        //     var embed = new EmbedBuilder()
 | 
					        //     var embed = _eb.Create()
 | 
				
			||||||
        //         .WithOkColor();
 | 
					        //         .WithOkColor();
 | 
				
			||||||
        //
 | 
					        //
 | 
				
			||||||
        //     await ctx.SendPaginatedConfirmAsync(page, (curPage) =>
 | 
					        //     await ctx.SendPaginatedConfirmAsync(page, (curPage) =>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -135,7 +135,7 @@ namespace NadekoBot.Modules.Xp
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                await ctx.SendPaginatedConfirmAsync(0, (page) =>
 | 
					                await ctx.SendPaginatedConfirmAsync(0, (page) =>
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    var embed = new EmbedBuilder()
 | 
					                    var embed = _eb.Create()
 | 
				
			||||||
                        .WithOkColor()
 | 
					                        .WithOkColor()
 | 
				
			||||||
                        .WithTitle($"{club.ToString()}")
 | 
					                        .WithTitle($"{club.ToString()}")
 | 
				
			||||||
                        .WithDescription(GetText("level_x", lvl.Level) + $" ({club.Xp} xp)")
 | 
					                        .WithDescription(GetText("level_x", lvl.Level) + $" ({club.Xp} xp)")
 | 
				
			||||||
@@ -187,7 +187,7 @@ namespace NadekoBot.Modules.Xp
 | 
				
			|||||||
                            .Take(10)
 | 
					                            .Take(10)
 | 
				
			||||||
                            .Select(x => x.ToString()));
 | 
					                            .Select(x => x.ToString()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        return new EmbedBuilder()
 | 
					                        return _eb.Create()
 | 
				
			||||||
                            .WithTitle(GetText("club_bans_for", club.ToString()))
 | 
					                            .WithTitle(GetText("club_bans_for", club.ToString()))
 | 
				
			||||||
                            .WithDescription(toShow)
 | 
					                            .WithDescription(toShow)
 | 
				
			||||||
                            .WithOkColor();
 | 
					                            .WithOkColor();
 | 
				
			||||||
@@ -218,7 +218,7 @@ namespace NadekoBot.Modules.Xp
 | 
				
			|||||||
                            .Take(10)
 | 
					                            .Take(10)
 | 
				
			||||||
                            .Select(x => x.ToString()));
 | 
					                            .Select(x => x.ToString()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        return new EmbedBuilder()
 | 
					                        return _eb.Create()
 | 
				
			||||||
                            .WithTitle(GetText("club_apps_for", club.ToString()))
 | 
					                            .WithTitle(GetText("club_apps_for", club.ToString()))
 | 
				
			||||||
                            .WithDescription(toShow)
 | 
					                            .WithDescription(toShow)
 | 
				
			||||||
                            .WithOkColor();
 | 
					                            .WithOkColor();
 | 
				
			||||||
@@ -373,7 +373,7 @@ namespace NadekoBot.Modules.Xp
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                var clubs = _service.GetClubLeaderboardPage(page);
 | 
					                var clubs = _service.GetClubLeaderboardPage(page);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var embed = new EmbedBuilder()
 | 
					                var embed = _eb.Create()
 | 
				
			||||||
                    .WithTitle(GetText("club_leaderboard", page + 1))
 | 
					                    .WithTitle(GetText("club_leaderboard", page + 1))
 | 
				
			||||||
                    .WithOkColor();
 | 
					                    .WithOkColor();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,7 +22,7 @@ namespace NadekoBot.Modules.Xp
 | 
				
			|||||||
            [UserPerm(GuildPerm.Administrator)]
 | 
					            [UserPerm(GuildPerm.Administrator)]
 | 
				
			||||||
            public async Task XpReset(ulong userId)
 | 
					            public async Task XpReset(ulong userId)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var embed = new EmbedBuilder()
 | 
					                var embed = _eb.Create()
 | 
				
			||||||
                    .WithTitle(GetText("reset"))
 | 
					                    .WithTitle(GetText("reset"))
 | 
				
			||||||
                    .WithDescription(GetText("reset_user_confirm"));
 | 
					                    .WithDescription(GetText("reset_user_confirm"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -39,7 +39,7 @@ namespace NadekoBot.Modules.Xp
 | 
				
			|||||||
            [UserPerm(GuildPerm.Administrator)]
 | 
					            [UserPerm(GuildPerm.Administrator)]
 | 
				
			||||||
            public async Task XpReset()
 | 
					            public async Task XpReset()
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var embed = new EmbedBuilder()
 | 
					                var embed = _eb.Create()
 | 
				
			||||||
                       .WithTitle(GetText("reset"))
 | 
					                       .WithTitle(GetText("reset"))
 | 
				
			||||||
                       .WithDescription(GetText("reset_server_confirm"));
 | 
					                       .WithDescription(GetText("reset_server_confirm"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -49,6 +49,7 @@ namespace NadekoBot.Modules.Xp.Services
 | 
				
			|||||||
        private readonly IHttpClientFactory _httpFactory;
 | 
					        private readonly IHttpClientFactory _httpFactory;
 | 
				
			||||||
        private readonly XpConfigService _xpConfig;
 | 
					        private readonly XpConfigService _xpConfig;
 | 
				
			||||||
        private readonly IPubSub _pubSub;
 | 
					        private readonly IPubSub _pubSub;
 | 
				
			||||||
 | 
					        private readonly IEmbedBuilderService _eb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public const int XP_REQUIRED_LVL_1 = 36;
 | 
					        public const int XP_REQUIRED_LVL_1 = 36;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -77,7 +78,8 @@ namespace NadekoBot.Modules.Xp.Services
 | 
				
			|||||||
            ICurrencyService cs,
 | 
					            ICurrencyService cs,
 | 
				
			||||||
            IHttpClientFactory http,
 | 
					            IHttpClientFactory http,
 | 
				
			||||||
            XpConfigService xpConfig,
 | 
					            XpConfigService xpConfig,
 | 
				
			||||||
            IPubSub pubSub)
 | 
					            IPubSub pubSub,
 | 
				
			||||||
 | 
					            IEmbedBuilderService eb)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _db = db;
 | 
					            _db = db;
 | 
				
			||||||
            _cmd = cmd;
 | 
					            _cmd = cmd;
 | 
				
			||||||
@@ -90,6 +92,7 @@ namespace NadekoBot.Modules.Xp.Services
 | 
				
			|||||||
            _httpFactory = http;
 | 
					            _httpFactory = http;
 | 
				
			||||||
            _xpConfig = xpConfig;
 | 
					            _xpConfig = xpConfig;
 | 
				
			||||||
            _pubSub = pubSub;
 | 
					            _pubSub = pubSub;
 | 
				
			||||||
 | 
					            _eb = eb;
 | 
				
			||||||
            _excludedServers = new ConcurrentHashSet<ulong>();
 | 
					            _excludedServers = new ConcurrentHashSet<ulong>();
 | 
				
			||||||
            _excludedChannels = new ConcurrentDictionary<ulong, ConcurrentHashSet<ulong>>();
 | 
					            _excludedChannels = new ConcurrentDictionary<ulong, ConcurrentHashSet<ulong>>();
 | 
				
			||||||
            _client = client;
 | 
					            _client = client;
 | 
				
			||||||
@@ -261,14 +264,14 @@ namespace NadekoBot.Modules.Xp.Services
 | 
				
			|||||||
                            {
 | 
					                            {
 | 
				
			||||||
                                var chan = await x.User.GetOrCreateDMChannelAsync();
 | 
					                                var chan = await x.User.GetOrCreateDMChannelAsync();
 | 
				
			||||||
                                if (chan != null)
 | 
					                                if (chan != null)
 | 
				
			||||||
                                    await chan.SendConfirmAsync(_strings.GetText("level_up_dm",
 | 
					                                    await chan.SendConfirmAsync(_eb, _strings.GetText("level_up_dm",
 | 
				
			||||||
                                        x.Guild.Id,
 | 
					                                        x.Guild.Id,
 | 
				
			||||||
                                        x.User.Mention, Format.Bold(x.Level.ToString()),
 | 
					                                        x.User.Mention, Format.Bold(x.Level.ToString()),
 | 
				
			||||||
                                        Format.Bold(x.Guild.ToString() ?? "-")));
 | 
					                                        Format.Bold(x.Guild.ToString() ?? "-")));
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                            else if (x.MessageChannel != null) // channel
 | 
					                            else if (x.MessageChannel != null) // channel
 | 
				
			||||||
                            {
 | 
					                            {
 | 
				
			||||||
                                await x.MessageChannel.SendConfirmAsync(_strings.GetText("level_up_channel",
 | 
					                                await x.MessageChannel.SendConfirmAsync(_eb, _strings.GetText("level_up_channel",
 | 
				
			||||||
                                    x.Guild.Id,
 | 
					                                    x.Guild.Id,
 | 
				
			||||||
                                    x.User.Mention, Format.Bold(x.Level.ToString())));
 | 
					                                    x.User.Mention, Format.Bold(x.Level.ToString())));
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
@@ -285,7 +288,7 @@ namespace NadekoBot.Modules.Xp.Services
 | 
				
			|||||||
                                chan = x.MessageChannel;
 | 
					                                chan = x.MessageChannel;
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                            await chan.SendConfirmAsync(_strings.GetText("level_up_global",
 | 
					                            await chan.SendConfirmAsync(_eb, _strings.GetText("level_up_global",
 | 
				
			||||||
                                x.Guild.Id,
 | 
					                                x.Guild.Id,
 | 
				
			||||||
                                x.User.Mention, Format.Bold(x.Level.ToString())));
 | 
					                                x.User.Mention, Format.Bold(x.Level.ToString())));
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -41,7 +41,7 @@ namespace NadekoBot.Modules.Xp
 | 
				
			|||||||
        [NadekoCommand, Aliases]
 | 
					        [NadekoCommand, Aliases]
 | 
				
			||||||
        public async Task XpRewsReset()
 | 
					        public async Task XpRewsReset()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var reply = await PromptUserConfirmAsync(new EmbedBuilder()
 | 
					            var reply = await PromptUserConfirmAsync(_eb.Create()
 | 
				
			||||||
                .WithPendingColor()
 | 
					                .WithPendingColor()
 | 
				
			||||||
                .WithDescription(GetText("xprewsreset_confirm")));
 | 
					                .WithDescription(GetText("xprewsreset_confirm")));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -91,7 +91,7 @@ namespace NadekoBot.Modules.Xp
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            return Context.SendPaginatedConfirmAsync(page, cur =>
 | 
					            return Context.SendPaginatedConfirmAsync(page, cur =>
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var embed = new EmbedBuilder()
 | 
					                var embed = _eb.Create()
 | 
				
			||||||
                    .WithTitle(GetText("level_up_rewards"))
 | 
					                    .WithTitle(GetText("level_up_rewards"))
 | 
				
			||||||
                    .WithOkColor();
 | 
					                    .WithOkColor();
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
@@ -200,7 +200,7 @@ namespace NadekoBot.Modules.Xp
 | 
				
			|||||||
            var globalSetting = _service.GetNotificationType(ctx.User);
 | 
					            var globalSetting = _service.GetNotificationType(ctx.User);
 | 
				
			||||||
            var serverSetting = _service.GetNotificationType(ctx.User.Id, ctx.Guild.Id);
 | 
					            var serverSetting = _service.GetNotificationType(ctx.User.Id, ctx.Guild.Id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var embed = new EmbedBuilder()
 | 
					            var embed = _eb.Create()
 | 
				
			||||||
                .WithOkColor()
 | 
					                .WithOkColor()
 | 
				
			||||||
                .AddField(GetText("xpn_setting_global"), GetNotifLocationString(globalSetting))
 | 
					                .AddField(GetText("xpn_setting_global"), GetNotifLocationString(globalSetting))
 | 
				
			||||||
                .AddField(GetText("xpn_setting_server"), GetNotifLocationString(serverSetting));
 | 
					                .AddField(GetText("xpn_setting_server"), GetNotifLocationString(serverSetting));
 | 
				
			||||||
@@ -288,7 +288,7 @@ namespace NadekoBot.Modules.Xp
 | 
				
			|||||||
            var lines = desc.Split('\n');
 | 
					            var lines = desc.Split('\n');
 | 
				
			||||||
            await ctx.SendPaginatedConfirmAsync(0, curpage =>
 | 
					            await ctx.SendPaginatedConfirmAsync(0, curpage =>
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var embed = new EmbedBuilder()
 | 
					                var embed = _eb.Create()
 | 
				
			||||||
                    .WithTitle(GetText("exclusion_list"))
 | 
					                    .WithTitle(GetText("exclusion_list"))
 | 
				
			||||||
                    .WithDescription(string.Join('\n', lines.Skip(15 * curpage).Take(15)))
 | 
					                    .WithDescription(string.Join('\n', lines.Skip(15 * curpage).Take(15)))
 | 
				
			||||||
                    .WithOkColor();
 | 
					                    .WithOkColor();
 | 
				
			||||||
@@ -331,7 +331,7 @@ namespace NadekoBot.Modules.Xp
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            await ctx.SendPaginatedConfirmAsync(page, (curPage) =>
 | 
					            await ctx.SendPaginatedConfirmAsync(page, (curPage) =>
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var embed = new EmbedBuilder()
 | 
					                var embed = _eb.Create()
 | 
				
			||||||
                    .WithTitle(GetText("server_leaderboard"))
 | 
					                    .WithTitle(GetText("server_leaderboard"))
 | 
				
			||||||
                    .WithOkColor();
 | 
					                    .WithOkColor();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -379,7 +379,7 @@ namespace NadekoBot.Modules.Xp
 | 
				
			|||||||
                return;
 | 
					                return;
 | 
				
			||||||
            var users = _service.GetUserXps(page);
 | 
					            var users = _service.GetUserXps(page);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var embed = new EmbedBuilder()
 | 
					            var embed = _eb.Create()
 | 
				
			||||||
                .WithTitle(GetText("global_leaderboard"))
 | 
					                .WithTitle(GetText("global_leaderboard"))
 | 
				
			||||||
                .WithOkColor();
 | 
					                .WithOkColor();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,14 +25,19 @@ namespace NadekoBot.Services
 | 
				
			|||||||
        private GreetGrouper<IGuildUser> greets = new GreetGrouper<IGuildUser>();
 | 
					        private GreetGrouper<IGuildUser> greets = new GreetGrouper<IGuildUser>();
 | 
				
			||||||
        private GreetGrouper<IGuildUser> byes = new GreetGrouper<IGuildUser>();
 | 
					        private GreetGrouper<IGuildUser> byes = new GreetGrouper<IGuildUser>();
 | 
				
			||||||
        private readonly BotConfigService _bss;
 | 
					        private readonly BotConfigService _bss;
 | 
				
			||||||
 | 
					        private readonly IEmbedBuilderService _eb;
 | 
				
			||||||
        public bool GroupGreets => _bss.Data.GroupGreets;
 | 
					        public bool GroupGreets => _bss.Data.GroupGreets;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public GreetSettingsService(DiscordSocketClient client, Bot bot, DbService db,
 | 
					        public GreetSettingsService(DiscordSocketClient client,
 | 
				
			||||||
            BotConfigService bss)
 | 
					            Bot bot,
 | 
				
			||||||
 | 
					            DbService db,
 | 
				
			||||||
 | 
					            BotConfigService bss,
 | 
				
			||||||
 | 
					            IEmbedBuilderService eb)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _db = db;
 | 
					            _db = db;
 | 
				
			||||||
            _client = client;
 | 
					            _client = client;
 | 
				
			||||||
            _bss = bss;
 | 
					            _bss = bss;
 | 
				
			||||||
 | 
					            _eb = eb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            GuildConfigsCache = new ConcurrentDictionary<ulong, GreetSettings>(
 | 
					            GuildConfigsCache = new ConcurrentDictionary<ulong, GreetSettings>(
 | 
				
			||||||
                bot.AllGuildConfigs
 | 
					                bot.AllGuildConfigs
 | 
				
			||||||
@@ -139,7 +144,7 @@ namespace NadekoBot.Services
 | 
				
			|||||||
                rep.Replace(embedData);
 | 
					                rep.Replace(embedData);
 | 
				
			||||||
                try
 | 
					                try
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    var toDelete = await channel.EmbedAsync(embedData).ConfigureAwait(false);
 | 
					                    var toDelete = await channel.EmbedAsync(embedData, _eb).ConfigureAwait(false);
 | 
				
			||||||
                    if (conf.AutoDeleteByeMessagesTimer > 0)
 | 
					                    if (conf.AutoDeleteByeMessagesTimer > 0)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        toDelete.DeleteAfter(conf.AutoDeleteByeMessagesTimer);
 | 
					                        toDelete.DeleteAfter(conf.AutoDeleteByeMessagesTimer);
 | 
				
			||||||
@@ -190,7 +195,7 @@ namespace NadekoBot.Services
 | 
				
			|||||||
                rep.Replace(embedData);
 | 
					                rep.Replace(embedData);
 | 
				
			||||||
                try
 | 
					                try
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    var toDelete = await channel.EmbedAsync(embedData).ConfigureAwait(false);
 | 
					                    var toDelete = await channel.EmbedAsync(embedData, _eb).ConfigureAwait(false);
 | 
				
			||||||
                    if (conf.AutoDeleteGreetMessagesTimer > 0)
 | 
					                    if (conf.AutoDeleteGreetMessagesTimer > 0)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        toDelete.DeleteAfter(conf.AutoDeleteGreetMessagesTimer);
 | 
					                        toDelete.DeleteAfter(conf.AutoDeleteGreetMessagesTimer);
 | 
				
			||||||
@@ -233,7 +238,7 @@ namespace NadekoBot.Services
 | 
				
			|||||||
                rep.Replace(embedData);
 | 
					                rep.Replace(embedData);
 | 
				
			||||||
                try
 | 
					                try
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    await channel.EmbedAsync(embedData).ConfigureAwait(false);
 | 
					                    await channel.EmbedAsync(embedData, _eb).ConfigureAwait(false);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                catch
 | 
					                catch
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
@@ -247,7 +252,7 @@ namespace NadekoBot.Services
 | 
				
			|||||||
                {
 | 
					                {
 | 
				
			||||||
                    try
 | 
					                    try
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        await channel.SendConfirmAsync(msg).ConfigureAwait(false);
 | 
					                        await channel.SendConfirmAsync(_eb, msg).ConfigureAwait(false);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    catch
 | 
					                    catch
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,46 +0,0 @@
 | 
				
			|||||||
using System;
 | 
					 | 
				
			||||||
using Discord;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace NadekoBot.Services
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    public interface IEmbedBuilderProvider
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        public IEmbedBuilder Create();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public interface IEmbedBuilder
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        public IEmbedBuilder WithDescription(string desc);
 | 
					 | 
				
			||||||
        public IEmbedBuilder WithTitle(string title);
 | 
					 | 
				
			||||||
        public IEmbedBuilder AddField(string title, object value, bool isInline = false);
 | 
					 | 
				
			||||||
        public IEmbedBuilder WithFooter(string text, string iconUrl = null);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public class DiscordEmbedBuilderWrapper : IEmbedBuilder
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        private EmbedBuilder _embed;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public DiscordEmbedBuilderWrapper()
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            _embed = new EmbedBuilder();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public IEmbedBuilder WithDescription(string desc)
 | 
					 | 
				
			||||||
            => Wrap(_embed.WithDescription(desc));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public IEmbedBuilder WithTitle(string title)
 | 
					 | 
				
			||||||
            => Wrap(_embed.WithTitle(title));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public IEmbedBuilder AddField(string title, object value, bool isInline = false)
 | 
					 | 
				
			||||||
            => Wrap(_embed.AddField(title, value, isInline));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public IEmbedBuilder WithFooter(string text, string iconUrl = null)
 | 
					 | 
				
			||||||
            => Wrap(_embed.WithFooter(text, iconUrl));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        private IEmbedBuilder Wrap(EmbedBuilder eb)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            _embed = eb;
 | 
					 | 
				
			||||||
            return this;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										84
									
								
								src/NadekoBot/Services/IEmbedBuilderService.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								src/NadekoBot/Services/IEmbedBuilderService.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,84 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using Discord;
 | 
				
			||||||
 | 
					using Discord.Commands;
 | 
				
			||||||
 | 
					using NadekoBot.Common.Configs;
 | 
				
			||||||
 | 
					using NadekoBot.Extensions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace NadekoBot.Services
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public interface IEmbedBuilderService
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        IEmbedBuilder Create(ICommandContext ctx = null);
 | 
				
			||||||
 | 
					        IEmbedBuilder Create(EmbedBuilder eb);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public class EmbedBuilderService : IEmbedBuilderService, INService
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        private readonly BotConfigService _botConfigService;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public EmbedBuilderService(BotConfigService botConfigService)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _botConfigService = botConfigService;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        public IEmbedBuilder Create(ICommandContext ctx = null) 
 | 
				
			||||||
 | 
					            => new DiscordEmbedBuilderWrapper(_botConfigService.Data);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        public IEmbedBuilder Create(EmbedBuilder embed) 
 | 
				
			||||||
 | 
					            => new DiscordEmbedBuilderWrapper(_botConfigService.Data, embed);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    public sealed class DiscordEmbedBuilderWrapper : IEmbedBuilder
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        private readonly BotConfig _botConfig;
 | 
				
			||||||
 | 
					        private EmbedBuilder _embed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public DiscordEmbedBuilderWrapper(in BotConfig botConfig, EmbedBuilder embed = null)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _botConfig = botConfig;
 | 
				
			||||||
 | 
					            _embed = embed ?? new EmbedBuilder();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public IEmbedBuilder WithDescription(string desc)
 | 
				
			||||||
 | 
					            => Wrap(_embed.WithDescription(desc));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public IEmbedBuilder WithTitle(string title)
 | 
				
			||||||
 | 
					            => Wrap(_embed.WithTitle(title));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public IEmbedBuilder AddField(string title, object value, bool isInline = false)
 | 
				
			||||||
 | 
					            => Wrap(_embed.AddField(title, value, isInline));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public IEmbedBuilder WithFooter(string text, string iconUrl = null)
 | 
				
			||||||
 | 
					            => Wrap(_embed.WithFooter(text, iconUrl));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public IEmbedBuilder WithAuthor(string name, string iconUrl = null, string url = null)
 | 
				
			||||||
 | 
					            => Wrap(_embed.WithAuthor(name, iconUrl, url));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public IEmbedBuilder WithUrl(string url)
 | 
				
			||||||
 | 
					            => Wrap(_embed.WithAuthor(url));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public IEmbedBuilder WithImageUrl(string url)
 | 
				
			||||||
 | 
					            => Wrap(_embed.WithAuthor(url));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public IEmbedBuilder WithThumbnailUrl(string url)
 | 
				
			||||||
 | 
					            => Wrap(_embed.WithThumbnailUrl(url));
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        public IEmbedBuilder WithColor(EmbedColor color)
 | 
				
			||||||
 | 
					            => color switch
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                EmbedColor.Ok => Wrap(_embed.WithColor(_botConfig.Color.Ok.ToDiscordColor())),
 | 
				
			||||||
 | 
					                EmbedColor.Pending => Wrap(_embed.WithColor(_botConfig.Color.Pending.ToDiscordColor())),
 | 
				
			||||||
 | 
					                EmbedColor.Error => Wrap(_embed.WithColor(_botConfig.Color.Error.ToDiscordColor())),
 | 
				
			||||||
 | 
					                _ => throw new ArgumentOutOfRangeException(nameof(color), "Unsupported EmbedColor type")
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public Embed Build()
 | 
				
			||||||
 | 
					            => _embed.Build();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private IEmbedBuilder Wrap(EmbedBuilder eb)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _embed = eb;
 | 
				
			||||||
 | 
					            return this;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -16,12 +16,14 @@ namespace NadekoBot.Services
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        private readonly DbService _db;
 | 
					        private readonly DbService _db;
 | 
				
			||||||
        private readonly GamblingConfigService _gss;
 | 
					        private readonly GamblingConfigService _gss;
 | 
				
			||||||
 | 
					        private readonly IEmbedBuilderService _eb;
 | 
				
			||||||
        private readonly IUser _bot;
 | 
					        private readonly IUser _bot;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public CurrencyService(DbService db, DiscordSocketClient c, GamblingConfigService gss)
 | 
					        public CurrencyService(DbService db, DiscordSocketClient c, GamblingConfigService gss, IEmbedBuilderService eb)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _db = db;
 | 
					            _db = db;
 | 
				
			||||||
            _gss = gss;
 | 
					            _gss = gss;
 | 
				
			||||||
 | 
					            _eb = eb;
 | 
				
			||||||
            _bot = c.CurrentUser;
 | 
					            _bot = c.CurrentUser;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -80,7 +82,7 @@ namespace NadekoBot.Services
 | 
				
			|||||||
                {
 | 
					                {
 | 
				
			||||||
                    var sign = _gss.Data.Currency.Sign;
 | 
					                    var sign = _gss.Data.Currency.Sign;
 | 
				
			||||||
                    await (await user.GetOrCreateDMChannelAsync())
 | 
					                    await (await user.GetOrCreateDMChannelAsync())
 | 
				
			||||||
                        .EmbedAsync(new EmbedBuilder()
 | 
					                        .EmbedAsync(_eb.Create()
 | 
				
			||||||
                            .WithOkColor()
 | 
					                            .WithOkColor()
 | 
				
			||||||
                            .WithTitle($"Received Currency")
 | 
					                            .WithTitle($"Received Currency")
 | 
				
			||||||
                            .AddField("Amount", amount + sign)
 | 
					                            .AddField("Amount", amount + sign)
 | 
				
			||||||
 
 | 
				
			|||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user