public Task SendTargetRevocationEmbedAsync(RevocablePunishment punishment, IUser target,
                                                   LocalizedLanguage language)
        {
            var typeName = punishment.GetType().Name.ToLower();
            var builder  = new LocalEmbedBuilder().WithWarnColor()
                           .WithTitle(_localization.Localize(language, $"punishment_{typeName}") +
                                      $" - {_localization.Localize(language, "punishment_case", punishment.Id)}")
                           .WithDescription(_localization.Localize(language, $"punishment_{typeName}_revoke_description", Markdown.Bold(_client.GetGuild(punishment.GuildId).Name.Sanitize())))
                           .AddField(_localization.Localize(language, "title_reason"),
                                     punishment.RevocationReason ?? _localization.Localize(language, "punishment_noreason"))
                           .WithTimestamp(punishment.RevokedAt ?? DateTimeOffset.UtcNow);

            if (punishment is Mute channelMute && channelMute.ChannelId.HasValue)
            {
                builder.AddField(_localization.Localize(language, "punishment_mute_channel"),
                                 _client.GetGuild(punishment.GuildId).GetTextChannel(channelMute.ChannelId.Value).Mention);
            }

            return(target.SendMessageAsync(embed: builder.Build()));
        }
            public async Task ChannelTopicAsync()
            {
                var channel = (CachedTextChannel)Context.Channel;

                if (string.IsNullOrEmpty(channel.Topic))
                {
                    await ReplyErrorAsync(Localization.AdministrationChannelNoTopic);

                    return;
                }

                var embed = new LocalEmbedBuilder
                {
                    Color       = RiasUtilities.ConfirmColor,
                    Title       = GetText(Localization.AdministrationChannelTopicTitle),
                    Description = channel.Topic
                };

                await ReplyAsync(embed);
            }
Beispiel #3
0
        public async Task ModulesAsync()
        {
            var embed = new LocalEmbedBuilder
            {
                Color  = RiasUtilities.ConfirmColor,
                Title  = GetText(Localization.HelpModulesListTitle),
                Footer = new LocalEmbedFooterBuilder().WithText(GetText(Localization.HelpModulesListFooter, Context.Prefix))
            };

            var isOwner = Context.User.Id == Credentials.MasterId;

            var modules = isOwner
                ? _commandService.GetAllModules()
                          .Where(m => m.Parent is null)
                          .OrderBy(m => m.Name)
                          .ToArray()
                : _commandService.GetAllModules()
                          .Where(m => m.Parent is null && m.Commands.All(c => !c.Checks.Any(x => x is OwnerOnlyAttribute)))
                          .OrderBy(m => m.Name)
                          .ToArray();

            foreach (var module in modules)
            {
                var fieldValue = "\u200B";
                if (module.Submodules.Count != 0)
                {
                    fieldValue = string.Join("\n", isOwner
                        ? module.Submodules
                                             .OrderBy(m => m.Name)
                                             .Select(x => x.Name)
                        : module.Submodules
                                             .Where(m => m.Commands.All(c => !c.Checks.Any(x => x is OwnerOnlyAttribute)))
                                             .OrderBy(m => m.Name)
                                             .Select(x => x.Name));
                }

                embed.AddField(module.Name, fieldValue, true);
            }

            await ReplyAsync(embed);
        }
Beispiel #4
0
        private LocalEmbedBuilder CreateModuleHelpEmbed(
            Module module,
            string commandNamesString,
            string commandAliasesString,
            string submoduleString)
        {
            var helpEmbedBuilder = new LocalEmbedBuilder {
                Color  = Constants.EspeonColour,
                Title  = $"{module.Name} Help",
                Author = new LocalEmbedAuthorBuilder {
                    IconUrl = Context.Member.GetAvatarUrl(),
                    Name    = Context.Member.DisplayName
                },
                ThumbnailUrl = Context.Guild.CurrentMember.GetAvatarUrl(),
                Description  = module.Description,
                Footer       = new LocalEmbedFooterBuilder {
                    Text = $"Execute \"{GetPrefix()} command\" to view help for that specific command"
                }
            };

            if (module.Parent != null)
            {
                helpEmbedBuilder.AddField("Parent Module", Markdown.Code(module.Parent.Name));
            }

            if (module.FullAliases.Count > 0)
            {
                helpEmbedBuilder.AddField("Module Aliases", string.Join(", ", module.FullAliases.Select(Markdown.Code)));
            }

            helpEmbedBuilder.AddField("Command Names", commandNamesString);
            helpEmbedBuilder.AddField("Command Aliases", commandAliasesString);

            if (submoduleString.Length > 0)
            {
                helpEmbedBuilder.AddField("Submodules", submoduleString);
            }

            return(helpEmbedBuilder);
        }
