示例#1
0
        public async Task SetClan(CommandContext ctx, [Description("The clan tag")] string clanTag,
                                  [Description("The clan flag")] string flagCode = null,
                                  [Description("Enable or Disable the Clan")]
                                  bool enable = true,
                                  [Description("To ban or not a clan from the site")]
                                  bool isBan = false)
        {
            await ctx.TriggerTypingAsync();

            var userId = ctx.User?.Id ?? 0;

            Log.Info($"Requesting {nameof(SetClan)} by {userId}...");
            if (userId != _coder)
            {
                var emoji = DiscordEmoji.FromName(ctx.Client, ":no_entry:");
                var embed = new DiscordEmbedBuilder
                {
                    Title       = "Access denied",
                    Description = $"{emoji} You may be a *coder*, but you are not **The Coder**!",
                    Color       = DiscordColor.Red
                };

                await ctx.RespondAsync("", embed : embed);

                return;
            }

            var cfg      = GuildConfiguration.FromGuild(ctx.Guild);
            var platform = GetPlatform(clanTag, cfg.Plataform, out clanTag);

            clanTag = clanTag.Trim('[', ']');
            clanTag = clanTag.ToUpperInvariant();

            if (!ClanTagRegex.IsMatch(clanTag))
            {
                await ctx.RespondAsync($"You must send a **valid** clan **tag** as parameter, {ctx.User?.Mention}.");

                return;
            }

            if (!string.IsNullOrWhiteSpace(flagCode))
            {
                flagCode = flagCode.RemoveDiacritics().ToUpperInvariant();

                if (flagCode.Length != 2)
                {
                    await ctx.RespondAsync($"The flag code must be 2 letters only, {ctx.User?.Mention}.");

                    return;
                }
            }

            Log.Warn($"{nameof(SetClan)}({clanTag}, {platform}, {flagCode}, {enable}, {isBan})...");

            try
            {
                await ctx.TriggerTypingAsync();

                var provider = new DbProvider(_connectionString);
                var recorder = new DbRecorder(_connectionString);

                var cacheDirectory = ConfigurationManager.AppSettings["CacheDir"] ?? Path.GetTempPath();
                var webCacheAge    = TimeSpan.FromHours(4);
                var appId          = ConfigurationManager.AppSettings["WgAppId"] ?? "demo";

                var fetcher = new Fetcher(cacheDirectory)
                {
                    ApplicationId    = appId,
                    WebCacheAge      = webCacheAge,
                    WebFetchInterval = TimeSpan.FromSeconds(1)
                };

                var clan = provider.GetClan(platform, clanTag);

                if (clan == null && enable)
                {
                    // Check to add...
                    await ctx.RespondAsync($"Not found `{clanTag}` on the database. Searching the WG API...");

                    await ctx.TriggerTypingAsync();

                    var clanOnSite = fetcher.FindClan(platform, clanTag, true);
                    if (clanOnSite == null)
                    {
                        await ctx.RespondAsync(
                            $"Not found `{clanTag}` on the WG API for `{platform}`. Check the clan tag.");

                        return;
                    }

                    if (clanOnSite.AllMembersCount < 7)
                    {
                        await ctx.RespondAsync(
                            $"The clan `{clanTag}` on `{platform}` has only {clanOnSite.AllMembersCount}, and will not be added to the system.");

                        return;
                    }

                    clanOnSite.Country = flagCode;
                    recorder.Add(clanOnSite);

                    await ctx.RespondAsync(
                        $"The clan `{clanTag}` on `{platform}` with {clanOnSite.AllMembersCount} members was added to the system and " +
                        "should appear on the site in ~12 hours. Keep playing to achieve at least 7 members with 21 recent battles and appear on the default view.");

                    Log.Info($"Added {platform}.{clanTag}");
                    return;
                }

                if (clan == null)
                {
                    await ctx.RespondAsync(
                        $"Not found `{clanTag}` on `{platform}`. Check the clan tag.");

                    return;
                }

                if (!clan.Enabled && enable)
                {
                    // Can be enabled?
                    var clanOnSite = fetcher.GetClans(new[] { clan }).FirstOrDefault();
                    if (clanOnSite == null)
                    {
                        await ctx.RespondAsync(
                            $"Not found `{clanTag}` on the WG API for `{platform}`. Check the clan tag.");

                        return;
                    }

                    if (clanOnSite.IsDisbanded)
                    {
                        await ctx.RespondAsync($"The clan `{clanTag}` on `{platform}` was disbanded.");

                        return;
                    }

                    if (clanOnSite.Count < 7)
                    {
                        await ctx.RespondAsync(
                            $"The clan `{clanTag}` on `{platform}` has only {clanOnSite.Count} members and will not be enabled.");

                        return;
                    }

                    if (clan.DisabledReason == DisabledReason.Banned)
                    {
                        await ctx.RespondAsync(
                            $"The clan `{clanTag}` ({clan.ClanId}) on `{platform}` was **banned** from the site.");

                        return;
                    }

                    recorder.EnableClan(clanOnSite.Plataform, clanOnSite.ClanId);
                    await ctx.RespondAsync(
                        $"The clan `{clanTag}` on `{platform}` disabled for `{clan.DisabledReason}` is enabled again.");

                    Log.Info($"Enabled {platform}.{clanTag}");
                }
                else if (clan.Enabled && !enable)
                {
                    if (isBan)
                    {
                        recorder.DisableClan(clan.Plataform, clan.ClanId, DisabledReason.Banned);

                        // Also deletes from the remote site
                        var putter = new Putter(clan.Plataform, ConfigurationManager.AppSettings["ApiAdminKey"]);
                        putter.DeleteClan(clan.ClanTag);

                        await ctx.RespondAsync(
                            $"The clan `{clanTag}` ({clan.ClanId}) on `{platform}` was **BANNED** from the site.");

                        Log.Warn($"BANNED {platform}.{clanTag}");
                    }
                    else
                    {
                        recorder.DisableClan(clan.Plataform, clan.ClanId, DisabledReason.Unknow);
                        await ctx.RespondAsync(
                            $"The clan `{clanTag}` ({clan.ClanId}) on `{platform}` was **disabled** from the site.");

                        Log.Warn($"Disabled {platform}.{clanTag}");
                    }
                }

                // change flag?
                flagCode = flagCode ?? string.Empty;
                if (!string.Equals(flagCode, clan.Country ?? string.Empty, StringComparison.InvariantCultureIgnoreCase))
                {
                    recorder.SetClanFlag(clan.Plataform, clan.ClanId, flagCode.ToLowerInvariant());
                    await ctx.RespondAsync(
                        $"The flag of the clan `{clanTag}` on `{platform}` was changed to `{flagCode}`.");

                    Log.Info($"Flag changed on {platform}.{clanTag} to {flagCode}.");
                }

                await ctx.RespondAsync($"all done for `{clan.ClanTag}` on `{platform}`.");
            }
            catch (Exception ex)
            {
                Log.Error($"{nameof(SetClan)}", ex);
                await ctx.RespondAsync(
                    $"Sorry, {ctx.User.Mention}. There was an error... the *Coder* will be notified of `{ex.Message}`.");
            }
        }
示例#2
0
        /// <summary>
        /// Unlinks a emoji from a role
        /// </summary>
        /// <param name="guild"></param>
        /// <param name="emoji"></param>
        /// <returns></returns>
        public async Task <bool> RemoveReactionRoleAsync(DiscordMessage message, DiscordEmoji emoji)
        {
            string key = Namespace.Combine(message.Channel.Guild, REDIS_REACT_ROLE, message);

            return(await Redis.RemoveHashSetAsync(key, emoji.Id.ToString()));
        }
        public async Task Yardım(CommandContext ctx)
        {
            var yardımEmbed = new DiscordEmbedBuilder
            {
                Color       = DiscordColor.Red,
                ImageUrl    = "https://i.ibb.co/0ZMJFZQ/111.png",
                Description = $"**Foxes Arena | Yardım**\n\n:one: Eğlence Komutları\n\n:two: Moderasyon Komutları\n\n:three: Bot Sahibi Komutları\n\n:four: Arena Komutları"
            };
            var message = await ctx.Channel.SendMessageAsync(embed : yardımEmbed).ConfigureAwait(false);

            var one   = DiscordEmoji.FromName(ctx.Client, ":one:");
            var two   = DiscordEmoji.FromName(ctx.Client, ":two:");
            var three = DiscordEmoji.FromName(ctx.Client, ":three:");
            var four  = DiscordEmoji.FromName(ctx.Client, ":four:");
            await message.CreateReactionAsync(one).ConfigureAwait(false);

            await message.CreateReactionAsync(two).ConfigureAwait(false);

            await message.CreateReactionAsync(three).ConfigureAwait(false);

            await message.CreateReactionAsync(four).ConfigureAwait(false);

            #region eğlenceKomutlar
            var interactivity = ctx.Client.GetInteractivity();

            var result = await interactivity.WaitForReactionAsync(x => x.User.Id == ctx.Message.Author.Id).ConfigureAwait(false);

            if (result.Result.Emoji == one)
            {
                await message.DeleteAsync().ConfigureAwait(false);

                var funCommands = new DiscordEmbedBuilder
                {
                    Color       = DiscordColor.Red,
                    ImageUrl    = "https://i.ibb.co/0ZMJFZQ/111.png",
                    Description = $"**Foxes Arena | Eğlence Komutları**\n\n**Bilgi**\nBurası kullanıcılarımızın kullanabileceği eğlence komutlarını içeriyor. \n\n**Komutlar**\n`kaçcm`, `ligimne`, `banla`"
                };
                var funCommandsMessage = await ctx.Channel.SendMessageAsync(embed : funCommands).ConfigureAwait(false);

                var funCommandsBackEmoji = DiscordEmoji.FromName(ctx.Client, ":track_previous:");
                await funCommandsMessage.CreateReactionAsync(funCommandsBackEmoji);

                var interactivityFunCommands = ctx.Client.GetInteractivity();
                var funCommandsBackResult    = await interactivityFunCommands.WaitForReactionAsync(x => x.User.Id == ctx.Message.Author.Id && x.Emoji == funCommandsBackEmoji).ConfigureAwait(false);

                if (funCommandsBackResult.Result.Emoji == funCommandsBackEmoji)
                {
                    await funCommandsMessage.DeleteAsync().ConfigureAwait(false);

                    await ctx.Message.DeleteAsync().ConfigureAwait(false);
                }
            }
            else if (result.Result.Emoji == two)
            {
                await message.DeleteAsync().ConfigureAwait(false);

                var funCommands = new DiscordEmbedBuilder
                {
                    Color       = DiscordColor.Red,
                    ImageUrl    = "https://i.ibb.co/0ZMJFZQ/111.png",
                    Description = $"**Foxes Arena | Moderasyon Komutları**\n\n**Bilgi**\nBurası yetkililerimizin kullanabileceği eğlence komutlarını içeriyor. \n\n**Komutlar**\n`ban`, `kick`, `temizle`"
                };
                var funCommandsMessage = await ctx.Channel.SendMessageAsync(embed : funCommands).ConfigureAwait(false);

                var funCommandsBackEmoji = DiscordEmoji.FromName(ctx.Client, ":track_previous:");
                await funCommandsMessage.CreateReactionAsync(funCommandsBackEmoji);

                var interactivityFunCommands = ctx.Client.GetInteractivity();
                var funCommandsBackResult    = await interactivityFunCommands.WaitForReactionAsync(x => x.User.Id == ctx.Message.Author.Id && x.Emoji == funCommandsBackEmoji).ConfigureAwait(false);

                if (funCommandsBackResult.Result.Emoji == funCommandsBackEmoji)
                {
                    await funCommandsMessage.DeleteAsync().ConfigureAwait(false);

                    await ctx.Message.DeleteAsync().ConfigureAwait(false);
                }
            }
            #endregion
        }
 public static Task <int> AddEmojiReactionEAsync(this ReactionsService service, ulong gid, DiscordEmoji emoji, IEnumerable <string> triggers, bool regex)
 => service.AddEmojiReactionAsync(gid, emoji.GetDiscordName(), triggers, regex);
        public static async Task OnMessageCreated(MessageCreateEventArgs args)
        {
            if (DefaultHandlerFilter.IsFluff(args.Message))
            {
                return;
            }

            if (args.Message.Channel.IsPrivate)
            {
                return;
            }

#if DEBUG
            if (args.Message.Content == "emoji test")
            {
                var badEmojis = new List <DiscordEmoji>(SadReactions.Concat(ThankYouReactions));
                var posted    = 0;
                var line      = 1;
                var msg       = await args.Channel.SendMessageAsync("Line " + line).ConfigureAwait(false);

                for (var i = 0; i < 5; i++)
                {
                    var tmp = new List <DiscordEmoji>();
                    foreach (var emoji in badEmojis)
                    {
                        try
                        {
                            await msg.CreateReactionAsync(emoji).ConfigureAwait(false);

                            if (++posted == 15)
                            {
                                line++;
                                posted = 0;
                                msg    = await args.Channel.SendMessageAsync("Line " + line).ConfigureAwait(false);
                            }
                        }
                        catch (Exception e)
                        {
                            Config.Log.Debug(e);
                            tmp.Add(emoji);
                        }
                    }
                    badEmojis = tmp;
                    if (badEmojis.Any())
                    {
                        await Task.Delay(1000).ConfigureAwait(false);
                    }
                }
                if (badEmojis.Any())
                {
                    await args.Channel.SendMessageAsync("Bad emojis: " + string.Concat(badEmojis)).ConfigureAwait(false);
                }
                else
                {
                    await args.Channel.SendMessageAsync("Everything looks fine").ConfigureAwait(false);
                }
                return;
            }
#endif

            if (!string.IsNullOrEmpty(args.Message.Content) && Paws.Matches(args.Message.Content) is MatchCollection mc)
            {
                using var db = new BotDb();
                var matchedGroups = (from m in mc
                                     from Group g in m.Groups
                                     where g.Success && !string.IsNullOrEmpty(g.Value)
                                     select g.Name
                                     ).Distinct()
                                    .ToArray();
                if (matchedGroups.Contains("kot"))
                {
                    if (!db.Kot.Any(k => k.UserId == args.Author.Id))
                    {
                        db.Kot.Add(new Kot {
                            UserId = args.Author.Id
                        });
                        await db.SaveChangesAsync().ConfigureAwait(false);
                    }
                }
                if (matchedGroups.Contains("doggo"))
                {
                    if (!db.Doggo.Any(d => d.UserId == args.Author.Id))
                    {
                        db.Doggo.Add(new Doggo {
                            UserId = args.Author.Id
                        });
                        await db.SaveChangesAsync().ConfigureAwait(false);
                    }
                }
            }

            var(needToSilence, needToThank) = NeedToSilence(args.Message);
            if (!(needToSilence || needToThank))
            {
                return;
            }

            if (needToThank)
            {
                DiscordEmoji emoji;
                string       thankYouMessage;
                lock (theDoor)
                {
                    emoji           = ThankYouReactions[rng.Next(ThankYouReactions.Length)];
                    thankYouMessage = LimitedToSpamChannel.IsSpamChannel(args.Channel) ||
                                      LimitedToOfftopicChannel.IsOfftopicChannel(args.Channel)
                        ? ThankYouMessages[rng.Next(ThankYouMessages.Length)]
                        : null;
                }
                await args.Message.ReactWithAsync(emoji, thankYouMessage).ConfigureAwait(false);
            }
            if (needToSilence)
            {
                DiscordEmoji emoji;
                string       sadMessage;
                lock (theDoor)
                {
                    emoji      = SadReactions[rng.Next(SadReactions.Length)];
                    sadMessage = SadMessages[rng.Next(SadMessages.Length)];
                }
                await args.Message.ReactWithAsync(emoji, sadMessage).ConfigureAwait(false);

                if (args.Author.IsSmartlisted(args.Client, args.Message.Channel.Guild))
                {
                    var botMember = args.Guild?.CurrentMember ?? args.Client.GetMember(args.Client.CurrentUser);
                    if (args.Channel.PermissionsFor(botMember).HasPermission(Permissions.ReadMessageHistory))
                    {
                        var lastBotMessages = await args.Channel.GetMessagesBeforeAsync(args.Message.Id, 20, DateTime.UtcNow.Add(-Config.ShutupTimeLimit)).ConfigureAwait(false);

                        if (lastBotMessages.OrderByDescending(m => m.CreationTimestamp).FirstOrDefault(m => m.Author.IsCurrent) is DiscordMessage msg)
                        {
                            await msg.DeleteAsync("asked to shut up").ConfigureAwait(false);
                        }
                    }
                    else
                    {
                        await args.Message.ReactWithAsync(DiscordEmoji.FromUnicode("🙅"), @"No can do, boss ¯\\_(ツ)\_/¯").ConfigureAwait(false);
                    }
                }
            }
        }
示例#6
0
        public static async Task CreateOnVoiceStateUpdated(DiscordClient client, VoiceStateUpdateEventArgs e)
        {
            try
            {
                if (e.Channel != null)
                {
                    if (e.Channel.Id == Bot.BotSettings.AutocreateGalleon ||
                        e.Channel.Id == Bot.BotSettings.AutocreateBrigantine ||
                        e.Channel.Id == Bot.BotSettings.AutocreateSloop
                        )                                      // мы создаем канал, если пользователь зашел в один из каналов автосоздания
                    {
                        if (ShipCooldowns.ContainsKey(e.User)) // проверка на кулдаун
                        {
                            if ((ShipCooldowns[e.User] - DateTime.Now).Seconds > 0)
                            {
                                var m = await e.Guild.GetMemberAsync(e.User.Id);

                                await m.PlaceInAsync(e.Guild.GetChannel(Bot.BotSettings.WaitingRoom));

                                await m.SendMessageAsync($"{Bot.BotSettings.ErrorEmoji} Вам нужно подождать " +
                                                         $"**{(ShipCooldowns[e.User] - DateTime.Now).Seconds}** секунд прежде чем " +
                                                         "создавать новый корабль!");

                                client.Logger.LogInformation(BotLoggerEvents.Event, $"Участник {e.User.Username}#{e.User.Discriminator} ({e.User.Discriminator}) был перемещён в комнату ожидания.");
                                return;
                            }
                        }

                        // если проверка успешно пройдена, добавим пользователя
                        // в словарь кулдаунов
                        ShipCooldowns[e.User] = DateTime.Now.AddSeconds(Bot.BotSettings.FastCooldown);

                        //Проверка на эмиссарство
                        var channelSymbol = Bot.BotSettings.AutocreateSymbol;

                        var member = await e.Guild.GetMemberAsync(e.User.Id);

                        member.Roles.ToList().ForEach(x =>
                        {
                            if (x.Id == Bot.BotSettings.EmissaryGoldhoadersRole)
                            {
                                channelSymbol = DiscordEmoji.FromName(client, ":moneybag:");
                            }
                            else if (x.Id == Bot.BotSettings.EmissaryTradingCompanyRole)
                            {
                                channelSymbol = DiscordEmoji.FromName(client, ":pig:");
                            }
                            else if (x.Id == Bot.BotSettings.EmissaryOrderOfSoulsRole)
                            {
                                channelSymbol = DiscordEmoji.FromName(client, ":skull:");
                            }
                            else if (x.Id == Bot.BotSettings.EmissaryAthenaRole)
                            {
                                channelSymbol = DiscordEmoji.FromName(client, ":gem:");
                            }
                            else if (x.Id == Bot.BotSettings.EmissaryReaperBonesRole)
                            {
                                channelSymbol = DiscordEmoji.FromName(client, ":skull_crossbones:");
                            }
                            else if (x.Id == Bot.BotSettings.HuntersRole)
                            {
                                channelSymbol = DiscordEmoji.FromName(client, ":fish:");
                            }
                            else if (x.Id == Bot.BotSettings.ArenaRole)
                            {
                                channelSymbol = DiscordEmoji.FromName(client, ":crossed_swords:");
                            }
                        });

                        var autoCreateSloopCategory      = e.Guild.GetChannel(Bot.BotSettings.AutocreateSloopCategory);
                        var autoCreateBrigantineCategory = e.Guild.GetChannel(Bot.BotSettings.AutocreateBrigantineCategory);
                        var autoCreateGalleongCategory   = e.Guild.GetChannel(Bot.BotSettings.AutocreateGalleonCategory);

                        //Генерируем создание канала
                        var used_names = autoCreateSloopCategory.Children.Select(x => x.Name).ToArray();
                        used_names.Concat(autoCreateBrigantineCategory.Children.Select(x => x.Name).ToArray());
                        used_names.Concat(autoCreateGalleongCategory.Children.Select(x => x.Name).ToArray());

                        var generatedName = ShipNames.GenerateChannelName(used_names);
                        var channelName   = $"{channelSymbol} {generatedName}";

                        DiscordChannel created = null;

                        if (!Bot.ShipNamesStats.ContainsKey(generatedName)) // create a key-value pair for a new ship name
                        {
                            Bot.ShipNamesStats[generatedName] = new[] { 0, 0, 0 }
                        }
                        ;

                        if (e.Channel.Id == Bot.BotSettings.AutocreateSloop)
                        {
                            Bot.ShipNamesStats[generatedName][0]++;
                            created = await e.Guild.CreateVoiceChannelAsync(
                                channelName, autoCreateSloopCategory,
                                bitrate : Bot.BotSettings.Bitrate, user_limit : 2);
                        }
                        else if (e.Channel.Id == Bot.BotSettings.AutocreateBrigantine)
                        {
                            Bot.ShipNamesStats[generatedName][1]++;
                            created = await e.Guild.CreateVoiceChannelAsync(
                                channelName, autoCreateBrigantineCategory,
                                bitrate : Bot.BotSettings.Bitrate, user_limit : 3);
                        }
                        else
                        {
                            Bot.ShipNamesStats[generatedName][2]++;
                            created = await e.Guild.CreateVoiceChannelAsync(
                                channelName, autoCreateGalleongCategory,
                                bitrate : Bot.BotSettings.Bitrate, user_limit : 4);
                        }

                        FastShipStats.WriteToFile(Bot.ShipNamesStats, "generated/stats/ship_names.csv");

                        await member.PlaceInAsync(created);

                        client.Logger.LogInformation(BotLoggerEvents.Event, $"Участник {e.User.Username}#{e.User.Discriminator} ({e.User.Id}) создал канал через автосоздание." +
                                                     $" Каналов в категории: {created.Parent.Children.Count()}");
                    }
                }
            }
            catch (NullReferenceException) // исключение выбрасывается если пользователь покинул канал
            {
                // нам здесь ничего не надо делать, просто пропускаем
            }
        }
        public static async Task OnMessageCreated(MessageCreateEventArgs args)
        {
            if (args.Author.IsBot)
            {
                return;
            }

            if (string.IsNullOrEmpty(args.Message.Content) || args.Message.Content.StartsWith(Config.CommandPrefix))
            {
                return;
            }

            var lastBotMessages = await args.Channel.GetMessagesBeforeAsync(args.Message.Id, 20, DateTime.UtcNow.AddSeconds(-30)).ConfigureAwait(false);

            foreach (var msg in lastBotMessages)
            {
                if (BotShutupHandler.NeedToSilence(msg).needToChill)
                {
                    return;
                }
            }

            lastBotMessages = await args.Channel.GetMessagesBeforeAsync(args.Message.Id, Config.ProductCodeLookupHistoryThrottle).ConfigureAwait(false);

            StringBuilder previousRepliesBuilder = null;

            foreach (var msg in lastBotMessages)
            {
                if (msg.Author.IsCurrent)
                {
                    previousRepliesBuilder = previousRepliesBuilder ?? new StringBuilder();
                    previousRepliesBuilder.AppendLine(msg.Content);
                    var embeds = msg.Embeds;
                    if (embeds?.Count > 0)
                    {
                        foreach (var embed in embeds)
                        {
                            previousRepliesBuilder.AppendLine(embed.Title).AppendLine(embed.Description);
                        }
                    }
                }
            }
            var previousReplies = previousRepliesBuilder?.ToString() ?? "";

            var codesToLookup = GetProductIds(args.Message.Content)
                                .Where(c => !previousReplies.Contains(c, StringComparison.InvariantCultureIgnoreCase))
                                .Take(args.Channel.IsPrivate ? 50 : 5)
                                .ToList();

            if (codesToLookup.Count == 0)
            {
                return;
            }

            await args.Message.ReactWithAsync(args.Client, Config.Reactions.PleaseWait).ConfigureAwait(false);

            try
            {
                var results = new List <(string code, Task <DiscordEmbedBuilder> task)>(codesToLookup.Count);
                foreach (var code in codesToLookup)
                {
                    results.Add((code, args.Client.LookupGameInfoAsync(code)));
                }
                var formattedResults = new List <DiscordEmbedBuilder>(results.Count);
                foreach (var result in results)
                {
                    try
                    {
                        formattedResults.Add(await result.task.ConfigureAwait(false));
                    }
                    catch (Exception e)
                    {
                        Config.Log.Warn(e, $"Couldn't get product code info for {result.code}");
                    }
                }

                // get only results with unique titles
                formattedResults = formattedResults.GroupBy(e => e.Title).Select(g => g.First()).ToList();
                DiscordEmoji sqvat = null;
                foreach (var result in formattedResults)
                {
                    try
                    {
                        if (!args.Channel.IsPrivate &&
                            args.Message.Author.Id == 197163728867688448 &&
                            (
                                result.Title.Contains("africa", StringComparison.InvariantCultureIgnoreCase) ||
                                result.Title.Contains("afrika", StringComparison.InvariantCultureIgnoreCase)
                            ))
                        {
                            sqvat        = sqvat ?? args.Client.GetEmoji(":sqvat:", Config.Reactions.No);
                            result.Title = "How about no (๑•ิཬ•ั๑)";
                            if (!string.IsNullOrEmpty(result.ThumbnailUrl))
                            {
                                result.ThumbnailUrl = "https://cdn.discordapp.com/attachments/417347469521715210/516340151589535745/onionoff.png";
                            }
                            await args.Message.ReactWithAsync(args.Client, sqvat).ConfigureAwait(false);
                        }
                        await args.Channel.SendMessageAsync(embed : result).ConfigureAwait(false);
                    }
                    catch (Exception e)
                    {
                        Config.Log.Warn(e, $"Couldn't post result for {result.Title}");
                    }
                }
            }
            finally
            {
                await args.Message.RemoveReactionAsync(Config.Reactions.PleaseWait).ConfigureAwait(false);
            }
        }