Beispiel #5
0
        public static async Task CreateRaidEmbedAsync(RestUserMessage msg, Raid raid)
        {
            var westernTimeZone = TZConvert.GetTimeZoneInfo("America/Los_Angeles");
            var localDateTime   = TimeZoneInfo.ConvertTime(raid.RaidTime, westernTimeZone);

            if (DateTimeOffset.UtcNow.CompareTo(raid.RaidTime) > 0)
            {
                if (msg.IsPinned)
                {
                    await msg.UnpinAsync();
                }
                await msg.ModifyAsync(m => m.Content = "This raid has already occurred.");

                await msg.ClearReactionsAsync();

                return;
            }

            await AddRaidEmojisAsync(msg);

            if (!msg.IsPinned)
            {
                await msg.PinAsync();
            }

            var roleCounts  = Enum.GetNames(typeof(ClassRole)).Select(r => (Role: Enum.Parse <ClassRole>(r), Count: raid.Participants.Where(rp => !rp.IsAbsent).Count(rp => rp.Character.Role == Enum.Parse <ClassRole>(r))));
            var classCounts = Enum.GetNames(typeof(WowClass)).Select(c => (Class: Enum.Parse <WowClass>(c), Count: raid.Participants.Where(rp => !rp.IsAbsent).Count(rp => rp.Character.Class == Enum.Parse <WowClass>(c))));

            var embed = new LocalEmbedBuilder()
                        .WithTitle($"{raid.RaidLocationId.Humanize().Transform(To.TitleCase)} - {localDateTime:MM/dd @ hh tt}")
                        .WithTimestamp(raid.RaidTime);

            var raiderGroups = raid.Participants.Where(rp => !rp.IsAbsent).ToArray().OrderBy(rp => rp.SignedUpAt)
                               .Select((rp, index) => (SignedUpNumber: index + 1, RaidParticipant: rp))
                               .GroupBy(signup => signup.RaidParticipant.Character.Class)
                               .Select(g => (Class: Enum.Parse <WowClass>(g.Key.ToString()), Raiders: g.OrderBy(r => r.SignedUpNumber)))
                               .ToDictionary(k => k.Class, v => v.Raiders);

            var embedLayoutDict = new Dictionary <WowClass, IOrderedEnumerable <(int, RaidParticipant)> > {
                { WowClass.Druid, null },
        public async Task Top()
        {
            var list = Data.ImposterKings.ToList();

            foreach (var queen in Data.ImposterQueens)
            {
                list.Add(queen);
            }
            var lenght = Math.Min(list.Count, 25);

            var order = list.Take(lenght).OrderByDescending(x => x.count);
            var sb    = new StringBuilder();
            var eb    = new LocalEmbedBuilder().WithTitle($"Top {lenght}");

            foreach (var(id, count) in order)
            {
                var user = Context.Guild.GetMember(id);
                sb.AppendLine($"{user.DisplayName} {(Data.WhitelistedIds.Any(x => x == user.Id) ? $"has betrayed trust: {count} times " : "user is not whitelisted as imposter")}");
            }
            eb.WithDescription(sb.ToString());
            await ReplyAsync("", eb, LocalMentions.None);
        }
Beispiel #7
0
        public async Task PingAsync(
            [Description("IP address or remote host")] string host = "8.8.8.8")
        {
            long distant = 0;

            using var ping = new Ping();

            try
            {
                distant = (await ping.SendPingAsync(host)).RoundtripTime;
            }
            catch (Exception)
            {
                host += ": timed out";
            }

            var emb = new LocalEmbedBuilder()
                      .WithColor(_configuration.DefaultEmbedColor)
                      .WithDescription($":heart:  |  {(Context.Bot.Latency.HasValue ? Math.Round(Context.Bot.Latency.Value.TotalMilliseconds, 2) : -42)}ms " +
                                       $"\n:earth_americas:  |  {distant}ms ({host})")
                      .WithTitle("Current latency : (websocket, host, messages)");

            var sw      = Stopwatch.StartNew();
            var message = await RespondAsync(emb.Build()).ConfigureAwait(false);

            sw.Stop();

            emb.Description += $"\n:e_mail:  |  {sw.ElapsedMilliseconds}ms";

            for (var i = 0; i < 5; i++)
            {
                sw.Restart();
                await message.ModifyAsync(x => x.Embed = emb.Build()).ConfigureAwait(false);

                sw.Stop();

                emb.Description += $", {sw.ElapsedMilliseconds}ms";
            }
        }
Beispiel #8
0
        public async Task HandleAsync(MessageUpdatedEventArgs args)
        {
            if (!(args.Channel is CachedTextChannel channel) ||
                !args.OldMessage.HasValue ||                                                            // TODO: What to do when message doesn't have value, other than ignore
                args.OldMessage.Value.Content?.Equals(args.NewMessage.Content ?? string.Empty) == true) // message content is identical
            {
                return;
            }

            using var ctx = new AdminDatabaseContext(_provider);
            var guild = await ctx.GetOrCreateGuildAsync(channel.Guild.Id);

            if (!(await ctx.GetLoggingChannelAsync(channel.Guild.Id, LogType.MessageUpdate) is { } logChannel))
            {
                return;
            }

            var builder = new LocalEmbedBuilder()
                          .WithErrorColor()
                          .WithTitle(_localization.Localize(guild.Language, "logging_message_update", channel.Tag))
                          .WithDescription(args.NewMessage.Author.Format(false))
                          .AddField(_localization.Localize(guild.Language, "info_id"), args.NewMessage.Id)
                          .WithTimestamp(DateTimeOffset.UtcNow);

            if (!string.IsNullOrWhiteSpace(args.OldMessage.Value.Content))
            {
                builder.AddField(_localization.Localize(guild.Language, "logging_message_update_oldcontent"),
                                 args.OldMessage.Value.Content.TrimTo(1024, true));
            }

            if (!string.IsNullOrWhiteSpace(args.NewMessage.Content))
            {
                builder.AddField(_localization.Localize(guild.Language, "logging_message_update_newcontent"),
                                 args.NewMessage.Content.TrimTo(1024, true));
            }

            await logChannel.SendMessageAsync(embed : builder.Build());
        }
Beispiel #9
0
        private async Task PostHentaiAsync(NsfwService.NsfwImageApiProvider provider, string?tags = null)
        {
            if (!((CachedTextChannel)Context.Channel).IsNsfw)
            {
                await ReplyErrorAsync(Localization.NsfwChannelNotNsfw);

                return;
            }

            if (!Service.CacheInitialized)
            {
                await ReplyErrorAsync(Localization.NsfwCacheNotInitialized);

                return;
            }

            var nsfwImage = await Service.GetNsfwImageAsync(provider, tags);

            if (nsfwImage is null)
            {
                await ReplyErrorAsync(Localization.NsfwNoHentai);

                return;
            }

            var embed = new LocalEmbedBuilder
            {
                Color  = RiasUtilities.ConfirmColor,
                Author = new LocalEmbedAuthorBuilder
                {
                    Name = $"{GetText(Localization.SearchesSource)}: {nsfwImage.Provider}",
                    Url  = nsfwImage.Url
                },
                ImageUrl = nsfwImage.Url
            };

            await ReplyAsync(embed);
        }
Beispiel #10
0
        public async Task XpLeaderboardAsync(int page = 1)
        {
            page--;
            if (page < 0)
            {
                page = 0;
            }

            var xpLeaderboard = (await DbContext.GetOrderedListAsync <GuildUsersEntity, int>(x => x.GuildId == Context.Guild !.Id, y => y.Xp, true))
                                .Where(x => Context.Guild !.GetMember(x.UserId) != null)
                                .Skip(page * 15)
                                .Take(15)
                                .ToList();

            if (xpLeaderboard.Count == 0)
            {
                await ReplyErrorAsync(Localization.XpGuildLeaderboardEmpty);

                return;
            }

            var embed = new LocalEmbedBuilder
            {
                Color = RiasUtilities.ConfirmColor,
                Title = GetText(Localization.XpGuildLeaderboard)
            };

            var index = page * 15;

            foreach (var userDb in xpLeaderboard)
            {
                embed.AddField($"{++index}. {Context.Guild!.GetMember(userDb.UserId)}",
                               $"{GetText(Localization.XpLevelX, RiasUtilities.XpToLevel(userDb.Xp, XpService.XpThreshold))} | {GetText(Localization.XpXp)} {userDb.Xp}",
                               true);
            }

            await ReplyAsync(embed);
        }
        public async Task SendLoggingRevocationEmbedAsync(RevocablePunishment punishment, IUser target, IUser moderator,
                                                          CachedTextChannel logChannel, LocalizedLanguage language)
        {
            var typeName = punishment.GetType().Name.ToLower();
            var builder  = new LocalEmbedBuilder().WithWarnColor()
                           .WithTitle(_localization.Localize(language, $"punishment_{typeName}") +
                                      $" - {_localization.Localize(language, "punishment_case", punishment.Id)}")
                           .WithDescription(_localization.Localize(language, $"punishment_{typeName}_revoke_description_guild",
                                                                   $"**{target}** (`{target.Id}`)"))
                           .AddField(_localization.Localize(language, "title_reason"),
                                     punishment.RevocationReason ?? _localization.Localize(language, "punishment_noreason"))
                           .WithFooter(_localization.Localize(language, "punishment_moderator", moderator.Tag),
                                       moderator.GetAvatarUrl())
                           .WithTimestamp(punishment.RevokedAt ?? DateTimeOffset.UtcNow);

            if (punishment is Mute channelMute && channelMute.ChannelId.HasValue)
            {
                builder.AddField(_localization.Localize(language, "punishment_mute_channel"),
                                 _client.GetGuild(punishment.GuildId).GetTextChannel(channelMute.ChannelId.Value)?.Mention ?? "???");
            }

            await logChannel.SendMessageAsync(embed : builder.Build());
        }
Beispiel #12
0
        public async Task LeaveGuildAsync(string name)
        {
            var guild = Snowflake.TryParse(name, out var guildId)
                ? RiasBot.GetGuild(guildId)
                : RiasBot.Guilds.FirstOrDefault(x => string.Equals(x.Value.Name, name)).Value;

            if (guild is null)
            {
                await ReplyErrorAsync(Localization.BotGuildNotFound);

                return;
            }

            var embed = new LocalEmbedBuilder()
            {
                Color       = RiasUtilities.ConfirmColor,
                Description = GetText(Localization.BotLeftGuild, guild.Name)
            }.AddField(GetText(Localization.CommonId), guild.Id, true).AddField(GetText(Localization.CommonUsers), guild.MemberCount, true);

            await ReplyAsync(embed);

            await guild.LeaveAsync();
        }
        public AdminCommandResult GetChannelInfo([Remainder] CachedGuildChannel channel = null)
        {
            channel ??= (CachedTextChannel)Context.Channel;

            var builder = new LocalEmbedBuilder()
                          .WithSuccessColor()
                          .AddField(Localize("info_id"), channel.Id)
                          .AddField(Localize("info_created"), string.Join('\n', channel.Id.CreatedAt.ToString("g", Context.Language.Culture),
                                                                          (DateTimeOffset.UtcNow - channel.Id.CreatedAt).HumanizeFormatted(Localization, Context.Language, TimeUnit.Minute, true)));

            builder = channel switch
            {
                CachedTextChannel textChannel => builder
                .WithTitle(Localize(textChannel.IsNews
                        ? "channel_info_news"
                        : "channel_info_text", textChannel))
                .WithDescription(Markdown.Italics(textChannel.Topic))
                .AddField(Localize("info_mention"), textChannel.Mention)
                .AddField(Localize("channel_info_slowmode"),
                          textChannel.Slowmode == 0
                            ? Localize("info_none")
                            : TimeSpan.FromSeconds(textChannel.Slowmode).HumanizeFormatted(Localization, Context.Language, TimeUnit.Second))
                .WithFooter(textChannel.Category is { }
Beispiel #14
0
        public static async Task HandleMessageEditedAsync(VerificationBot bot, MessageUpdatedEventArgs e)
        {
            // Sometimes fires for messages that haven't been edited
            // Unsure if this is a bug, or some other form of message update
            if (e.GuildId == null || e.OldMessage == null ||
                e?.OldMessage?.Content == e?.NewMessage?.Content)
            {
                return;
            }

            LocalEmbedBuilder embed = null;

            foreach (ConfigChannel channel in bot.Config
                     .GetOrAddGuild(e.GuildId.Value).Channels.Values
                     .Where(c => c.ChangelogChannels.Contains(e.ChannelId)))
            {
                if (embed == null)
                {
                    embed = new LocalEmbedBuilder()
                            .WithTitle("Message edited")
                            .AddField("Channel", $"<#{e.OldMessage.ChannelId}>")
                            .AddField("Author", e.OldMessage.Author.Mention)
                            .AddField("Old Content", e.OldMessage.Content.Length > 0 ? e.OldMessage.Content : "N/A")
                            .AddField("Link", $"https://discord.com/channels/{e.GuildId.Value.RawValue}/{e.ChannelId.RawValue}/{e.MessageId.RawValue}");
                }

                if (await bot.GetChannelAsync(channel.GuildId, channel.Id) is ITextChannel textChannel)
                {
                    await textChannel.SendMessageAsync
                    (
                        new LocalMessageBuilder()
                        .WithEmbed(embed)
                        .Build()
                    );
                }
            }
        }
Beispiel #15
0
        public async Task GlobalXpLeaderboardAsync(int page = 1)
        {
            page--;
            if (page < 0)
            {
                page = 0;
            }

            var xpLeaderboard = await DbContext.GetOrderedListAsync <UsersEntity, int>(x => x.Xp, true, (page * 15)..((page + 1) * 15));

            if (xpLeaderboard.Count == 0)
            {
                await ReplyErrorAsync(Localization.XpLeaderboardEmpty);

                return;
            }

            var embed = new LocalEmbedBuilder
            {
                Color = RiasUtilities.ConfirmColor,
                Title = GetText(Localization.XpLeaderboard)
            };

            var index = page * 15;

            foreach (var userDb in xpLeaderboard)
            {
                var user = (IUser)RiasBot.GetUser(userDb.UserId) ?? await RiasBot.GetUserAsync(userDb.UserId);

                embed.AddField($"{++index}. {user}",
                               $"{GetText(Localization.XpLevelX, RiasUtilities.XpToLevel(userDb.Xp, XpService.XpThreshold))} | {GetText(Localization.XpXp)} {userDb.Xp}",
                               true);
            }

            await ReplyAsync(embed);
        }
        public async Task TopB()
        {
            var klenght     = Math.Min(Data.ImposterKings.Count, 25);
            var qlenght     = Math.Min(Data.ImposterQueens.Count, 25);
            var kingorder   = Data.ImposterKings.Take(klenght).OrderByDescending(x => x.count);
            var queensorder = Data.ImposterQueens.Take(qlenght).OrderByDescending(x => x.count);
            var eb          = new LocalEmbedBuilder();
            var sb          = new StringBuilder();

            foreach (var(id, count) in kingorder)
            {
                var user = Context.Guild.GetMember(id);
                sb.AppendLine($"{user.DisplayName}  {(Data.WhitelistedIds.Any(x => x == user.Id) ? $"has betrayed trust: {count} times " : "user is not whitelisted as imposter")}");
            }
            eb.AddField("Top Kings", sb.ToString(), true);
            sb.Clear();
            foreach (var(id, count) in queensorder)
            {
                var user = Context.Guild.GetMember(id);
                sb.AppendLine($"{user.DisplayName}  {(Data.WhitelistedIds.Any(x => x == user.Id) ? $"has betrayed trust: {count} times " : "user is not whitelisted as imposter")}");
            }
            eb.AddField("Top Queens", sb.ToString(), true);
            await ReplyAsync("", eb, LocalMentions.None);
        }
 public static LocalEmbedBuilder AddInlineField(this LocalEmbedBuilder eb, Action <LocalEmbedFieldBuilder> action)
 => eb.AddField(action);
Beispiel #18
0
        protected override async Task <IUserMessage> InitialiseAsync()
        {
            var tempDict = new Dictionary <string, (Module Module, LocalEmbedBuilder Embed, string Title)>();

            foreach (var module in CommandService.GetAllModules())
            {
                if (module.Attributes
                    .FirstOrDefault(x => x.GetType()
                                    .Equals(typeof(HelpMetadataAttribute))) is HelpMetadataAttribute attMatch)
                {
                    var title = $"{attMatch.ButtonCode} {module.Name}";
                    if (!tempDict.TryAdd(
                            attMatch.ButtonCode,
                            (module, HelpService.GetModuleHelp(module).WithColor(attMatch.Color),
                             title)))
                    {
                        // TODO: warn about module being ignored due to duplicate button.
                    }
                }
            }

            var footerTitles = new List <string>
            {
                $"{HelpPageEmote} Help"
            };

            footerTitles.AddRange(tempDict.Values.Select(x => x.Title));
            var footerContent = string.Join(", ", footerTitles);
            var homeBuilder   = new LocalEmbedBuilder()
                                .WithTitle("Modules")
                                .WithColor(Color.Aqua)
                                .WithFooter(footerContent);

            foreach (var dPage in tempDict)
            {
                if (dPage.Value.Module.Commands.Count == 0)
                {
                    homeBuilder.AddField(new LocalEmbedFieldBuilder
                    {
                        Name  = dPage.Value.Title,
                        Value = "No Commands."
                    });
                }
                else
                {
                    homeBuilder.AddField(new LocalEmbedFieldBuilder
                    {
                        Name  = dPage.Value.Title,
                        Value = string.Join(", ", dPage.Value.Module.Commands.Select(c => '`' + c.Name + '`').Distinct())
                    });

                    pages.Add(dPage.Key, dPage.Value.Embed.WithFooter(footerContent).Build());
                }
            }

            homePage = homeBuilder.Build();

            var message = await Channel.SendMessageAsync("", false, homePage);

            await AddButtonAsync(new Button(new LocalEmoji(HelpPageEmote), x =>
            {
                return(Message.ModifyAsync(m => m.Embed = homePage));
            }));

            foreach (var page in pages)
            {
                await AddButtonAsync(new Button(new LocalEmoji(page.Key), x =>
                {
                    return(Message.ModifyAsync(m => m.Embed = page.Value));
                }));
            }

            return(message);
        }
        private async Task SendTargetEmbedAsync(Punishment punishment, IUser target, Punishment additionalPunishment, LocalizedLanguage language)
        {
            var typeName = punishment.GetType().Name.ToLower();
            var builder  = new LocalEmbedBuilder().WithErrorColor()
                           .WithTitle(_localization.Localize(language, $"punishment_{typeName}") +
                                      $" - {_localization.Localize(language, "punishment_case", punishment.Id)}")
                           .AddField(_localization.Localize(language, "title_reason"),
                                     punishment.Reason ?? _localization.Localize(language, "punishment_noreason"))
                           .WithTimestamp(punishment.CreatedAt);

            if (!(additionalPunishment is null))
            {
                builder.AddField(FormatAdditionalPunishment(additionalPunishment, language));
            }

            if (punishment is Warning)
            {
                using var ctx = new AdminDatabaseContext(_provider);

                var warningCount = await ctx.Punishments.OfType <Warning>().CountAsync(x =>
                                                                                       x.TargetId == target.Id && x.GuildId == punishment.GuildId && !x.RevokedAt.HasValue);

                builder.WithDescription(_localization.Localize(language, "punishment_warning_description",
                                                               Markdown.Bold(_client.GetGuild(punishment.GuildId).Name.Sanitize()),
                                                               Markdown.Bold(warningCount.ToOrdinalWords(language.Culture))));
            }
            else
            {
                builder.WithDescription(_localization.Localize(language, $"punishment_{typeName}_description",
                                                               _client.GetGuild(punishment.GuildId).Name));
            }

            if (punishment is RevocablePunishment revocable)
            {
                var field = new LocalEmbedFieldBuilder()
                            .WithName(_localization.Localize(language, "punishment_appeal"));

                switch (revocable)
                {
                case Ban ban:
                    field.WithValue(!ban.Duration.HasValue || ban.Duration.Value > TimeSpan.FromDays(1)
                            ? GetAppealInstructions()
                            : _localization.Localize(language, "punishment_tooshort",
                                                     ban.Duration.Value.Humanize(minUnit: TimeUnit.Minute, culture: language.Culture)));
                    break;

                case Mute mute:
                    field.WithValue(!mute.Duration.HasValue || mute.Duration.Value > TimeSpan.FromDays(1)
                            ? GetAppealInstructions()
                            : _localization.Localize(language, "punishment_tooshort",
                                                     mute.Duration.Value.Humanize(minUnit: TimeUnit.Minute, culture: language.Culture)));
                    break;

                default:
                    field = null;
                    break;
                }

                if (!(field is null))
                {
                    builder.AddField(field);
                }

                string GetAppealInstructions()
                {
                    return(_localization.Localize(language, "punishment_appeal_instructions",
                                                  Markdown.Code(punishment.Id.ToString()),
                                                  Markdown.Code($"{_config.DefaultPrefix}appeal {punishment.Id} [{_localization.Localize(language, "title_reason").ToLower()}]")));
                }
            }

            if (punishment is Mute channelMute && channelMute.ChannelId.HasValue)
            {
                builder.AddField(_localization.Localize(language, "punishment_mute_channel"),
                                 _client.GetGuild(punishment.GuildId).GetTextChannel(channelMute.ChannelId.Value).Mention);
            }

            if (punishment.Format != ImageFormat.Default)
            {
                builder.WithImageUrl($"attachment://attachment.{punishment.Format.ToString().ToLower()}");
                _ = target.SendMessageAsync(new LocalAttachment(punishment.Image,
                                                                $"attachment.{punishment.Format.ToString().ToLower()}"), embed: builder.Build());

                return;
            }

            _ = target.SendMessageAsync(embed: builder.Build());
        }
        private async Task <IUserMessage> SendLoggingEmbedAsync(Punishment punishment, IUser target, IUser moderator, Punishment additionalPunishment, CachedTextChannel logChannel, LocalizedLanguage language)
        {
            var typeName = punishment.GetType().Name.ToLower();
            var builder  = new LocalEmbedBuilder()
                           .WithErrorColor()
                           .WithTitle(_localization.Localize(language, $"punishment_{typeName}") +
                                      $" - {_localization.Localize(language, "punishment_case", punishment.Id)}")
                           .AddField(_localization.Localize(language, "title_reason"),
                                     punishment.Reason ?? _localization.Localize(language, "punishment_needsreason",
                                                                                 Markdown.Code(
                                                                                     $"{_config.DefaultPrefix}reason {punishment.Id} [{_localization.Localize(language, "title_reason").ToLower()}]")))
                           .WithFooter(_localization.Localize(language, "punishment_moderator", moderator.Tag),
                                       moderator.GetAvatarUrl())
                           .WithTimestamp(punishment.CreatedAt);

            builder = punishment switch
            {
                Ban ban => builder.AddField(
                    _localization.Localize(language, "punishment_duration"), ban.Duration.HasValue
                        ? ban.Duration.Value.Humanize(minUnit: TimeUnit.Second, culture: language.Culture)
                        : _localization.Localize(language, "punishment_permanent")),
                Mute mute => builder.AddField(
                    _localization.Localize(language, "punishment_duration"), mute.Duration.HasValue
                        ? mute.Duration.Value.Humanize(minUnit: TimeUnit.Second, culture: language.Culture)
                        : _localization.Localize(language, "punishment_permanent")),
                _ => builder
            };

            if (punishment is Mute channelMute && channelMute.ChannelId.HasValue)
            {
                builder.AddField(_localization.Localize(language, "punishment_mute_channel"),
                                 _client.GetGuild(punishment.GuildId).GetTextChannel(channelMute.ChannelId.Value).Mention);
            }

            if (punishment is Warning)
            {
                using var ctx = new AdminDatabaseContext(_provider);

                var warningCount = await ctx.Punishments.OfType <Warning>().CountAsync(x =>
                                                                                       x.TargetId == target.Id && x.GuildId == punishment.GuildId && !x.RevokedAt.HasValue);

                builder.WithDescription(_localization.Localize(language, "punishment_warning_description_guild", $"**{target}** (`{target.Id}`)",
                                                               Markdown.Bold(warningCount.ToOrdinalWords(language.Culture))));

                if (!(additionalPunishment is null))
                {
                    builder.AddField(FormatAdditionalPunishment(additionalPunishment, language));
                }
            }
            else
            {
                builder.WithDescription(_localization.Localize(language, $"punishment_{typeName}_description_guild",
                                                               $"**{target}** (`{target.Id}`)"));
            }

            if (punishment.Format != ImageFormat.Default)
            {
                // TODO: Copying stream - is it necessary?
                var image = new MemoryStream(punishment.Image.ToArray());
                builder.WithImageUrl($"attachment://attachment.{punishment.Format.ToString().ToLower()}");
                return(await logChannel.SendMessageAsync(new LocalAttachment(image,
                                                                             $"attachment.{punishment.Format.ToString().ToLower()}"), embed : builder.Build()));
            }

            return(await logChannel.SendMessageAsync(embed : builder.Build()));
        }
 public static LocalEmbedBuilder WithDefaultColor(this LocalEmbedBuilder eb)
 => eb.WithColor(Global.DefaultEmbedColor);
 public static LocalEmbedBuilder AddInlineCodeBlockField(this LocalEmbedBuilder eb, string name, object value)
 => eb.AddField(name, Markdown.CodeBlock("csharp", value.ToString()), true);
        public static bool TryParseEmbed(string json, out LocalEmbedBuilder embed)
        {
            embed = new LocalEmbedBuilder();
            try
            {
                var embedDeserialized = JsonConvert.DeserializeObject <JsonEmbed>(json);

                var author      = embedDeserialized.Author;
                var title       = embedDeserialized.Title;
                var description = embedDeserialized.Description;

                var colorString = embedDeserialized.Color;
                var thumbnail   = embedDeserialized.Thumbnail;
                var image       = embedDeserialized.Image;
                var fields      = embedDeserialized.Fields;
                var footer      = embedDeserialized.Footer;
                var timestamp   = embedDeserialized.Timestamp;

                if (author != null)
                {
                    embed.WithAuthor(author);
                }

                if (!string.IsNullOrEmpty(title))
                {
                    embed.WithTitle(title);
                }

                if (!string.IsNullOrEmpty(description))
                {
                    embed.WithDescription(description);
                }

                if (!string.IsNullOrEmpty(colorString))
                {
                    embed.WithColor(HexToInt(colorString) ?? 0xFFFFFF);
                }

                if (!string.IsNullOrEmpty(thumbnail))
                {
                    embed.WithThumbnailUrl(thumbnail);
                }
                if (!string.IsNullOrEmpty(image))
                {
                    embed.WithImageUrl(image);
                }

                if (fields != null)
                {
                    foreach (var field in fields)
                    {
                        var fieldName   = field.Name;
                        var fieldValue  = field.Value;
                        var fieldInline = field.IsInline;

                        if (!string.IsNullOrEmpty(fieldName) && !string.IsNullOrEmpty(fieldValue))
                        {
                            embed.AddField(fieldName, fieldValue, fieldInline);
                        }
                    }
                }

                if (footer != null)
                {
                    embed.WithFooter(footer);
                }

                if (timestamp.HasValue)
                {
                    embed.WithTimestamp(timestamp.Value);
                }
                else if (embedDeserialized.WithCurrentTimestamp)
                {
                    embed.WithCurrentTimestamp();
                }

                return(true);
            }
            catch
            {
                return(false);
            }
        }
 public static LocalEmbedBuilder AddInlineField(this LocalEmbedBuilder eb, LocalEmbedFieldBuilder efb)
 => eb.AddField(efb);
 public static LocalEmbedBuilder AddInlineField(this LocalEmbedBuilder eb, string name, object value)
 => eb.AddField(name, value, true);
        public async ValueTask <AdminCommandResult> ShowModmailThreadAsync(int id, [MustBe(Operator.GreaterThan, 0)] int page = 1)
        {
            var modmail = await Context.Database.Modmails.Include(x => x.Messages).FirstOrDefaultAsync(x => x.Id == id);

            if (modmail is null)
            {
                return(CommandErrorLocalized("modmail_notfound"));
            }

            if (Context.IsPrivate && modmail.UserId != Context.User.Id)
            {
                return(CommandErrorLocalized("modmail_notfound"));
            }

            if (!Context.IsPrivate && modmail.GuildId != Context.Guild.Id)
            {
                return(CommandErrorLocalized("modmail_notfound"));
            }

            var split = modmail.Messages.OrderBy(x => x.Timestamp)
                        .ToList().SplitBy(10);

            page = Math.Min(page, split.Count) - 1;

            var guild = Context.IsPrivate ? Context.Client.GetGuild(modmail.GuildId) : Context.Guild;
            var user  = await Context.Client.GetOrDownloadUserAsync(modmail.UserId);

            var sb         = new StringBuilder();
            var lastTarget = ModmailTarget.User;
            var pages      = new List <Page>();
            var counter    = 0;

            foreach (var group in split)
            {
                var builder = new LocalEmbedBuilder()
                              .WithSuccessColor()
                              .WithTitle(Context.Localize("modmail_message_title", modmail.Id));

                if (split.Count > 1)
                {
                    builder.WithFooter($"{++counter}/{split.Count}");
                }

                for (var i = 0; i < group.Count; i++)
                {
                    var message = group[i];

                    if (message.Target != lastTarget && i > 0)
                    {
                        if (Context.IsPrivate)
                        {
                            builder.AddField(lastTarget == ModmailTarget.User
                                    ? Context.User.Name.Sanitize()
                                    : Context.Localize("modmail_modteam", guild.Name.Sanitize()),
                                             sb.ToString().TrimTo(256, true));
                        }
                        else
                        {
                            builder.AddField(lastTarget == ModmailTarget.User
                                    ? modmail.IsAnonymous ? Context.Localize("modmail_anonymous") : user.Name.Sanitize()
                                    : Context.Localize("modmail_modteam", guild.Name.Sanitize()),
                                             sb.ToString().TrimTo(256, true));
                        }

                        sb.Clear();
                        i--;
                    }
                    else
                    {
                        sb.AppendNewline(message.Text);
                    }

                    lastTarget = message.Target;

                    if (i == group.Count - 1)
                    {
                        if (Context.IsPrivate)
                        {
                            builder.AddField(lastTarget == ModmailTarget.User
                                    ? Context.User.Name.Sanitize()
                                    : Context.Localize("modmail_modteam", guild.Name.Sanitize()),
                                             sb.ToString().TrimTo(256, true));
                        }
                        else
                        {
                            builder.AddField(lastTarget == ModmailTarget.User
                                    ? modmail.IsAnonymous ? Context.Localize("modmail_anonymous") : user.Name.Sanitize()
                                    : Context.Localize("modmail_modteam", guild.Name.Sanitize()),
                                             sb.ToString().TrimTo(256, true));
                        }
                    }
                }

                pages.Add(builder.Build());
            }

            if (split.Count > 1)
            {
                await Pagination.SendPaginatorAsync(Context.Channel, new DefaultPaginator(pages, page), pages[page]);

                return(CommandSuccess());
            }

            return(CommandSuccess(embed: pages[0].Embed));
        }
 public static LocalEmbedBuilder WithCurrentTimestamp(this LocalEmbedBuilder embedBuilder)
 => embedBuilder.WithTimestamp(DateTimeOffset.UtcNow);
 public static LocalEmbedBuilder AddInlineBlankField(this LocalEmbedBuilder eb)
 => eb.AddBlankField(true);
        public async ValueTask <AdminCommandResult> GetBackpackProfileAsync([Remainder] BackpackUser user)
        {
            var now     = DateTimeOffset.UtcNow;
            var builder = new LocalEmbedBuilder()
                          .WithSuccessColor()
                          .WithTitle(Localize("backpack_info_title", user.Name))
                          .WithThumbnailUrl(user.AvatarUrl.ToString())
                          .AddField(Localize("info_id"), user.Id)
                          .AddField(Localize("backpack_info_lastonline"),
                                    string.Join('\n', user.LastOnline.ToString("g", Context.Language.Culture),
                                                (now - user.LastOnline).HumanizeFormatted(Localization, Context.Language, TimeUnit.Second,
                                                                                          true)))
                          .AddField(Localize("backpack_info_flags"),
                                    user.Flags == BackpackUserFlags.None
                        ? Localize("info_none")
                        : user.Flags.Humanize(LetterCasing.Title));

            if (user.AmountDonated != default)
            {
                builder.AddField(Localize("backpack_info_donated"), $"${user.AmountDonated:F} USD");
            }

            if (user.PremiumMonthsGifted != default)
            {
                builder.AddField(Localize("backpack_info_premiumgifts"), user.PremiumMonthsGifted);
            }

            if (user.Trust.Negative != default || user.Trust.Positive != default)
            {
                var netTrust = user.Trust.Positive - user.Trust.Negative;

                builder.AddField(Localize("backpack_info_trust"),
                                 $"{(netTrust > 0 ? "+" : string.Empty)}{netTrust} (+{user.Trust.Positive}/-{user.Trust.Negative})");
            }

            var currencies = await BackpackClient.GetCurrenciesAsync();

            var inventoryValue = user.Inventory.Keys * currencies.CrateKey.Price.Value + user.Inventory.Metal +
                                 user.Inventory.Value;

            builder.AddField(Localize("backpack_info_worth"),
                             Localize("backpack_info_worth_text", (inventoryValue / currencies.CrateKey.Price.Value).ToString("F"),
                                      inventoryValue.ToString("F"),
                                      (inventoryValue * currencies.RefinedMetal.Price.Value).ToString("F")));


            if (!user.SiteBans.IsDefaultOrEmpty ||
                user.Flags.HasFlag(BackpackUserFlags.SteamCommunityBanned) ||
                user.Flags.HasFlag(BackpackUserFlags.SteamRepCaution) ||
                user.Flags.HasFlag(BackpackUserFlags.SteamRepScammer) ||
                user.Flags.HasFlag(BackpackUserFlags.SteamVACBanned) ||
                user.Flags.HasFlag(BackpackUserFlags.SteamEconomyBanned) ||
                user.Flags.HasFlag(BackpackUserFlags.ValveGameBanned))
            {
                builder.WithErrorColor()
                .WithFooter(Localize("backpack_info_caution",
                                     Markdown.Code($"{Context.Prefix}backpack bans <user>")));
            }


            return(CommandSuccess(embed: builder.Build()));
        }
 public static LocalEmbedBuilder AddCodeBlockField(this LocalEmbedBuilder eb, string name, string value)
 => eb.AddField(name, Markdown.CodeBlock("csharp", value));