示例#8
0
 public static string Cross()
 {
     return(DiscordEmoji.FromName(DiscordBot.Instance.Client, $":x:"));
 }
示例#9
0
        private static async Task CheckMessageAsync(DiscordClient client, DiscordChannel channel, DiscordUser user, DiscordMessage message, DiscordEmoji emoji, bool isBacklog)
        {
            try
            {
                if (user.IsBotSafeCheck() || channel.IsPrivate)
                {
                    return;
                }

                // in case it's not in cache and doesn't contain any info, including Author
                message = await channel.GetMessageAsync(message.Id).ConfigureAwait(false);

                if (emoji == Config.Reactions.Starbucks)
                {
                    await CheckMediaTalkAsync(client, channel, message, emoji).ConfigureAwait(false);
                }
                if (emoji == Config.Reactions.Shutup && !isBacklog)
                {
                    await ShutupAsync(client, user, message).ConfigureAwait(false);
                }
                if (emoji == Config.Reactions.BadUpdate && !isBacklog)
                {
                    await BadUpdateAsync(client, user, message, emoji).ConfigureAwait(false);
                }

                await CheckGameFansAsync(client, channel, message).ConfigureAwait(false);
            }
            catch (Exception e)
            {
                Config.Log.Error(e);
            }
        }
示例#10
0
        private static async Task Run()
        {
            discord.DebugLogger.LogMessageReceived += (o, e) =>
            {
                bool needsFileLogging = false;
                switch (e.Level)
                {
                case LogLevel.Debug:
                    Console.BackgroundColor = ConsoleColor.Gray;
                    break;

                case LogLevel.Info:
                    Console.BackgroundColor = ConsoleColor.DarkGreen;
                    break;

                case LogLevel.Warning:
                case LogLevel.Error:
                case LogLevel.Critical:
                    needsFileLogging = true;
                    switch (e.Level)
                    {
                    case LogLevel.Warning:
                        Console.BackgroundColor = ConsoleColor.DarkYellow;
                        break;

                    case LogLevel.Error:
                        Console.BackgroundColor = ConsoleColor.DarkRed;
                        break;

                    case LogLevel.Critical:
                        Console.BackgroundColor = ConsoleColor.Red;
                        break;
                    }
                    break;
                }
                Console.ForegroundColor = ConsoleColor.Black;
                Console.Write($"[{e.Level}]");
                Console.ResetColor();
                Console.WriteLine($" [{e.Timestamp}] [{e.Application}] {e.Message}");
                if (needsFileLogging)
                {
                    File.AppendAllLines(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "ChangeWatcher", "log.txt"), new[] { $"[{e.Level}] [{e.Timestamp}] [{e.Application}] {e.Message}" });
                    Environment.Exit(-1);
                }
            };

            discord.GuildAvailable += e =>
            {
                discord.DebugLogger.LogMessage(LogLevel.Info, "Cold-o-Bot", $"Guild available: {e.Guild.Name}", DateTime.Now);
                return(Task.Delay(0));
            };

            discord.MessageCreated += async e =>
            {
                discord.DebugLogger.LogMessage(LogLevel.Debug, "Cold-o-Bot",
                                               e.Message.Author.Username + ": " + e.Message.Content, DateTime.Now);
                if (e.Message.Content.StartsWith(prefix))
                {
                    string content = e.Message.Content.Substring(prefix.Length);
                    if (content.StartsWith("ping"))
                    {
                        DiscordMessage message = null;
                        await Task.Run(async() => message = await e.Message.RespondAsync($"pong!"));

                        await message.ModifyAsync(
                            $"{message.Content} `{e.Message.CreationTimestamp - message.CreationTimestamp:ss\'s\'fff\'m\'}`");
                    }

                    /*else if (content.StartsWith("test"))
                     * {
                     *  var split = content.Split(' ').Skip(1).ToArray();
                     *  if (split.Length == 0)
                     *  {
                     *      await e.Message.RespondAsync("something else?");
                     *      return;
                     *  }
                     *  switch (split[0])
                     *  {
                     *      case "0":
                     *          await e.Message.RespondAsync(((int)await new ScoreImageRequest("ColdVolcano", 848345, Mode.Osu).Perform()).ToString());
                     *          break;
                     *      case "1":
                     *          await e.Message.RespondAsync(((int)await new ScoreImageRequest("jakads", 249346, Mode.Mania).Perform()).ToString());
                     *          break;
                     *      case "2":
                     *          await e.Message.RespondAsync(((int)await new ScoreImageRequest("ColdVolcao", 848345, Mode.Osu).Perform()).ToString());
                     *          break;
                     *  }
                     *  bool isLink = LinkDecoder.IsValidBeatmapForImage(split[0], out var type);
                     *  if (isLink)
                     *  {
                     *      string response;
                     *      if (type.IsBeatmapset)
                     *      {
                     *          if (type.IsNewSite || type.IsOldSite)
                     *              response = "https://assets.ppy.sh/beatmaps/" + split[0].Split('/').Last() + "/covers/cover.jpg";
                     *          else
                     *              response = "https://assets.ppy.sh/beatmaps/" + split[0].TrimEnd('s') + "/covers/cover.jpg";
                     *      }
                     *      else
                     *      {
                     *          response = "https://assets.ppy.sh/beatmaps/" + (await new GetBeatmapsRequest(keys["osuKey"], false, beatmapID: int.Parse(split[0].Split('/').Last())).Perform()).Last().BeatmapsetID + "/covers/cover.jpg";
                     *      }
                     *      await e.Message.RespondAsync(response);
                     *      return;
                     *  }
                     *  await e.Message.RespondAsync("Given string was not a beatmap or beatmapset link");
                     * }*/
                    else if (content.StartsWith("about"))
                    {
                        double ramUsage;
                        using (var proc = Process.GetCurrentProcess())
                            ramUsage = proc.PrivateMemorySize64 / 1024d / 1024;
                        var time = DateTime.Now - timeStarted;
                        await e.Message.RespondAsync(embed : new DiscordEmbedBuilder()
                                                     .AddField("RAM usage:", ramUsage.ToString("00.0000") + "MB", true)
                                                     .AddField("Active since",
                                                               $"{string.Join(" ", timeStarted.ToUniversalTime().ToString().Split(new[] { ' ' }, 5).TakeWhile(s => s[0] != '-' && s[0] != '+'))} (it's been " +
                                                               (time.Days > 0 ? time.Days + "d" : "") + (time.Hours > 0 ? time.Hours + "h" : "") +
                                                               (time.Minutes > 0 ? time.Minutes + "m" : "") +
                                                               (time.Seconds + Math.Round(time.Milliseconds / 1000f) > 0
                                    ? time.Seconds + Math.Round(time.Milliseconds / 1000f) + "s"
                                    : "") + ")", true)
                                                     .AddField("Lib", $"DSharp+ v{discord.VersionString}"));
                    }
                    else if (content.StartsWith("user"))
                    {
                        string[] split = e.Message.Content.Split(' ');

                        if (!e.Channel.IsPrivate)
                        {
                            DiscordMember member;
                            if (split.Length == 1)
                            {
                                member = await e.Guild.GetMemberAsync(e.Message.Author.Id);
                            }
                            else
                            {
                                int i = 0;
                                for (; !char.IsDigit(split[1], i); i++)
                                {
                                }
                                if (!ulong.TryParse(split[1].Substring(i, split[1].Length - (i + 1)),
                                                    out var snowflake))
                                {
                                    return;
                                }
                                member = await e.Guild.GetMemberAsync(snowflake);

                                if (member == null)
                                {
                                    return;
                                }
                            }

                            DiscordEmbedBuilder builder = new DiscordEmbedBuilder()
                                                          .AddField("ID", member.Id.ToString(), true)
                                                          .AddField("Status", member.Presence?.Status.ToString() ?? "Offline", true)
                                                          .AddField("Time created",
                                                                    string.Join(" ",
                                                                                member.CreationTimestamp.ToUniversalTime().ToString().Split(new[] { ' ' }, 5)
                                                                                .TakeWhile(s => s[0] != '-' && s[0] != '+')), true)
                                                          .WithAuthor($"{member.Username}#{member.Discriminator}", icon_url: member.AvatarUrl)
                                                          .WithThumbnailUrl(member.AvatarUrl ?? member.DefaultAvatarUrl);
                            builder.AddField("Time joined",
                                             string.Join(" ",
                                                         member.JoinedAt.ToUniversalTime().ToString().Split(new[] { ' ' }, 5)
                                                         .TakeWhile(s => s[0] != '-' && s[0] != '+')), true);
                            string roles = string.Empty;
                            var    rol   = member.Roles.ToArray();
                            for (int j = 0; j < rol.Length; j++)
                            {
                                roles += rol[j].Name + (j + 1 == rol.Length ? "" : ", ");
                            }
                            if (roles.Length > 0)
                            {
                                builder.AddField("Roles", roles, true);
                            }
                            await e.Message.RespondAsync(embed : builder);
                        }
                        else
                        {
                            DiscordUser member = e.Author;

                            if (split.Length > 1)
                            {
                                await e.Message.RespondAsync("Can't add arguments in PM");

                                return;
                            }
                            await e.Message.RespondAsync(embed : new DiscordEmbedBuilder()
                                                         .AddField("ID", member.Id.ToString(), true)
                                                         .AddField("ID", member.Id.ToString(), true)
                                                         .AddField("Status", member.Presence?.Status.ToString() ?? "Offline", true)
                                                         .AddField("Time created",
                                                                   string.Join(" ",
                                                                               member.CreationTimestamp.ToUniversalTime().ToString().Split(new[] { ' ' }, 5)
                                                                               .TakeWhile(s => s[0] != '-' && s[0] != '+')), true)
                                                         .WithAuthor($"{member.Username}#{member.Discriminator}", icon_url : member.AvatarUrl)
                                                         .WithThumbnailUrl(member.AvatarUrl ?? member.DefaultAvatarUrl));
                        }
                    }
                    else if (content.StartsWith("twownk"))
                    {
                        await e.Message.CreateReactionAsync(DiscordEmoji.FromGuildEmote(discord, 320774047267029002));
                    }
                    else if (content.StartsWith("restart") && e.Message.Author.Id == 120196252775350273)
                    {
                        await e.Message.RespondAsync("Will start again in 4 seconds");

                        await discord.UpdateStatusAsync(userStatus : UserStatus.Invisible);

                        Task.Delay(2000).GetAwaiter().GetResult();
                        Task.Run(discord.DisconnectAsync).GetAwaiter().GetResult();
                        Process.GetCurrentProcess().CloseMainWindow();
                    }
                    else if (content.StartsWith("lenny"))
                    {
                        await e.Message.RespondAsync("( ͡° ͜ʖ ͡°)");
                    }
                    else if (content.StartsWith("deletemessages ") && e.Message.Author.Id == 120196252775350273)
                    {
                        string[] split = e.Message.Content.Split(' ');
                        if (split.Length == 2 && int.TryParse(split[1], out var count) && count > 0 && count < 5)
                        {
                            await e.Message.RespondAsync(DiscordEmoji.FromName(discord, ":put_litter_in_its_place:")
                                                         .ToString());

                            await e.Channel.DeleteMessagesAsync(e.Channel.GetMessagesBeforeAsync(e.Message, count)
                                                                .Result);
                        }
                        else
                        {
                            await e.Message.RespondAsync("Parameters do not match");
                        }
                    }
                    else if (content.StartsWith("serverinfo") && !e.Channel.IsPrivate)
                    {
                        await e.Message.RespondAsync("",
                                                     embed : new DiscordEmbedBuilder
                        {
                            Color        = new DiscordColor(),
                            ThumbnailUrl = e.Guild.IconUrl,
                        }
                                                     .WithAuthor(e.Guild.Name, icon_url : e.Guild.IconUrl)
                                                     .AddField("Owner", $"{e.Guild.Owner.Username}#{e.Guild.Owner.Discriminator}", true)
                                                     .AddField("Members", $"{e.Guild.MemberCount}", true)
                                                     .AddField("Time Created",
                                                               $"{string.Join(" ", e.Guild.CreationTimestamp.ToUniversalTime().ToString().Split(new[] { ' ' }, 5).TakeWhile(s => s[0] != '-' && s[0] != '+'))}",
                                                               true)
                                                     .AddField("Roles", $"{e.Guild.Roles.Count}", true)
                                                     .AddField("Channels",
                                                               $"{e.Guild.Channels.Count} ({e.Guild.Channels.Count(c => c.Type == ChannelType.Text)} text, {e.Guild.Channels.Count(c => c.Type == ChannelType.Voice)} voice)",
                                                               true));
                    }
                    else if (content.StartsWith("profile") && e.Message.Author.Id == 120196252775350273)
                    {
                        string[] split = e.Message.Content.Split(' ');
                        if (split.Length >= 3)
                        {
                            switch (split[1])
                            {
                            case "status":
                                bool canParse = Enum.TryParse(split[2], out UserStatus status);
                                if (canParse)
                                {
                                    await discord.UpdateStatusAsync(
                                        new DiscordActivity(discord.CurrentUser.Presence.Activity.Name,
                                                            discord.CurrentUser.Presence.Activity.ActivityType), status);

                                    await e.Message.RespondAsync(
                                        DiscordEmoji.FromName(discord, ":ok:").ToString() +
                                        " Succesfully updated online status");
                                }
                                else
                                {
                                    await e.Message.RespondAsync(
                                        DiscordEmoji.FromName(discord, ":octagonal_sign:").ToString() +
                                        " Could not parse values");
                                }
                                break;

                            case "game":
                                await discord.UpdateStatusAsync(
                                    new DiscordActivity(string.Join(" ", split.Skip(2).ToArray())),
                                    discord.CurrentUser.Presence.Status);

                                await e.Message.RespondAsync(DiscordEmoji.FromName(discord, ":ok:").ToString() +
                                                             " Succesfully updated online status");

                                break;
                            }
                        }
                        else
                        {
                            await e.Message.RespondAsync("Not enough arguments");
                        }
                    }
                    else if (content.StartsWith("roll"))
                    {
                        string[] split    = e.Message.Content.Split(' ');
                        uint     maxValue = 100;
                        int      value    = 0;
                        if (split.Length >= 2)
                        {
                            switch (split[1].Contains("d"))
                            {
                            case true:
                                string[] dicesAndMaxes = split[1].Split('d');
                                if (uint.TryParse(dicesAndMaxes[0], out var dices) &&
                                    uint.TryParse(dicesAndMaxes[1], out maxValue) ||
                                    int.TryParse(dicesAndMaxes[1], out value) && value != 0)
                                {
                                    if (dices == 1)
                                    {
                                        break;
                                    }
                                    if (dices == 0)
                                    {
                                        await e.Message.RespondAsync("Can't roll a dice I don't have");

                                        return;
                                    }
                                    if (dices <= 10)
                                    {
                                        if (maxValue == 0 && value == 0)
                                        {
                                            maxValue = 6;
                                        }
                                        var response =
                                            $"<@{e.Message.Author.Id}> rolled {dices} dices with {maxValue} sides:\n";
                                        long totalResult = 0;
                                        var  ran         = new Random();
                                        for (int i = 0; i < dices; i++)
                                        {
                                            var diceResult = value != 0
                                                    ? ran.Next(value, -1)
                                                    : ran.Next(1, (int)maxValue);
                                            totalResult += diceResult;
                                            response    += $"Dice {i + 1} got a {diceResult}\n";
                                        }
                                        response += $"A total of {totalResult} points!";
                                        await e.Message.RespondAsync(response);
                                    }
                                    else
                                    {
                                        await e.Message.RespondAsync(
                                            $"{e.Author.Mention}: You can only roll up to 10 dices");
                                    }
                                }
                                else
                                {
                                    break;
                                }
                                return;

                            case false:
                                if ((!uint.TryParse(split[1], out maxValue) || maxValue == 0) &&
                                    (!int.TryParse(split[1], out value) || value == 0))
                                {
                                    maxValue = 100;
                                }
                                break;
                            }
                        }
                        await e.Message.RespondAsync($"<@{e.Message.Author.Id}> rolled " +
                                                     (value != 0
                                                         ? new Random().Next(value, 0)
                                                         : new Random().Next(1, (int)maxValue)));
                    }
                }
            };

            discord.Ready += e =>
            {
                discord.DebugLogger.LogMessage(LogLevel.Info, "Cold-o-Bot", "Cold-o-Bot is now running!", DateTime.Now);
                timeStarted = DateTimeOffset.Now.ToUniversalTime();
                return(Task.Delay(1));
            };

            await discord.ConnectAsync();

            prefix = discord.CurrentUser.Username.EndsWith("Beta") ? "??" : "!!";

            await Task.Delay(-1);
        }
示例#11
0
        public async Task SetupReactionRolesCommand(CommandContext ctx, DiscordMember invoker)
        {
            List <DiscordMessage> messagesForCleanup = new List <DiscordMessage>();
            var channelTagMessage = await ctx.RespondAsync("Please tag the channel you wish to have the reaction roles message be in.");

            messagesForCleanup.Add(channelTagMessage);

            var response = await ctx.Message.GetNextMessageAsync();

            while (response.TimedOut || response.Result.MentionedChannels.Count == 0)
            {
                messagesForCleanup.Add(await ctx.RespondAsync("Please make sure to tag the channel you want place the reaction roles message in."));
                response = await ctx.Message.GetNextMessageAsync();
            }

            messagesForCleanup.Add(response.Result);
            var ReactionRoleMessageChannel = response.Result.MentionedChannels.First();

            var builder = new DiscordEmbedBuilder()
                          .WithTitle("Reaction Roles Setup")
                          .WithColor(DiscordColor.DarkGreen)
                          .WithDescription($"Please React to this message with the emoji you want to use, then follow the prompts before chosing another.\n" +
                                           $"React with {DiscordEmoji.FromName(ctx.Client, "stop_sign")} to finish.\n" +
                                           $"Chosen Reaction Roles:\n")
                          .WithTimestamp(DateTime.Now);

            var ReactionRoleReactionSelectionMessage = await ctx.RespondAsync(null, false, builder.Build());

            messagesForCleanup.Add(ReactionRoleReactionSelectionMessage);
            var EmojiSelectionResult = await ReactionRoleReactionSelectionMessage.WaitForReactionAsync(invoker);

            Dictionary <int, DiscordRole> OrderedRoles = new Dictionary <int, DiscordRole>();
            StringBuilder RolesStringBuilder           = new StringBuilder();
            int           lastRoleNumber = 1;

            foreach (var role in ctx.Guild.Roles)
            {
                RolesStringBuilder.Append($"`{lastRoleNumber}`: `{role.Value.Name}`\n");
                OrderedRoles.Add(lastRoleNumber++, role.Value);
            }

            var RolesString = RolesStringBuilder.ToString();

            while (!EmojiSelectionResult.TimedOut)
            {
                if (EmojiSelectionResult.Result.Emoji.Equals(DiscordEmoji.FromName(ctx.Client, "stop_sign")))
                {
                    foreach (var m in messagesForCleanup)
                    {
                        await m.DeleteAsync("Tavernkeep Interaction Cleanup");
                    }
                    return;
                }
                if (!EmojiRolePairs.ContainsKey(EmojiSelectionResult.Result.Emoji))
                {
                    var roleRequestEmbed = new DiscordEmbedBuilder()
                                           .WithTitle($"Role to assign for {EmojiSelectionResult.Result.Emoji}")
                                           .WithColor(DiscordColor.DarkGreen)
                                           .WithDescription("Please respond with a role number from the following list:\n" + RolesString)
                                           .Build();

                    var roleSelectionMessage = await ctx.RespondAsync(null, false, roleRequestEmbed);

                    messagesForCleanup.Add(roleSelectionMessage);

                    var RoleSelectResponse = await roleSelectionMessage.GetNextMessageAsync();

                    if (!RoleSelectResponse.TimedOut)
                    {
                        int.TryParse(RoleSelectResponse.Result.Content, out int selection);
                        if (OrderedRoles.ContainsKey(selection))
                        {
                            this.EmojiRolePairs.Add(EmojiSelectionResult.Result.Emoji, OrderedRoles[selection]);
                        }
                    }
                }
            }
        }
示例#12
0
        public async Task EnterBuilding(CommandContext c, Building building)
        {
            List <BuildingAction> actions = new List <BuildingAction>();

            Player player;

            using (var session = Db.DocStore.OpenAsyncSession())
            {
                var acts = await session.LoadAsync <BuildingAction>(building.Actions);

                actions.AddRange(acts.Values);

                player = await session.LoadAsync <Player>(c.User.Id.ToString());
            }

            var desc = new System.Text.StringBuilder();

            if (building.WelcomeMessage != null)
            {
                desc.AppendLine($"*\"{building.WelcomeMessage}\"*");
                desc.AppendLine();
            }

            foreach (var act in actions)
            {
                desc.AppendLine(act.Description);
            }

            var embed = new DiscordEmbedBuilder()
                        .WithColor(DiscordColor.Blurple)
                        .WithTitle(building.Name)
                        .WithDescription(desc.ToString())
                        .WithFooter(Realm.GetMessage("building_timeout"));
            var playerRespondMsg = await c.RespondAsync(embed : embed);

            foreach (var act in actions)
            {
                await playerRespondMsg.CreateReactionAsync(DiscordEmoji.FromName(c.Client, act.ReactionIcon));
            }

            await c.ConfirmMessage();

            var interact = c.Client.GetInteractivity();
            var response = await interact.WaitForMessageReactionAsync(playerRespondMsg, c.User, TimeSpan.FromSeconds(15));

            if (response == null)
            {
                await c.RejectMessage();

                await playerRespondMsg.DeleteAsync();

                return;
            }

            await playerRespondMsg.DeleteAllReactionsAsync();

            var responseName = response.Emoji.GetDiscordName().ToLower();

            var buildingActionId = actions.FirstOrDefault(ba => ba.ReactionIcon.Equals(responseName))?.Id;

            if (buildingActionId == null)
            {
                Serilog.Log.ForContext <GenericBuilding>().Error("Could not find BuildingAction with id {response}", responseName);
                await c.RejectMessage("An error occured. Contact one of the admins (Error_BuildingActionReactionIdNotFound)");

                return;
            }

            var attachment = await Db.DocStore.Operations.SendAsync(new GetAttachmentOperation(buildingActionId, "action.js", AttachmentType.Document, null));

            if (attachment == null)
            {
                Serilog.Log.ForContext <GenericBuilding>().Error($"{building.Name} is missing an action script.");
                await c.RejectMessage($"{building.Name} is missing an action script. Contact one of the admins (Error_BuildingActionScriptNotFound)");

                return;
            }

            string script = await new System.IO.StreamReader(attachment.Stream).ReadToEndAsync();

            await playerRespondMsg.DeleteAsync();

            await Script.ScriptManager.RunDiscordScriptAsync(buildingActionId, script, c, player, playerRespondMsg);
        }
示例#13
0
            public async Task WhoIs(CommandContext ctx, [Description("Пользователь"), RemainingText] DiscordUser user)
            {
                await ctx.TriggerTypingAsync();

                try
                {
                    DiscordMember member = null;
                    try
                    {
                        member = await ctx.Guild.GetMemberAsync(user.Id);
                    }
                    catch (NotFoundException)
                    {
                        // is not a member of the guild
                    }

                    //Сбор информации в переменные
                    var ban       = GetBansInfo(user.Id);
                    var warnings  = WarnSQL.GetForUser(user.Id).Count;
                    var reports   = ReportSQL.GetForUser(user.Id);
                    var webUser   = WebUser.GetByDiscordId(user.Id);
                    var voiceTime = VoiceListener.GetUpdatedVoiceTime(member.Id);

                    //Создание эмбеда
                    var embed = new DiscordEmbedBuilder();
                    embed.WithAuthor($"{user.Username}#{user.Discriminator}", iconUrl: user.AvatarUrl);
                    embed.WithThumbnail(user.AvatarUrl);

                    //Статус на сервере
                    if (ban != null)
                    {
                        embed.WithColor(new DiscordColor("#c0392b"));
                        embed.WithDescription($"Забанен до {ban}.");
                    }
                    else if (member == null)
                    {
                        embed.WithColor(new DiscordColor("#e67e22"));
                        embed.WithDescription("Не является участником.");
                    }
                    else
                    {
                        embed.WithColor(new DiscordColor("#27ae60"));
                        embed.WithDescription("Участник сервера.");
                    }


                    //1 Row - ID, Username
                    embed.AddFieldOrDefault("ID", user.Id.ToString(), true);
                    if (member != null)
                    {
                        embed.AddFieldOrDefault("Имя на сервере", member.Mention, true);
                    }
                    embed.NewInlineRow();

                    //2 Row - Creation and join dates, VoiceTime
                    embed.AddFieldOrDefault("Создан", user.CreationTimestamp.ToString("HH:mm:ss \n dd.MM.yyyy"), true);
                    if (member != null)
                    {
                        embed.AddFieldOrDefault("Присоединился", member.JoinedAt.ToString("HH:mm:ss \n dd.MM.yyyy"), true);
                    }
                    embed.AddFieldOrDefault("Время в каналах", $"{(voiceTime.Days * 24) + voiceTime.Hours}:{voiceTime.Minutes}", true);

                    //3 Row - WebUser info
                    if (webUser != null)
                    {
                        embed.AddFieldOrDefault("Привязка", "Да", true);
                        embed.AddFieldOrEmpty("Страна", GetCountryFlag(webUser.LastIp), true);
                        if (!string.IsNullOrEmpty(webUser.LastXbox))
                        {
                            embed.AddFieldOrDefault("Xbox", webUser.LastXbox.ToString(), true);
                        }
                        else
                        {
                            embed.AddFieldOrDefault("Xbox", "Нет", true);
                        }
                    }
                    embed.NewInlineRow();

                    //4 Row - Donate info
                    embed.AddFieldOrReplace("Донат", GetDonationInfo(user.Id), "Нет", true);
                    embed.AddFieldOrReplace("Подписка", GetSubscriptionInfo(user.Id), "Нет", true);
                    embed.AddFieldOrReplace("Приватный корабль", GetPrivateShip(user.Id), "Нет", true);
                    embed.NewInlineRow();

                    //5 Row - Reports info
                    embed.AddFieldOrDefault("Предупреждения", $":pencil: {warnings}", true);
                    embed.AddFieldOrDefault("Правила", GetCodexInfo(reports, member), true);
                    embed.AddFieldOrDefault("Правила рейда", GetFleetCodexInfo(reports, member), true);
                    embed.AddFieldOrDefault("Мут", $"{GetMutesInfo(reports)}", true);
                    embed.AddFieldOrDefault("Голосовой мут", $"{GetVoiceMutesInfo(reports)}", true);
                    embed.NewInlineRow();

                    //6 Row - Note
                    if (Note.Notes.ContainsKey(user.Id))
                    {
                        embed.AddFieldOrDefault("Заметка", Note.Notes[user.Id].Content);
                    }

                    embed.WithFooter("(*) Не принял после разблокировки");

                    var message = await ctx.RespondAsync(embed : embed.Build());

                    //Реакция на вывод сообщения с предупреждениями
                    if (warnings > 0)
                    {
                        var interactivity = ctx.Client.GetInteractivity();

                        var emoji = DiscordEmoji.FromName(ctx.Client, ":pencil:");

                        await message.CreateReactionAsync(emoji);

                        var em = await interactivity.WaitForReactionAsync(xe => xe.Emoji == emoji, message, ctx.User, TimeSpan.FromSeconds(60));

                        if (!em.TimedOut)
                        {
                            await ctx.TriggerTypingAsync();

                            var command = $"whois wl {user.Id}";

                            var cmds = ctx.CommandsNext;

                            // Ищем команду и извлекаем параметры.
                            var cmd = cmds.FindCommand(command, out var customArgs);

                            // Создаем фейковый контекст команды.
                            var fakeContext = cmds.CreateFakeContext(ctx.Member, ctx.Channel, command, ctx.Prefix, cmd, customArgs);

                            // Выполняем команду за пользователя.
                            await cmds.ExecuteCommandAsync(fakeContext);
                        }
                        else
                        {
                            await message.DeleteAllReactionsAsync();
                        }
                    }
                }
                catch (NotFoundException)
                {
                    await ctx.RespondAsync($"{Bot.BotSettings.ErrorEmoji} Пользователь не найден.");
                }
            }
示例#14
0
        public static async Task <Reaction> AddAndWaitForYesNoReaction(this InteractivityExtension interactivity, DiscordMessage msg, DiscordUser user)
        {
            DiscordClient client = interactivity.Client;

            await msg.CreateReactionAsync(DiscordEmoji.FromName(client, ":regional_indicator_y:"));

            await msg.CreateReactionAsync(DiscordEmoji.FromName(client, ":regional_indicator_n:"));

            InteractivityResult <MessageReactionAddEventArgs> interactivityResult = await interactivity.WaitForReactionAsync(msg, user);

            if (interactivityResult.TimedOut || interactivityResult.Result.Emoji.Equals(DiscordEmoji.FromName(client, ":regional_indicator_n:")))
            {
                DiscordMessage snark = await interactivityResult.Result.Channel.SendMessageAsync($"{user.Mention}, well then why did you get my attention! Thanks for wasting my time. Let me clean up now. :triumph:");

                await Task.Delay(5000);

                await interactivityResult.Result.Channel.DeleteMessagesAsync(new List <DiscordMessage> {
                    msg, snark
                });

                return(interactivityResult.TimedOut ? Reaction.None : Reaction.No);
            }

            await msg.DeleteAllReactionsAsync();

            return(Reaction.Yes);
        }
示例#15
0
        // Updates the grid with Emoji and value.
        public async Task UpdateField(List <Field> grid, DiscordMessage embed, DiscordEmoji demoji, DiscordEmoji playerEmoji, int playerValue)
        {
            for (int i = 0; i < 9; i++)
            {
                if (demoji == GameEmoji.OneThroughNine()[i])
                {
                    grid[i].FieldEmoji = playerEmoji;
                    grid[i].FieldValue = playerValue;
                }
            }

            await embed.ModifyAsync(embed : new Optional <DiscordEmbed>(CreatePlayField(grid))).ConfigureAwait(false);
        }
示例#16
0
        private static async Task CheckMediaTalkAsync(DiscordClient client, DiscordChannel channel, DiscordMessage message, DiscordEmoji emoji)
        {
            if (!Config.Moderation.Channels.Contains(channel.Id))
            {
                return;
            }

            // message.Timestamp throws if it's not in the cache AND is in local time zone
            if (DateTime.UtcNow - message.CreationTimestamp > Config.ModerationTimeThreshold)
            {
                return;
            }

            if (message.Reactions.Any(r => r.Emoji == emoji && (r.IsMe || r.Count < Config.Moderation.StarbucksThreshold)))
            {
                return;
            }

            if (message.Author.IsWhitelisted(client, channel.Guild))
            {
                return;
            }

            var users = await message.GetReactionsAsync(emoji).ConfigureAwait(false);

            if (users.Any(u => u.IsCurrent))
            {
                return;
            }

            var members = users
                          .Distinct()
                          .Select(u => channel.Guild
                                  .GetMemberAsync(u.Id)
                                  .ContinueWith(ct => ct.IsCompletedSuccessfully ? ct : Task.FromResult((DiscordMember)null), TaskScheduler.Default))
                          .ToList() //force eager task creation
                          .Select(t => t.Unwrap().ConfigureAwait(false).GetAwaiter().GetResult())
                          .Where(m => m != null)
                          .ToList();
            var reporters = members.Where(m => m.Roles.Any()).ToList();

            if (reporters.Count < Config.Moderation.StarbucksThreshold)
            {
                return;
            }

            await message.ReactWithAsync(emoji).ConfigureAwait(false);

            await client.ReportAsync(Config.Reactions.Starbucks + " Media talk report", message, reporters, null, ReportSeverity.Medium).ConfigureAwait(false);
        }
示例#17
0
        public async Task PostRoleText(CommandContext ctx)
        {
            //Declare emojis
            DiscordEmoji csgo   = DiscordEmoji.FromName(ctx.Client, ":gun:");
            DiscordEmoji valo   = DiscordEmoji.FromName(ctx.Client, ":bow_and_arrow:");
            DiscordEmoji lol    = DiscordEmoji.FromName(ctx.Client, ":crystal_ball:");
            DiscordEmoji phasmo = DiscordEmoji.FromName(ctx.Client, ":ghost:");

            DiscordEmoji linke   = DiscordEmoji.FromName(ctx.Client, ":mosquito:");
            DiscordEmoji grüne   = DiscordEmoji.FromName(ctx.Client, ":leaves:");
            DiscordEmoji afd     = DiscordEmoji.FromName(ctx.Client, ":clown:");
            DiscordEmoji fdp     = DiscordEmoji.FromName(ctx.Client, ":moneybag:");
            DiscordEmoji partei  = DiscordEmoji.FromName(ctx.Client, ":detective_tone2:");
            DiscordEmoji panther = DiscordEmoji.FromName(ctx.Client, ":wolf:");
            DiscordEmoji child   = DiscordEmoji.FromName(ctx.Client, ":underage:");
            DiscordEmoji horny   = DiscordEmoji.FromName(ctx.Client, ":eggplant:");


            if (ctx.Guild.Id == 939186520617783317)
            {
                #region Annies Server
                #region comments
                //DiscordEmoji male = DiscordEmoji.FromName(ctx.Client, ":prince:");
                //DiscordEmoji female = DiscordEmoji.FromName(ctx.Client, ":princess:");
                //DiscordEmoji divers = DiscordEmoji.FromName(ctx.Client, ":crown:");
                //DiscordEmoji baby = DiscordEmoji.FromName(ctx.Client, ":baby:");
                //DiscordEmoji teen = DiscordEmoji.FromName(ctx.Client, ":beer:");
                //DiscordEmoji adult = DiscordEmoji.FromName(ctx.Client, ":tumbler_glass:");
                //DiscordEmoji old = DiscordEmoji.FromName(ctx.Client, ":older_woman:");

                //var msgGender = await ctx.Channel.SendMessageAsync($"**Geschlecht**\n{female} weiblich\n{divers} divers\n{male} mänlich").ConfigureAwait(false);
                //await msgGender.CreateReactionAsync(female).ConfigureAwait(false);
                //await msgGender.CreateReactionAsync(divers).ConfigureAwait(false);
                //await msgGender.CreateReactionAsync(male).ConfigureAwait(false);

                //var msgAge = await ctx.Channel.SendMessageAsync($"**Alter**\n{baby} 12+\n{teen} 16+\n{adult} 18+\n{old} 21+").ConfigureAwait(false);
                //await msgAge.CreateReactionAsync(baby).ConfigureAwait(false);
                //await msgAge.CreateReactionAsync(teen).ConfigureAwait(false);
                //await msgAge.CreateReactionAsync(adult).ConfigureAwait(false);
                //await msgAge.CreateReactionAsync(old).ConfigureAwait(false);
                #endregion

                //Build message
                var msgGames = await ctx.Channel.SendMessageAsync($"**Reagiere hier um deine Rollen zu bekommen:**\n{csgo} CS:GO \n{valo} Valorant\n{lol} LoL\n{phasmo} Phasmophobia").ConfigureAwait(false);

                await msgGames.CreateReactionAsync(csgo).ConfigureAwait(false);

                await msgGames.CreateReactionAsync(valo).ConfigureAwait(false);

                await msgGames.CreateReactionAsync(lol).ConfigureAwait(false);

                await msgGames.CreateReactionAsync(phasmo).ConfigureAwait(false);

                #endregion
            }
            else if (ctx.Guild.Id == 327105561298599946)
            {
                #region Plebhunter
                //Politische Rollen
                var msgPolRoles = await ctx.Channel.SendMessageAsync($"**Wer sich politisch äußern möchte kann hier gerne sich Rollen abholen:**\n{linke} Linke\n{grüne} Grüne\n{afd} AFD\n{fdp} FDP\n{panther} Die grauen Panther\n{partei} Die Partei").ConfigureAwait(false);

                await msgPolRoles.CreateReactionAsync(linke).ConfigureAwait(false);

                await msgPolRoles.CreateReactionAsync(grüne).ConfigureAwait(false);

                await Task.Delay(1000);

                await msgPolRoles.CreateReactionAsync(afd).ConfigureAwait(false);

                await msgPolRoles.CreateReactionAsync(fdp).ConfigureAwait(false);

                await msgPolRoles.CreateReactionAsync(partei).ConfigureAwait(false);

                await msgPolRoles.CreateReactionAsync(panther).ConfigureAwait(false);

                await Task.Delay(1000);

                //Games
                var msgGameRoles = await ctx.Channel.SendMessageAsync($"**Lass mich in Ruhe, ich will zocken!**\n{csgo} CSGO\n{lol} LoL").ConfigureAwait(false);

                await msgGameRoles.CreateReactionAsync(csgo).ConfigureAwait(false);

                await msgGameRoles.CreateReactionAsync(lol).ConfigureAwait(false);

                await Task.Delay(1000);

                //Age Rollen
                var msgAgeRoles = await ctx.Channel.SendMessageAsync($"**Damit sich keiner beschweren kann:**\n{child} Minderjährig\n{horny} Horny on Main").ConfigureAwait(false);

                await msgAgeRoles.CreateReactionAsync(child).ConfigureAwait(false);

                await msgAgeRoles.CreateReactionAsync(horny).ConfigureAwait(false);

                await Task.Delay(1000);

                #endregion
            }


            //Delete executing message
            await ctx.Message.DeleteAsync();
        }
示例#18
0
        private static async Task BadUpdateAsync(DiscordClient client, DiscordUser user, DiscordMessage message, DiscordEmoji emoji)
        {
            if (message?.Channel.Id != Config.BotChannelId)
            {
                return;
            }

            if (!user.IsSmartlisted(client, message.Channel.Guild))
            {
                return;
            }

            await Moderation.ToggleBadUpdateAnnouncementAsync(message).ConfigureAwait(false);

            try
            {
                await message.DeleteReactionAsync(emoji, user).ConfigureAwait(false);
            }
            catch { }
        }
示例#19
0
        public static async Task UpdateFindChannelEmbedOnVoiceStateUpdated(DiscordClient client, VoiceStateUpdateEventArgs e)
        {
            if (e.Before?.Channel?.Id == e.After?.Channel?.Id)
            {
                return;
            }

            List <DiscordChannel> channels = new List <DiscordChannel>();

            if (e.Before?.Channel?.Id != null)
            {
                channels.Add(e.Before.Channel);
            }

            if (e.After?.Channel?.Id != null)
            {
                channels.Add(e.After.Channel);
            }

            foreach (var channel in channels)
            {
                try
                {
                    if (FindChannelInvites.ContainsKey(channel.Id))
                    {
                        client.Logger.LogDebug(BotLoggerEvents.Event, $"Получение сообщения в поиске игроков!");
                        try
                        {
                            var embedMessage = await e.Guild.GetChannel(Bot.BotSettings.FindChannel).GetMessageAsync(FindChannelInvites[channel.Id]);

                            if (channel.Users.Count() == 0)
                            {
                                try
                                {
                                    client.Logger.LogDebug(BotLoggerEvents.Event, $"Удаление ембеда в поиске игроков!");
                                    await embedMessage.DeleteAsync();

                                    FindChannelInvites.Remove(channel.Id);
                                    await SaveFindChannelMessagesAsync();
                                }
                                catch (NotFoundException) { }
                            }
                            else
                            {
                                var oldEmbed   = embedMessage.Embeds.FirstOrDefault();
                                var oldContent = oldEmbed.Description.Split("\n\n");

                                var usersNeeded = channel.UserLimit - channel.Users.Count();

                                var embedThumbnail = "";
                                //Если канал в категории рейда, вставляем картинку с рейдом и проверяем если это обычный канал рейда (в нём 1 лишний слот, его мы игнорируем)
                                if (channel.Parent.Name.StartsWith("Рейд"))
                                {
                                    if (channel.Name.StartsWith("Рейд"))
                                    {
                                        usersNeeded = Math.Max(0, (usersNeeded - 1));
                                    }

                                    embedThumbnail = usersNeeded switch
                                    {
                                        0 => Bot.BotSettings.ThumbnailFull,
                                        _ => Bot.BotSettings.ThumbnailRaid
                                    };
                                }
                                //Если это не канал рейда, вставляем подходящую картинку по слотам, или NA если число другое
                                else
                                {
                                    embedThumbnail = usersNeeded switch
                                    {
                                        0 => Bot.BotSettings.ThumbnailFull,
                                        1 => Bot.BotSettings.ThumbnailOne,
                                        2 => Bot.BotSettings.ThumbnailTwo,
                                        3 => Bot.BotSettings.ThumbnailThree,
                                        _ => Bot.BotSettings.ThumbnailNA
                                    };
                                }

                                //Index 0 for description
                                var content = $"{oldContent[0]}\n\n";

                                //Index 1 for users in channel
                                var slotsCount = 1;
                                foreach (var member in channel.Users)
                                {
                                    if (content.Length > 1900 || slotsCount > 15)
                                    {
                                        content += $"{DiscordEmoji.FromName(client, ":arrow_heading_down:")} и еще {channel.Users.Count() - slotsCount + 1}.\n";
                                        break;
                                    }
                                    else
                                    {
                                        content += $"{DiscordEmoji.FromName(client, ":doubloon:")} {member.Mention}\n";
                                        slotsCount++;
                                    }
                                }

                                for (int i = 0; i < usersNeeded; i++)
                                {
                                    if (content.Length > 1900 || slotsCount > 15)
                                    {
                                        if (i != 0) //Без этого сообщение будет отправлено вместе с тем что выше
                                        {
                                            content += $"{DiscordEmoji.FromName(client, ":arrow_heading_down:")} и еще {channel.UserLimit - slotsCount + 1} свободно.\n";
                                        }
                                        break;
                                    }
                                    else
                                    {
                                        content += $"{DiscordEmoji.FromName(client, ":gold:")} ☐\n";
                                        slotsCount++;
                                    }
                                }

                                //Index 2 for invite link
                                content += $"\n{oldContent[2]}";

                                //Embed
                                var embed = new DiscordEmbedBuilder
                                {
                                    Description = content,
                                    Color       = usersNeeded == 0 ? new DiscordColor("#2c3e50") : new DiscordColor("#e67e22")
                                };

                                embed.WithAuthor($"{channel.Name}", oldEmbed.Author.Url.ToString(), oldEmbed.Author.IconUrl.ToString());
                                embed.WithThumbnail(embedThumbnail);
                                embed.WithTimestamp(DateTime.Now);
                                embed.WithFooter(usersNeeded != 0 ? $"В поиске команды. +{usersNeeded}" : $"Канал заполнен {DiscordEmoji.FromName(client, ":no_entry:")}");

                                client.Logger.LogDebug(BotLoggerEvents.Event, $"Обновление ембеда в поиске игроков!");
                                await embedMessage.ModifyAsync(embed : embed.Build());
                            }
                        }
                        catch (NotFoundException)
                        {
                            FindChannelInvites.Remove(channel.Id);
                        }
                    }
                }
                catch (NullReferenceException)
                {
                    client.Logger.LogWarning(BotLoggerEvents.Event, $"Не удалось обновить сообщение с эмбедом для голосового канала. Канал будет удалён из привязки к сообщению.");
                    FindChannelInvites.Remove(channel.Id);
                    await SaveFindChannelMessagesAsync();

                    return;
                }
            }
        }
示例#20
0
        private static async Task DispatchTimer(TimerData tdata)
        {
            var timer  = tdata.DbTimer;
            var client = tdata.Context;

            if (timer.ActionType == TimerActionType.Reminder)
            {
                DiscordChannel chn = null;
                try
                {
                    chn = await client.GetChannelAsync((ulong)timer.ChannelId);
                }
                catch
                {
                    return;
                }

                if (chn == null)
                {
                    return;
                }

                var data  = timer.GetData <TimerReminderData>();
                var emoji = DiscordEmoji.FromName(client, ":alarm_clock:");
                var user  = (ulong)timer.UserId;
                var msg   = $"{emoji} <@!{user}>, you wanted to be reminded of the following:\n\n{data.ReminderText}";
                await chn.SafeMessageAsync(msg, false);

                // ALWAYS filter stuff so i set it to false. No need to @everyone in a reminder.
            }
            else if (timer.ActionType == TimerActionType.Unban)
            {
                var data = timer.GetData <TimerUnbanData>();
                if (client.Guilds.Any(x => x.Key == (ulong)timer.GuildId))
                {
                    using (var db = tdata.Database.CreateContext())
                    {
                        var guild = client.Guilds[(ulong)timer.GuildId];
                        try
                        {
                            await guild.UnbanMemberAsync((ulong)data.UserId);
                        }
                        catch
                        {
                            // ignored
                        }

                        var settings = guild.GetGuildSettings(db);
                        await client.LogAutoActionAsync(guild, db, $"Member unbanned: {data.DisplayName}#{data.Discriminator} (ID: {data.UserId})");
                    }
                }
            }
            else if (timer.ActionType == TimerActionType.Unmute)
            {
                var data = timer.GetData <TimerUnmuteData>();
                if (client.Guilds.Any(x => x.Key == (ulong)timer.GuildId))
                {
                    using (var db = tdata.Database.CreateContext())
                    {
                        var guild  = client.Guilds[(ulong)timer.GuildId];
                        var member = await guild.GetMemberAsync((ulong)data.UserId);

                        var role = (DiscordRole)null;
                        try
                        {
                            role = guild.GetRole((ulong)data.MuteRoleId);
                        }
                        catch (Exception)
                        {
                            try
                            {
                                role = guild.GetRole(guild.GetGuildSettings(db).MuteRoleId);
                            }
                            catch (Exception)
                            {
                                await client.LogAutoActionAsync(guild, db, $"**[IMPORTANT]**\nFailed to unmute member: {data.DisplayName}#{data.Discriminator} (ID: {data.UserId})\nMute role does not exist!");

                                return;
                            }
                        }
                        await member.RevokeRoleAsync(role, "");

                        await client.LogAutoActionAsync(guild, db, $"Member unmuted: {data.DisplayName}#{data.Discriminator} (ID: {data.UserId})");
                    }
                }
            }
            else if (timer.ActionType == TimerActionType.Pin)
            {
                var data = timer.GetData <TimerPinData>();
                if (client.Guilds.Any(x => x.Key == (ulong)timer.GuildId))
                {
                    using (var db = tdata.Database.CreateContext())
                    {
                        var guild   = client.Guilds[(ulong)timer.GuildId];
                        var channel = guild.GetChannel((ulong)data.ChannelId);
                        var message = await channel.GetMessageAsync((ulong)data.MessageId);

                        await message.PinAsync();

                        await client.LogAutoActionAsync(guild, db, $"Scheduled pin: Message with ID: {data.MessageId} in Channel #{channel.Name} ({channel.Id})");
                    }
                }
            }
            else if (timer.ActionType == TimerActionType.Unpin)
            {
                var data = timer.GetData <TimerPinData>();
                if (client.Guilds.Any(x => x.Key == (ulong)timer.GuildId))
                {
                    using (var db = tdata.Database.CreateContext())
                    {
                        var guild   = client.Guilds[(ulong)timer.GuildId];
                        var channel = guild.GetChannel((ulong)data.ChannelId);
                        var message = await channel.GetMessageAsync((ulong)data.MessageId);

                        await message.UnpinAsync();

                        await client.LogAutoActionAsync(guild, db, $"Scheduled unpin: Message with ID: {data.MessageId} in Channel #{channel.Name} ({channel.Id})");
                    }
                }
            }
        }
 public static Task <int> RemoveEmojiReactionsEAsync(this ReactionsService service, ulong gid, DiscordEmoji emoji)
 => service.RemoveEmojiReactionsAsync(gid, emoji.GetDiscordName());
示例#22
0
        public async Task Help(CommandContext ctx)
        {
            var                   interactivity = ctx.Client.GetInteractivity();
            int                   i             = 0;
            List <string>         Cmds          = new List <string>();
            List <List <string> > c             = new List <List <string> >();

            var Commands = ctx.Client.GetCommandsNext();

            foreach (KeyValuePair <string, Command> cmd in Commands.RegisteredCommands)
            {
                if (!cmd.Value.IsHidden)
                {
                    Cmds.Add(cmd.Key);
                }
            }
            for (int j = 0; j < Cmds.Count; j += 5)
            {
                c.Add(Cmds.Skip(j).Take(j + 5).ToList());
            }
            var Pages = Math.Ceiling(Cmds.Count / 5.0);
            var embed = new DiscordEmbedBuilder
            {
                Title = "Official server",
                Url   = "https://discord.gg/kwcd9dq",
                Color = new DiscordColor(9043849)
            }.WithAuthor($"Page {i + 1}/{Pages}", null, ctx.Client.CurrentUser.AvatarUrl)
            .WithFooter($"PennyBot | Lilwiggy {DateTime.UtcNow.Year}");

            foreach (string s in c[i])
            {
                // Console.WriteLine(s);
                // Console.WriteLine(c[i]);
                embed.AddField(s, Commands.RegisteredCommands.Values.ToList().Find(x => x.Name == s).Description);
            }

            var m = await ctx.Channel.SendMessageAsync("", embed : embed);

            await m.CreateReactionAsync(DiscordEmoji.FromUnicode("⬅"));

            await m.CreateReactionAsync(DiscordEmoji.FromUnicode("➡"));

            var help = new HelpCommandHelper();

            while (true)
            {
                var em = await interactivity.WaitForReactionAsync(e => e == DiscordEmoji.FromUnicode("➡") || e == DiscordEmoji.FromUnicode("⬅"), ctx.User, TimeSpan.FromMinutes(3));

                if (em == null)
                {
                    break;
                }
                if (em.Emoji == DiscordEmoji.FromUnicode("➡"))
                {
                    if (i == Pages - 1)
                    {
                        i = 0;
                    }
                    else
                    {
                        i++;
                    }
                }
                else if (em.Emoji == DiscordEmoji.FromUnicode("⬅"))
                {
                    if (i == 0)
                    {
                        i = Convert.ToInt32(Pages) - 1;
                    }
                    else
                    {
                        i--;
                    }
                }
                Console.WriteLine("hi");
                await m.DeleteReactionAsync(em.Emoji, ctx.User);

                var emb = help.GetCommandsEmbed(ctx, i, m);
                Console.WriteLine(emb.Fields[0].Value);
                await m.ModifyAsync("", emb);
            }
            ;
        }
示例#23
0
        public async Task SendMeetingReminder(DiscordClient client)
        {
            var discordGuild = client.Guilds.FirstOrDefault(g => g.Key == Constants.GuildId).Value;

            if (discordGuild == null)
            {
                Console.Error.WriteLine("Could not find the specified guild");
                return;
            }

            var now = DateTime.Now;

            var events = await GetFoxtrotCalendarEvents(now);

            foreach (var evt in events.Items)
            {
                var eventDateStart = evt.Start != null ? evt.Start.DateTime : null;
                if (eventDateStart == null)
                {
                    continue;
                }

                var eventDateEnd = evt.End != null ? evt.End.DateTime : null;
                if (eventDateEnd == null)
                {
                    continue;
                }

                var deltaTime = (eventDateStart - now).Value.TotalMinutes;
                if (15 >= deltaTime && deltaTime > 0.0)
                {
                    var isReminded =
                        await _reminderRepository.IsReminded(eventDateStart.Value, discordGuild.Id, evt.Summary);

                    if (isReminded.status == Status.Found || isReminded.reminded)
                    {
                        continue;
                    }

                    var reminder = new ReminderDTO
                    {
                        StartTime = eventDateStart.Value,
                        GuildId   = discordGuild.Id,
                        Summary   = evt.Summary,
                        Reminded  = true
                    };

                    var channel = discordGuild.Channels.FirstOrDefault(c => c.Key == Constants.ReminderChannelId).Value;
                    if (channel == null)
                    {
                        Console.Error.WriteLine("Could not find the reminder channel");
                        continue;
                    }

                    var foxtrotRole =
                        discordGuild.Roles.Values.FirstOrDefault(r => r.Name.ToLower().Contains("foxtrot"));

                    await _reminderRepository.Create(reminder);

                    var messageText = $" **{evt.Summary}** is today from {eventDateStart:HH:mm} - {eventDateEnd:HH:mm}. Remember to start your [time tracking](https://clockify.me/tracker).";

                    var reminderEmbed = new DiscordEmbedBuilder
                    {
                        Title       = evt.Summary,
                        Description = messageText,
                        Timestamp   = DateTimeOffset.Now,
                        Color       = DiscordColor.Aquamarine
                    };

                    var messageBuilder = new DiscordMessageBuilder
                    {
                        Content = foxtrotRole != null ? foxtrotRole.Mention : "@here",
                        Embed   = reminderEmbed
                    };
                    var message = await channel.SendMessageAsync(messageBuilder);

                    await message.CreateReactionAsync(DiscordEmoji.FromName(client, ":gift:"));
                }
            }
        }
示例#24
0
 public async Task Ping(CommandContext ctx)
 {
     var emoji = DiscordEmoji.FromName(ctx.Client, ":ping_pong:");
     await ctx.Channel.SendMessageAsync($"{ctx.User.Mention} {emoji} Pong! Ping: {ctx.Client.Ping}ms");
 }
示例#25
0
 /// <summary>
 /// Links a emoji to a role.
 /// </summary>
 /// <param name="guild"></param>
 /// <param name="emoji"></param>
 /// <returns></returns>
 public async Task AddReactionRoleAsync(DiscordMessage message, DiscordEmoji emoji, DiscordRole role)
 {
     string key = Namespace.Combine(message.Channel.Guild, REDIS_REACT_ROLE, message);
     await Redis.StoreStringAsync(key, emoji.Id.ToString(), role.Id.ToString());
 }
        private async Task <(bool success, DiscordMessage message)> EditEventPropertiesAsync(CommandContext ctx, EventSchedule evt, string eventName = null)
        {
            var interact     = ctx.Client.GetInteractivity();
            var abort        = DiscordEmoji.FromUnicode("🛑");
            var lastPage     = DiscordEmoji.FromUnicode("↪");
            var firstPage    = DiscordEmoji.FromUnicode("↩");
            var previousPage = DiscordEmoji.FromUnicode("⏪");
            var nextPage     = DiscordEmoji.FromUnicode("⏩");
            var trash        = DiscordEmoji.FromUnicode("🗑");
            var saveEdit     = DiscordEmoji.FromUnicode("💾");

            var            skipEventNameStep = !string.IsNullOrEmpty(eventName);
            DiscordMessage msg      = null;
            string         errorMsg = null;
            DiscordMessage txt;
            MessageReactionAddEventArgs emoji;

step1:
            // step 1: get the new start date
            var embed = FormatEvent(evt, errorMsg, 1).WithDescription($"Example: `{DateTime.UtcNow:yyyy-MM-dd HH:mm} PST`\nBy default all times use UTC, only limited number of time zones supported");

            msg = await msg.UpdateOrCreateMessageAsync(ctx.Channel, "Please specify a new **start date and time**", embed : embed).ConfigureAwait(false);

            errorMsg          = null;
            (msg, txt, emoji) = await interact.WaitForMessageOrReactionAsync(msg, ctx.User, InteractTimeout, abort, lastPage, nextPage, (evt.IsComplete() ? saveEdit : null)).ConfigureAwait(false);

            if (emoji != null)
            {
                if (emoji.Emoji == abort)
                {
                    return(false, msg);
                }

                if (emoji.Emoji == saveEdit)
                {
                    return(true, msg);
                }

                if (emoji.Emoji == lastPage)
                {
                    goto step4;
                }
            }
            else if (txt != null)
            {
                if (!TimeParser.TryParse(txt.Content, out var newTime))
                {
                    errorMsg = $"Couldn't parse `{txt.Content}` as a start date and time";
                    goto step1;
                }
                if (newTime < DateTime.UtcNow && evt.End == default)
                {
                    errorMsg = "Specified time is in the past, are you sure it is correct?";
                }


                var duration = evt.End - evt.Start;
                evt.Start = newTime.Ticks;
                evt.End   = evt.Start + duration;
                evt.Year  = newTime.Year;
            }
            else
            {
                return(false, msg);
            }

step2:
            // step 2: get the new duration
            embed = FormatEvent(evt, errorMsg, 2).WithDescription("Example: `2d 1h 15m`, or `2.1:00`");
            msg   = await msg.UpdateOrCreateMessageAsync(ctx.Channel, "Please specify a new **event duration**", embed : embed.Build()).ConfigureAwait(false);

            errorMsg          = null;
            (msg, txt, emoji) = await interact.WaitForMessageOrReactionAsync(msg, ctx.User, InteractTimeout, abort, previousPage, nextPage, (evt.IsComplete() ? saveEdit : null)).ConfigureAwait(false);

            if (emoji != null)
            {
                if (emoji.Emoji == abort)
                {
                    return(false, msg);
                }

                if (emoji.Emoji == saveEdit)
                {
                    return(true, msg);
                }

                if (emoji.Emoji == previousPage)
                {
                    goto step1;
                }

                if (skipEventNameStep)
                {
                    goto step4;
                }
            }
            else if (txt != null)
            {
                var newLength = await TryParseTimeSpanAsync(ctx, txt.Content, false).ConfigureAwait(false);

                if (!newLength.HasValue)
                {
                    errorMsg = $"Couldn't parse `{txt.Content}` as a duration";
                    goto step2;
                }

                evt.End = (evt.Start.AsUtc() + newLength.Value).Ticks;
            }
            else
            {
                return(false, msg);
            }

step3:
            // step 3: get the new event name
            embed = FormatEvent(evt, errorMsg, 3);
            msg   = await msg.UpdateOrCreateMessageAsync(ctx.Channel, "Please specify a new **event name**", embed : embed.Build()).ConfigureAwait(false);

            errorMsg          = null;
            (msg, txt, emoji) = await interact.WaitForMessageOrReactionAsync(msg, ctx.User, InteractTimeout, abort, previousPage, (string.IsNullOrEmpty(evt.EventName) ? null : trash), nextPage, (evt.IsComplete() ? saveEdit : null)).ConfigureAwait(false);

            if (emoji != null)
            {
                if (emoji.Emoji == abort)
                {
                    return(false, msg);
                }

                if (emoji.Emoji == saveEdit)
                {
                    return(true, msg);
                }

                if (emoji.Emoji == previousPage)
                {
                    goto step2;
                }

                if (emoji.Emoji == trash)
                {
                    evt.EventName = null;
                }
            }
            else if (txt != null)
            {
                evt.EventName = string.IsNullOrWhiteSpace(txt.Content) || txt.Content == "-" ? null : txt.Content;
            }
            else
            {
                return(false, msg);
            }

step4:
            // step 4: get the new schedule entry name
            embed = FormatEvent(evt, errorMsg, 4);
            msg   = await msg.UpdateOrCreateMessageAsync(ctx.Channel, "Please specify a new **schedule entry title**", embed : embed.Build()).ConfigureAwait(false);

            errorMsg          = null;
            (msg, txt, emoji) = await interact.WaitForMessageOrReactionAsync(msg, ctx.User, InteractTimeout, abort, previousPage, firstPage, (evt.IsComplete() ? saveEdit : null)).ConfigureAwait(false);

            if (emoji != null)
            {
                if (emoji.Emoji == abort)
                {
                    return(false, msg);
                }

                if (emoji.Emoji == saveEdit)
                {
                    return(true, msg);
                }

                if (emoji.Emoji == firstPage)
                {
                    goto step1;
                }

                if (emoji.Emoji == previousPage)
                {
                    if (skipEventNameStep)
                    {
                        goto step2;
                    }
                    goto step3;
                }
            }
            else if (txt != null)
            {
                if (string.IsNullOrEmpty(txt.Content))
                {
                    errorMsg = "Entry title cannot be empty";
                    goto step4;
                }

                evt.Name = txt.Content;
            }
            else
            {
                return(false, msg);
            }

step5:
            // step 5: confirm
            if (errorMsg == null && !evt.IsComplete())
            {
                errorMsg = "Some required properties are not defined";
            }
            embed = FormatEvent(evt, errorMsg);
            msg   = await msg.UpdateOrCreateMessageAsync(ctx.Channel, "Does this look good? (y/n)", embed : embed.Build()).ConfigureAwait(false);

            errorMsg          = null;
            (msg, txt, emoji) = await interact.WaitForMessageOrReactionAsync(msg, ctx.User, InteractTimeout, abort, previousPage, firstPage, (evt.IsComplete() ? saveEdit : null)).ConfigureAwait(false);

            if (emoji != null)
            {
                if (emoji.Emoji == abort)
                {
                    return(false, msg);
                }

                if (emoji.Emoji == saveEdit)
                {
                    return(true, msg);
                }

                if (emoji.Emoji == previousPage)
                {
                    goto step4;
                }

                if (emoji.Emoji == firstPage)
                {
                    goto step1;
                }
            }
            else if (!string.IsNullOrEmpty(txt?.Content))
            {
                if (!evt.IsComplete())
                {
                    goto step5;
                }

                switch (txt.Content.ToLowerInvariant())
                {
                case "yes":
                case "y":
                case "✅":
                case "☑":
                case "✔":
                case "👌":
                case "👍":
                    return(true, msg);

                case "no":
                case "n":
                case "❎":
                case "❌":
                case "👎":
                    return(false, msg);

                default:
                    errorMsg = "I don't know what you mean, so I'll just abort";
                    goto step5;
                }
            }
            else
            {
                return(false, msg);
            }

            return(false, msg);
        }
示例#27
0
        private async Task Commands_CommandErrored(CommandErrorEventArgs e)
        {
            e.Context.Client.DebugLogger.LogMessage(LogLevel.Error, this.Bot.LogName, $"{e.Context.User.Username} tried executing '{e.Command?.QualifiedName ?? "<unknown command>"}' but it errored: {e.Exception.GetType()}: {e.Exception.Message ?? "<no message>"}", DateTime.Now);


            var ex = e.Exception;

            while (ex is AggregateException || ex.InnerException != null)
            {
                ex = ex.InnerException;
            }

            // Check if exception is result of command prechecks.
            switch (ex)
            {
            case ChecksFailedException exep:
            {
                var failedchecks = exep.FailedChecks.First();
                switch (failedchecks)
                {
                // Bot is lacking permissions.
                case RequireBotPermissionsAttribute reqbotperm:
                {
                    string permissionsLacking = reqbotperm.Permissions.ToPermissionString();
                    var    emoji = DiscordEmoji.FromName(e.Context.Client, ":no_entry:");
                    await e.Context.RespondAsync(embed : EmbedTemplates.CommandErrorEmbed(e.Context.Member, e.Command)
                                                 .WithTitle($"{emoji} Боту не хватает прав")
                                                 .WithDescription(permissionsLacking)).ConfigureAwait(false);

                    break;
                }

                // User is lacking permissions.
                case RequireUserPermissionsAttribute requserperm:
                {
                    string permissionsLacking = requserperm.Permissions.ToPermissionString();
                    var    emoji = DiscordEmoji.FromName(e.Context.Client, ":no_entry:");

                    await e.Context.RespondAsync(embed : EmbedTemplates.CommandErrorEmbed(e.Context.Member, e.Command)
                                                 .WithTitle($"{emoji} Вам не хватает прав")
                                                 .WithDescription(permissionsLacking)).ConfigureAwait(false);

                    break;
                }

                // User is not owner of the bot.
                case RequireOwnerAttribute reqowner:
                {
                    var emoji = DiscordEmoji.FromName(e.Context.Client, ":no_entry:");
                    await e.Context.RespondAsync(embed : EmbedTemplates.CommandErrorEmbed(e.Context.Member, e.Command)
                                                 .WithTitle($"{emoji} Команда доступна только владельцу")).ConfigureAwait(false);

                    break;
                }

                // User is not owner or don't have permissions.
                case OwnerOrPermissionAttribute ownerOrPermission:
                {
                    string permissionsLacking = ownerOrPermission.Permissions.ToPermissionString();
                    var    emoji = DiscordEmoji.FromName(e.Context.Client, ":no_entry:");
                    await e.Context.RespondAsync(embed : EmbedTemplates.CommandErrorEmbed(e.Context.Member, e.Command)
                                                 .WithTitle($"{emoji} Вы не являетесь владельцем или вам не хватает прав")
                                                 .WithDescription(permissionsLacking)).ConfigureAwait(false);

                    break;
                }

                // Command shouldn't be executed so fast.
                case CooldownAttribute cooldown:
                {
                    await e.Context.RespondAsync(embed : EmbedTemplates.CommandErrorEmbed(e.Context.Member, e.Command)
                                                 .WithDescription("Вы пытаетесь использовать команду слишком часто, таймер - " +
                                                                  $"не больше {cooldown.MaxUses} раз в {cooldown.Reset.TotalMinutes} минут")).ConfigureAwait(false);

                    break;
                }

                // User wasn't connected to voice channel. Optionally to the same voice channel as bot
                case RequireVoiceConnectionAttribute requireVoice:
                {
                    await e.Context.RespondAsync(embed : EmbedTemplates.CommandErrorEmbed(e.Context.Member, e.Command)
                                                 .WithDescription($"Вы должны быть подключены к {(requireVoice.SameVoiceChannelAsBot ? "тому же голосовому каналу что и бот" : "голосовому каналу")}")).ConfigureAwait(false);

                    break;
                }

                default:
                {
                    await e.Context.RespondAsync(embed : EmbedTemplates.CommandErrorEmbed(e.Context.Member, e.Command)
                                                 .WithDescription($"Вам не хватает прав, чтобы узнать каких используйте {Formatter.InlineCode($"{this.Bot.Config.Discord.Prefixes.RandomElement()}help {e.Command.QualifiedName}")}"));

                    break;
                }
                }

                break;
            }

            case DatabaseException dbEx:
            {
                var description = new StringBuilder("Произошла ошибка в работе БД, возможно стоит попробовать чуть позже.");
                description.AppendLine(string.IsNullOrWhiteSpace(dbEx.Message)
                                                ? $"Тип действия: {dbEx.ActionType.ToString()}"
                                                : $"Сообщение - {Formatter.InlineCode(dbEx.Message)}. Тип действия: {dbEx.ActionType.ToString()}");

                await e.Context.RespondAsync(embed : EmbedTemplates.CommandErrorEmbed(e.Context.Member, e.Command)
                                             .WithDescription(description.ToString())).ConfigureAwait(false);

                break;
            }

            case DiscordUserInputException inputEx:
            {
                await e.Context.RespondAsync($"{inputEx.Message}. Название параметра {inputEx.ArgumentName}").ConfigureAwait(false);

                break;
            }

            case CommandNotFoundException commandNotFoundException:
            {
                var cmdName           = commandNotFoundException.CommandName;
                var suggestedCommands = new List <Command>();
                var nL = new NormalizedLevenshtein();

                // Let's assumme that 0.33 is good Levenshtein distance

                foreach (var cmd in this.Commands.RegisteredCommands.Values.Distinct())
                {
                    if (cmd is CommandGroup cmdGroup)
                    {
                        foreach (var children in cmdGroup.Children)
                        {
                            if (Helpers.IsCommandSimilar(children, cmdName, nL))
                            {
                                suggestedCommands.Add(children);
                            }
                        }
                        if (cmdGroup.IsExecutableWithoutSubcommands && Helpers.IsCommandSimilar(cmdGroup, cmdName, nL))
                        {
                            suggestedCommands.Add(cmdGroup);
                        }
                    }
                    else
                    {
                        if (Helpers.IsCommandSimilar(cmd, cmdName, nL))
                        {
                            suggestedCommands.Add(cmd);
                        }
                    }
                }

                if (suggestedCommands.Any())
                {
                    suggestedCommands.OrderBy(x => x.QualifiedName);
                    var description = new StringBuilder();
                    description.AppendLine($"Команды с названием {Formatter.InlineCode(cmdName)} не найдено. Вот возможные варианты того, что вы имели в виду:");
                    foreach (var cmd in suggestedCommands)
                    {
                        description.AppendLine(Formatter.InlineCode(cmd.QualifiedName));
                    }

                    await e.Context.RespondAsync(embed : EmbedTemplates.ErrorEmbed()
                                                 .WithDescription(description.ToString())).ConfigureAwait(false);
                }
                break;
            }

            case InvalidOperationException invOpEx when invOpEx.Message == "No matching subcommands were found, and this group is not executable.":
            {
                //Ignore.
                break;
            }

            default:
            {
                var embed = EmbedTemplates.CommandErrorEmbed(e.Context.Member, e.Command)
                            .WithTitle("Произошла непредвиденная ошибка в работе команды")
                            .WithDescription($"Message: \n{Formatter.InlineCode(ex.Message)}\n в \n{Formatter.InlineCode(ex.Source)}");
                await e.Context.RespondAsync(embed : embed).ConfigureAwait(false);

                await this.Bot.ErrorChannel.SendMessageAsync(embed : embed).ConfigureAwait(false);

                break;
            }
            }
        }
示例#28
0
 // Removes the emoji that has been recently selected by a player or AI
 public async Task RemoveChoice(DiscordMessage embed, DiscordEmoji demoji)
 {
     await embed.DeleteReactionsEmojiAsync(demoji).ConfigureAwait(false);
 }
示例#29
0
        public async Task CreateTestLootDuel(CommandContext c)
        {
            var message = await c.RespondAsync(embed : DiscordEmbedUtils.MakeEmbed(":moneybag: Grab the Loot: Duel Mode!", "First to grab the :moneybag: gets it! Beware of the decoys, you only get one shot!"));

            var userBlacklist = new HashSet <DiscordUser>();

            var timer = new Timer();

            timer.Interval = RandomUtils.Range(1.0, 5.0) * 1000;
            timer.Start();

            var trigger = Instance.AddReactionTrigger(message, null);

            trigger.onTriggered += (user, emoji) => {
                if (emoji == EmojiUtils.moneybag && !userBlacklist.Contains(user))
                {
                    Instance.RemoveReactionTrigger(message);
                    Task.Run(async() => {
                        timer.Stop();
                        await message.DeleteAllReactionsAsync();
                        //await message.ModifyAsync( embed: DiscordEmbedUtils.MakeTextEmbed( text: $"**{user.Username}** got the loot!" ) );
                        //var task = message.DeleteAsync();
                        await c.RespondAsync(embed: DiscordEmbedUtils.MakeEmbed(text: $":moneybag: Got the loot!", author: user));
                    });
                }
                else if (userBlacklist.Add(user))
                {
                    Task.Run(async() => {
                        //await message.ModifyAsync( embed: DiscordEmbedUtils.MakeTextEmbed( text: $"**{user.Username}** got the loot!" ) );
                        //var task = message.DeleteAsync();
                        await c.RespondAsync(embed: DiscordEmbedUtils.MakeEmbed(text: $":skull_crossbones: Missed the loot!", author: user));
                    });
                }
            };

            var numIcons  = EmojiUtils.lootIcons.Length;
            var lootIcons = new DiscordEmoji[numIcons];

            for (int i = 0; i < numIcons; i++)
            {
                lootIcons[i] = EmojiUtils.lootIcons[RandomUtils.Range(0, numIcons)];
            }

            int currentIcon = 0;

            timer.Elapsed += (sender, e) => {
                if (currentIcon <= numIcons)
                {
                    if (currentIcon < numIcons)
                    {
                        message.CreateReactionAsync(lootIcons[currentIcon]);
                    }
                    currentIcon++;
                }
                else
                {
                    timer.Stop();
                    Instance.RemoveReactionTrigger(message);
                    Task.Run(async() => {
                        //await message.ModifyAsync( embed: DiscordEmbedUtils.MakeTextEmbed( text: $"You all missed the loot! Better luck next time." ) );
                        //await message.DeleteAllReactionsAsync();
                        var task = message.DeleteAsync();
                        await c.RespondAsync(embed: DiscordEmbedUtils.MakeEmbed(text: $"You all missed the loot! Better luck next time."));
                    });
                }
                timer.Interval = RandomUtils.Range(1.0, 5.0) * 1000;
            };
        }
示例#30
0
        public async Task GetDbStatus(CommandContext ctx)
        {
            await ctx.TriggerTypingAsync();

            var userId = ctx.User?.Id ?? 0;

            Log.Info($"Requesting {nameof(GetDbStatus)} by {userId}...");
            if (userId != _coder)
            {
                var emoji = DiscordEmoji.FromName(ctx.Client, ":no_entry:");
                var embed = new DiscordEmbedBuilder
                {
                    Title       = "Access denied",
                    Description = $"{emoji} You may be a *coder*, but you are not **The Coder**!",
                    Color       = DiscordColor.Red
                };

                await ctx.RespondAsync("", embed : embed);

                return;
            }

            try
            {
                var provider = new DbProvider(_connectionString);
                var s        = provider.GetDataDiagnostic();

                var sb = new StringBuilder();

                sb.AppendLine($"Scheduled Players Per Hour: {s.ScheduledPlayersPerHour:N0}");
                sb.AppendLine($"Last Hour Players: {s.AvgPlayersPerHourLastHour:N0}");
                sb.AppendLine($"Avg Players Per Hour Last 2 Hours: {s.AvgPlayersPerHourLast2Hours:N0}");
                sb.AppendLine($"Avg Players Per Hour Last 6 Hours: {s.AvgPlayersPerHourLast6Hours:N0}");
                sb.AppendLine($"Avg Players Per Hour Last Day: {s.AvgPlayersPerHourLastDay:N0}");
                sb.AppendLine();
                sb.AppendLine(
                    $"Delay on the last 48h/72h/96h: {s.Last48HDelay:N1}; {s.Last72HDelay:N1}; {s.Last96HDelay:N1}");
                sb.AppendLine($"Total Players: {s.TotalPlayers:N0}; Enabled Clans: {s.TotalEnabledClans};");
                sb.AppendLine($"Players Queue Length: {s.PlayersQueueLenght}");
                sb.AppendLine($"Membership Queue Length: {s.MembershipQueueLenght}");
                sb.AppendLine($"Calculate Queue Length: {s.CalculateQueueLenght}");

                var embed = new DiscordEmbedBuilder
                {
                    Title       = "Database Status",
                    Description = sb.ToString(),
                    Color       = DiscordColor.Goldenrod,
                    Author      = new DiscordEmbedBuilder.EmbedAuthor
                    {
                        Name = "WoTClans",
                        Url  = "https://wotclans.com.br"
                    },
                    Footer = new DiscordEmbedBuilder.EmbedFooter
                    {
                        Text = $"Retrieved at {s.Moment:yyyy-MM-dd HH:mm} UTC."
                    }
                };

                await ctx.RespondAsync("", embed : embed);

                Log.Debug($"{nameof(GetDbStatus)} returned ok.");
            }
            catch (Exception ex)
            {
                Log.Error($"{nameof(GetDbStatus)}", ex);
                await ctx.RespondAsync(
                    $"Sorry, {ctx.User?.Mention}. There was an error... the *Coder* will be notified of `{ex.Message}`.");
            }
        }