Пример #1
0
        public async Task ListCharactersAsync()
        {
            var characters = DbContext.User.Characters;

            var embed = new LocalEmbedBuilder()
                        .WithTitle($"{Context.Member.DisplayName}'s characters:");

            if (!characters.Any())
            {
                embed.WithDescription("You have no characters registered. You may do with `!character add NameOfYourToon ClassName Role (Melee|Ranged|Tank|Healer)`");
                await ReplyAsync(embed : embed.Build());

                return;
            }

            var sb = new StringBuilder();

            foreach (var character in characters)
            {
                sb.AppendLine($"{character.CharacterName} | {character.Class} | {character.Role}");
            }

            embed.WithDescription(sb.ToString());
            await ReplyAsync(embed : embed.Build());
        }
Пример #2
0
        public async Task ListCharactersAsync(CachedMember user)
        {
            var characters = DbContext.Database.Users.FirstOrDefault(u => u.Id == user.Id)?.Characters;

            var embed = new LocalEmbedBuilder()
                        .WithTitle($"{user.DisplayName}'s characters:");

            if (characters is null || !characters.Any())
            {
                embed.WithDescription($"They have no characters.");
                await ReplyAsync(embed : embed.Build());

                return;
            }

            var sb = new StringBuilder();

            foreach (var character in characters)
            {
                sb.AppendLine($"{character.CharacterName} | {character.Class} | {character.Role}");
            }

            embed.WithDescription(sb.ToString());
            await ReplyAsync(embed : embed.Build());
        }
Пример #3
0
        public async Task HelpAsync()
        {
            var modules = await Task.WhenAll(_commands.GetAllModules().Where(x => !x.Attributes.Any(y => y is HiddenAttribute) && x.Parent is null && x.Aliases.Count > 0).Select(async x =>
            {
                var result = await x.RunChecksAsync(Context);
                return(result.IsSuccessful ? x : null);
            }).Where(x => x != null));

            var commands = (await Task.WhenAll(_commands.GetAllCommands().Where(x => !x.Attributes.Any(y => y is HiddenAttribute) && x.Module.Aliases.Count == 0).Select(async x =>
            {
                var result = await x.RunChecksAsync(Context);
                return(result.IsSuccessful ? x : null);
            }))).Where(x => x != null && x.Module.Parent is null).DistinctBy(x => x.Name).ToArray();

            var embed = new LocalEmbedBuilder
            {
                Title       = "Help",
                Description = "This embed contains a list of every available modules. If you want to see every command of a module, use `!help <module>`.",
                Footer      = new LocalEmbedFooterBuilder
                {
                    Text = $"{modules.Length} modules and {commands.Length} commands available in this context."
                }
            };

            embed.AddField("Modules", string.Join(", ", modules.Select(x => $"`{x.Name}`")));
            embed.AddField("Commands", string.Join(", ", commands.Select(x => $"`{x.Name}`")));

            await ReplyAsync(embed : embed.Build());
        }
Пример #4
0
        public async Task EvalAsync([Remainder] string rawCode)
        {
            var code            = CommandHelper.GetCode(rawCode);
            var sw              = Stopwatch.StartNew();
            var script          = CSharpScript.Create(code, CommandHelper.RoslynScriptOptions, typeof(RoslynCommandContext));
            var diagnostics     = script.Compile();
            var compilationTime = sw.ElapsedMilliseconds;

            if (diagnostics.Any(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error))
            {
                var builder = new LocalEmbedBuilder {
                    Title       = "Compilation Failure",
                    Color       = Color.Red,
                    Description = $"Compilation took {compilationTime}ms but failed due to..."
                };
                foreach (var diagnostic in diagnostics)
                {
                    var message = diagnostic.GetMessage();
                    builder.AddField(diagnostic.Id,
                                     message.Substring(0, Math.Min(500, message.Length)));
                }

                await ReplyAsync(embed : builder.Build());

                return;
            }

            var context = new RoslynCommandContext(Context);
            var result  = await script.RunAsync(context);

            sw.Stop();
            await ReplyAsync(result.ReturnValue.ToString());
        }
Пример #5
0
        public async Task MasteriesAsync(Region region, [Remainder] string summonerName)
        {
            summonerName ??= DbContext.User.LeagueProfile.Username;

            if (string.IsNullOrWhiteSpace(summonerName))
            {
                await RespondEmbedAsync("You need to specify a nickname or set yours up.");

                return;
            }

            var summoner = await _riot.Summoner.GetSummonerByNameAsync(region, summonerName);

            if (summoner is null)
            {
                await RespondEmbedAsync("Unknown summoner. Try another region.");

                return;
            }

            var versions = await _staticEndpoints.Versions.GetAllAsync();

            var champions = await _staticEndpoints.Champions.GetAllAsync(versions.First());

            var masteries = await _riot.ChampionMastery.GetChampionMasteriesAsync(region, summoner.Id);

            var maxPage     = masteries.Count;
            var currentPage = 1;
            var pages       = new List <Page>();

            foreach (var mastery in masteries)
            {
                var page = new Page {
                    Identifier = champions.Keys[(int)mastery.ChampionId]
                };

                var embed = new LocalEmbedBuilder
                {
                    Color        = Color.Goldenrod,
                    Description  = $"Mastery for champion {page.Identifier}",
                    ThumbnailUrl =
                        $"http://ddragon.leagueoflegends.com/cdn/{versions.First()}/img/champion/{page.Identifier}.png"
                };
                embed.WithFooter($"{summonerName} | Paginator - Page {currentPage}/{maxPage}");

                embed.AddField("Level", mastery.ChampionLevel, true);
                embed.AddField("Points", mastery.ChampionPoints.ToString("N0"), true);
                embed.AddField("Chest", $"{(!mastery.ChestGranted ? "Not" : "")} granted", true);
                embed.AddField("Last play time", mastery.LastPlayTime.ToString("G"), true);

                page.Embed = embed.Build();

                currentPage++;

                pages.Add(page);
            }

            await PaginateAsync(pages.ToImmutableArray());
        }
Пример #6
0
        public async Task HandleAsync(MessageDeletedEventArgs args)
        {
            if (!(args.Channel is CachedTextChannel channel) ||
                !args.Message.HasValue || args.Message.Value.Author.IsBot) // TODO: What to do when message doesn't have value, other than ignore
            {
                return;
            }

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

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

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

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

            if (channel.Guild.CurrentMember.Permissions.ViewAuditLog)
            {
                await Task.Delay(TimeSpan.FromSeconds(1));

                var logs = await channel.Guild.GetAuditLogsAsync <RestMessagesDeletedAuditLog>(10);

                if (logs.FirstOrDefault(x =>
                                        x.TargetId == args.Message.Value.Author.Id && x.ChannelId == args.Channel.Id) is { } log)
                {
                    var moderator = await args.Client.GetOrDownloadUserAsync(log.ResponsibleUserId);

                    builder.WithTitle(_localization.Localize(guild.Language, "logging_message_delete_moderator", moderator.Tag, channel.Tag));
                }
            }

            if (_temporaryImages.Remove(args.Message.Id, out var attachment))
            {
                using (attachment)
                {
                    await logChannel.SendMessageAsync(attachment,
                                                      embed : builder
                                                      .WithImageUrl($"attachment://{attachment.FileName}")
                                                      .Build());
                }

                return;
            }

            await logChannel.SendMessageAsync(embed : builder.Build());
        }
Пример #7
0
 public static Task <RestUserMessage> EmbedMessageAsync(this ITextChannel channel, LocalEmbedBuilder builder)
 {
     if (builder.Color == null)
     {
         builder.Color = Color.Lavender;
     }
     return(channel.SendMessageAsync("", false, builder.Build()));
 }
Пример #8
0
        public async Task AvatarAsync(SkeletonUser user = null)
        {
            user ??= new SkeletonUser(Context.User);

            var embed = new LocalEmbedBuilder {
                Color = Color.Goldenrod, ImageUrl = user.AvatarUrl
            }
            .WithAuthor($"{user.FullName} | {user.Id}");

            await RespondAsync(embed.Build());
        }
Пример #9
0
        private static async Task <IUserMessage> SendMessageAsync(IMessageChannel channel, string message, string?title, Color color)
        {
            var embed = new LocalEmbedBuilder()
            {
                Color       = color,
                Title       = title,
                Description = message
            };

            return(await channel.SendMessageAsync(embed : embed.Build()));
        }
Пример #10
0
        private Task OnCommandExecutionFailed(CommandExecutionFailedEventArgs e)
        {
            var ctx = (AatroxCommandContext)e.Context;

            _logger.Error($"Command errored: {e.Context.Command.Name} by {ctx.User.Id} in {ctx.Guild.Id}", e.Result.Exception);

            var str = new StringBuilder();

            switch (e.Result.Exception)
            {
            case DiscordHttpException ex when ex.HttpStatusCode == HttpStatusCode.Unauthorized:
                str.AppendLine("I don't have enough power to perform this action. (please check that the hierarchy of the bot is correct)");
                break;

            case DiscordHttpException ex when ex.HttpStatusCode == HttpStatusCode.BadRequest:
                str.AppendLine($"The requested action has been stopped by Discord: `{ex.Message}`");
                break;

            case DiscordHttpException ex:
                str.AppendLine($":angry: | Something bad happened: [{ex.HttpStatusCode}] {ex.Message}");
                break;

            case ArgumentException ex:
                str.AppendLine($"{ex.Message}\n");
                str.AppendLine($"Are you sure you didn't fail when typing the command? Please do `{ctx.Prefix}help {e.Result.Command.FullAliases[0]}`");
                break;

            default:
                str.AppendLine($"{e.Result.Exception.GetType()} occured.");
                str.AppendLine($"{e.Result.Exception.Message}");
                str.AppendLine($"{e.Result.Exception.StackTrace}");
                _logger.Error($"{e.Result.Exception.GetType()} occured.", e.Result.Exception);
                break;
            }

            if (str.Length == 0)
            {
                return(Task.CompletedTask);
            }

            var embed = new LocalEmbedBuilder
            {
                Color = _configuration.DefaultEmbedColor,
                Title = "Something went wrong!"
            };

            embed.AddField("__Command__", e.Result.Command.Name, true);
            embed.AddField("__Author__", ctx.User.FullName(), true);
            embed.AddField("__Error(s)__", str.ToString());
            embed.WithFooter($"Type '{ctx.Prefix}help {ctx.Command.FullAliases[0].ToLowerInvariant()}' for more information.");

            return(ctx.Channel.SendMessageAsync("", false, embed.Build()));
        }
Пример #11
0
        public async Task LanguagesAsync()
        {
            var embed = new LocalEmbedBuilder();

            foreach (var languageGroup in TranslateService.GetAvailableLanguages().GroupBy(x => x.BaseCulture.Name.ToCharArray().First()).OrderBy(x => x.Key))
            {
                var resContent = languageGroup.Select(x => $"`{x.BaseCulture.Name}` - **{x.BaseCulture.DisplayName}** {x.BaseCulture.NativeName}").ToArray();
                embed.AddField(languageGroup.Key.ToString(CultureInfo.CurrentCulture), string.Join("\n", resContent));
            }

            await ReplyAsync("", false, embed.Build());
        }
Пример #12
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";
            }
        }
Пример #13
0
        public async Task Emojis()
        {
            using (var db = new DataContext())
            {
                var embed = new LocalEmbedBuilder();

                if (Context.Guild != null)
                {
                    var matches = db.TranslatePairs.Where(x => x.GuildId == Context.Guild.Id).ToArray().GroupBy(x => x.DestLang);
                    embed.Description = string.Join("\n", matches.Select(x => $"{x.Key}: {string.Join(" ", x.Select(p => p.Source))}")).FixLength(2047);
                }

                embed.AddField("Defaults", string.Join("\n", TranslateService.DefaultMap.Select(x => $"{x.LanguageString}: {string.Join(" ", x.EmoteMatches)}")));
                await ReplyAsync("", false, embed.Build());
            }
        }
        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()));
        }
Пример #15
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());
        }
        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());
        }
Пример #17
0
        public async ValueTask <AdminCommandResult> ModifySuggestionAsync(int id, [Remainder] string reason = null)
        {
            var suggestion = await Context.Database.Suggestions.FindAsync(id);

            if (suggestion?.GuildId != Context.Guild.Id)
            {
                return(CommandErrorLocalized("suggestion_notfound"));
            }

            if (!(await Context.Database.GetLoggingChannelAsync(Context.Guild.Id, LogType.SuggestionArchive) is { }
                  archiveChannel))
            {
                return(CommandErrorLocalized("suggestion_noarchive"));
            }

            IUserMessage message = null;
            int          upvotes = 0, downvotes = 0;

            if (await Context.Database.GetLoggingChannelAsync(Context.Guild.Id, LogType.Suggestion) is { }
                suggestionChannel)
            {
                try
                {
                    message = (IUserMessage)await suggestionChannel.GetMessageAsync(suggestion.MessageId);

                    var upvote = (await Context.Database.SpecialEmojis.FindAsync(Context.Guild.Id.RawValue, EmojiType.Upvote))?.Emoji ??
                                 EmojiTools.Upvote;
                    var downvote = (await Context.Database.SpecialEmojis.FindAsync(Context.Guild.Id.RawValue, EmojiType.Downvote))?.Emoji ??
                                   EmojiTools.Downvote;

                    upvotes   = Math.Max((await message.GetReactionsAsync(upvote, int.MaxValue)).Count - 1, 0);
                    downvotes = Math.Max((await message.GetReactionsAsync(downvote, int.MaxValue)).Count - 1, 0);
                }
                catch { /* ignored */ }
            }

            var author = await Context.Client.GetOrDownloadUserAsync(suggestion.UserId);

            var builder = new LocalEmbedBuilder()
                          .WithAuthor(Context.Localize(Context.Alias.Equals("approve")
                        ? "suggestion_approved_title"
                        : "suggestion_denied_title", suggestion.Id, author.Tag, upvotes, downvotes),
                                      author.GetAvatarUrl())
                          .WithDescription(suggestion.Text)
                          .WithFooter(Context.Localize(Context.Alias.Equals("approve")
                        ? "suggestion_approved_footer"
                        : "suggestion_denied_footer", Context.User.Tag),
                                      Context.User.GetAvatarUrl());

            if (Context.Alias.Equals("approve"))
            {
                builder.WithSuccessColor();
            }
            else
            {
                builder.WithErrorColor();
            }

            if (!string.IsNullOrWhiteSpace(reason))
            {
                builder.AddField(Context.Localize("title_reason"), reason);
            }

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

            _ = message?.DeleteAsync();

            Context.Database.Suggestions.Remove(suggestion);
            await Context.Database.SaveChangesAsync();

            return(CommandSuccessLocalized(Context.Alias.Equals("approve")
                ? "suggestion_approved"
                : "suggestion_denied"));
        }
        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());
        }
        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));
        }
Пример #20
0
        private async Task HandleReceivedMessageAsync(CachedUserMessage message)
        {
            if (message.Author.IsBot)
            {
                return;
            }

            if (!(message.Channel is CachedTextChannel textChannel) ||
                !textChannel.Guild.CurrentMember.GetPermissionsFor(textChannel).Has(Permission.SendMessages))
            {
                return;
            }
            if (CommandUtilities.HasAnyPrefix(message.Content, Prefixes, StringComparison.CurrentCulture, out var prefix, out var output) ||
                CommandUtilities.HasPrefix(message.Content, $"<@{Client.CurrentUser.Id}>", StringComparison.Ordinal, out output) ||
                CommandUtilities.HasPrefix(message.Content, $"<@!{Client.CurrentUser.Id}>", StringComparison.Ordinal, out output))
            {
                if (string.IsNullOrWhiteSpace(output))
                {
                    return;
                }

                try
                {
                    if (prefix is null)
                    {
                        prefix = Client.CurrentUser.Mention;
                    }
                    var ctx = MummyContext.Create(Client, message, Services, prefix);


                    ActiveTimings[ctx.UserId] = Stopwatch.StartNew();
                    var r = await Commands.ExecuteAsync(output, ctx);

                    ActiveTimings[ctx.UserId].Stop();
                    ActiveTimings.Remove(ctx.UserId, out var st);
                    if (r.IsSuccessful)
                    {
                        LogService.LogInformation($"command: {ctx.Command.Name} has successful finished execution in {st.ElapsedMilliseconds}ms.", LogSource.MessagesService, ctx.GuildId);
                    }
                    else
                    {
                        switch (r)
                        {
                        case ExecutionFailedResult executionfailed:
                        {
                            LogService.LogError(executionfailed.ToString(), LogSource.MessagesService, ctx.GuildId, executionfailed.Exception);

                            break;
                        }

                        case ArgumentParseFailedResult parsefailed:
                        {
                            var eb = new LocalEmbedBuilder();
                            eb.WithAuthor(ctx.User);
                            eb.WithTitle("ArmgumentParseFailure");
                            eb.AddField(parsefailed.Reason, parsefailed.RawArguments);
                            await ctx.Channel.SendMessageAsync(embed : eb.Build());

                            break;
                        }

                        case ArgumentParserResult parseresult:
                        {
                            LogService.LogCritical("dunno argumentparse", LogSource.MessagesService, ctx.GuildId);
                            await ctx.Channel.SendMessageAsync("a error has occoured and not been handled this error will be resolved shortly. (hopefully)");

                            break;
                        }

                        case ChecksFailedResult checksfailed:
                        {
                            var eb = new LocalEmbedBuilder();
                            eb.WithAuthor(ctx.User);
                            eb.WithTitle($"{checksfailed.FailedChecks.Count} checks have failed");
                            foreach (var(Check, Result) in checksfailed.FailedChecks)
                            {
                                eb.AddField((Check as MummyCheckBase).Name, Result.Reason, true);
                            }
                            await ctx.Channel.SendMessageAsync(embed : eb.Build());

                            break;
                        }

                        case CommandDisabledResult disabled:
                        {
                            var eb = new LocalEmbedBuilder();
                            eb.WithAuthor(ctx.User);
                            await ctx.Channel.SendMessageAsync();

                            eb.WithTitle($"{disabled.Command} is currently diabled");

                            await ctx.Channel.SendMessageAsync(embed : eb.Build());

                            break;
                        }

                        case CommandNotFoundResult notfound:
                        {
                            var eb = new LocalEmbedBuilder();
                            eb.WithAuthor(ctx.User);
                            eb.WithTitle($"command with name {notfound.Reason}");
                            await ctx.Channel.SendMessageAsync(embed : eb.Build());

                            break;
                        }

                        case CommandOnCooldownResult oncooldown:
                        {
                            var eb = new LocalEmbedBuilder();
                            eb.WithAuthor(ctx.User);
                            eb.WithTitle($"{oncooldown.Command.Name} is currently on cooldown");
                            foreach (var(cooldown, retryafter) in oncooldown.Cooldowns)
                            {
                                int index     = cooldown.ToString().LastIndexOf('.');
                                var bucketype = (CooldownBucketType)cooldown.BucketType;
                                eb.AddField(cooldown.ToString().Substring(index + 1), $"is only allowed to be run {cooldown.Amount} per {cooldown.Per.Humanize()} and it forced per {bucketype}, currently locked for {retryafter.TotalMinutes} Minutes", true);
                            }
                            await ctx.Channel.SendMessageAsync(embed : eb.Build());

                            break;
                        }

                        case OverloadsFailedResult overloadsFailed:
                        {
                            var eb = new LocalEmbedBuilder();
                            eb.WithAuthor(ctx.User);
                            eb.WithDescription(overloadsFailed.Reason);
                            foreach (var(command, overloadResult) in overloadsFailed.FailedOverloads)
                            {
                                eb.AddField($"{command.Name} {string.Join(' ', command.Parameters.Select(x => x.Name))}", overloadResult.Reason);
                            }

                            await ctx.Channel.SendMessageAsync(embed : eb.Build());

                            break;
                        }

                        case ParameterChecksFailedResult paramcheckfailed:
                        {
                            var eb = new LocalEmbedBuilder();
                            eb.WithAuthor(ctx.User);
                            eb.WithTitle($"checks on {paramcheckfailed.Parameter} have failed with provided argument: {paramcheckfailed.Argument}");
                            foreach (var(Check, Result) in paramcheckfailed.FailedChecks)
                            {
                                var index = Check.ToString().LastIndexOf('.');
                                var name  = Check.ToString().Substring(index + 1);
                                eb.AddField(name, Result.Reason);
                            }
                            break;
                        }

                        case TypeParseFailedResult typeParseFailed:
                        {
                            var eb = new LocalEmbedBuilder();
                            eb.WithAuthor(ctx.User);
                            eb.AddField(typeParseFailed.Parameter.Name, typeParseFailed.Reason);
                            await ctx.Channel.SendMessageAsync(embed : eb.Build());

                            break;
                        }
                        }
                    }
                }
                catch (Exception ex)
                {
                    LogService.LogError("Issue with message service", LogSource.MessagesService, exception: ex);
                }
            }
        }
        public async ValueTask <Page> BuildPageAsync()
        {
            var titleName = _context.Guild.Name.Sanitize();

            if (_type == PunishmentListType.User)
            {
                var target = await _context.Client.GetOrDownloadUserAsync(_targetId);

                titleName = target?.Format() ?? "???";
            }

            var builder = new LocalEmbedBuilder()
                          .WithSuccessColor()
                          .WithTitle(_context.Localize("punishment_list_title", titleName))
                          .WithFooter($"{_currentPage + 1}/{_pages.Count}");

            foreach (var punishment in _pages[_currentPage])
            {
                var target = _cachedUsers.TryGetValue(punishment.TargetId, out var cached)
                    ? cached
                    : _cachedUsers[punishment.TargetId] = await _context.Client
                                                          .GetOrDownloadUserAsync(punishment.TargetId);

                var moderator = _cachedUsers.TryGetValue(punishment.ModeratorId, out cached)
                    ? cached
                    : _cachedUsers[punishment.ModeratorId] = await _context.Client
                                                             .GetOrDownloadUserAsync(punishment.ModeratorId);

                var name = _context.Localize($"punishment_{punishment.GetType().Name.ToLower()}") +
                           $" - {_context.Localize("punishment_case", punishment.Id)}";

                var sb = new StringBuilder()
                         .AppendNewline(_context.Localize("punishment_target", target?.Format(false) ?? "???"))
                         .AppendNewline(_context.Localize("punishment_moderator", moderator?.Format(false) ?? "???"));

                if (punishment is Mute mute && mute.ChannelId.HasValue)
                {
                    sb.AppendNewline(_context.Localize("punishment_mute_channel") + ": " +
                                     (_context.Guild.GetTextChannel(mute.ChannelId.Value)?.Mention ?? "???"));
                }

                sb.AppendNewline(_context.Localize("title_reason") + ": " + punishment.Reason.TrimTo(512))
                .AppendNewline(_context.Localize("punishment_timestamp",
                                                 punishment.CreatedAt.ToString("g", _context.Language.Culture)));

                if (punishment is RevocablePunishment revocable)
                {
                    if (revocable.IsAppealable)
                    {
                        sb.AppendNewline(_context.Localize("punishment_appealed") + ' ' +
                                         (revocable.AppealedAt.HasValue
                                          ? $"✅ {revocable.AppealedAt.Value.ToString("g", _context.Language.Culture)} - {revocable.AppealReason.TrimTo(950)}"
                                          : "❌"));
                    }

                    var revoker = revocable.RevokedAt.HasValue
                        ? await _context.Client.GetOrDownloadUserAsync(revocable.RevokerId)
                        : default;

                    sb.AppendNewline(_context.Localize("punishment_revoked") + ' ' + (revocable.RevokedAt.HasValue
                                      ? "✅ " + revocable.RevokedAt.Value.ToString("g", _context.Language.Culture) +
                                                                                      $" - {Markdown.Bold(revoker?.Tag ?? "???")} - " +
                                                                                      (revocable.RevocationReason?.TrimTo(920) ??
                                                                                       _context.Localize("punishment_noreason"))
                                      : "❌"));
                }

                builder.AddField(name, sb.ToString());
            }

            return(builder.Build());
        }
Пример #22
0
        public Task HelpAsync([Remainder, Description("Command or module.")] string command)
        {
            if (string.IsNullOrWhiteSpace(command))
            {
                return(HelpAsync());
            }

            var matchingCommands = _commands.FindCommands(command);

            if (matchingCommands.Count == 0)
            {
                string typoFix = command.Levenshtein(_commands);
                if (!string.IsNullOrWhiteSpace(typoFix))
                {
                    matchingCommands = _commands.FindCommands(typoFix);
                }
            }

            LocalEmbedBuilder embed;

            if (matchingCommands.Count == 0) //Could be a module.
            {
                var matchingModule = _commands.TopLevelModules.FirstOrDefault(x => x.Name.Equals(command, StringComparison.OrdinalIgnoreCase));
                if (matchingModule is null)
                {
                    matchingModule = _commands.TopLevelModules.FirstOrDefault(x => x.Name.Equals(command.Levenshtein(_commands), StringComparison.OrdinalIgnoreCase));
                }

                var modules = _commands.GetAllModules();
                if (matchingModule is null) //Look for nested modules
                {
                    matchingModule = modules.FirstOrDefault(x => x.FullAliases.Any(y => y.Equals(command, StringComparison.OrdinalIgnoreCase)));
                }

                if (matchingModule is null) //Look for nested modules with levenshtein
                {
                    matchingModule = modules.FirstOrDefault(x => x.FullAliases.Any(y => y.Equals(command.Levenshtein(modules.Select(z => z.FullAliases.FirstOrDefault()).ToList()), StringComparison.OrdinalIgnoreCase)));
                }

                if (matchingModule is null) //Look for submodule but without complete module path
                {
                    matchingModule = modules.FirstOrDefault(x => x.Name.Equals(command, StringComparison.OrdinalIgnoreCase));
                }

                if (matchingModule is null) //Look for submodule but without complete module path with levenshtein
                {
                    matchingModule = modules.FirstOrDefault(x => x.Name.Equals(command.Levenshtein(modules.Select(z => z.Name).ToList()), StringComparison.OrdinalIgnoreCase));
                }

                if (matchingModule is null) //Remove last input
                {
                    var cmdArgs = command.Split(' ').ToList();
                    cmdArgs.RemoveAt(cmdArgs.Count - 1);

                    return(HelpAsync(string.Join(' ', cmdArgs)));
                }

                embed = new LocalEmbedBuilder
                {
                    Title       = $"Help - {matchingModule.Name} Module",
                    Description = "This embed contains the list of every command in this module.",
                    Footer      = new LocalEmbedFooterBuilder
                    {
                        Text = $"{matchingModule.Commands.Count} commands available in this context."
                    }
                };

                if (matchingModule.Submodules.Count > 0)
                {
                    embed.AddField("Modules", string.Join(", ", matchingModule.Submodules.DistinctBy(x => x.Name).Select(x => $"`{x.Name}`")));
                }

                if (matchingModule.Commands.Count > 0)
                {
                    embed.AddField("Commands", string.Join(", ", matchingModule.Commands.DistinctBy(x => x.Name).Select(x => $"`{x.Name}`")));
                }

                var moduleChecks = CommandUtilities.EnumerateAllChecks(matchingModule).Cast <AbfCheckBaseAttribute>().ToArray();
                if (moduleChecks.Length > 0)
                {
                    embed.AddField("Requirements", string.Join("\n", moduleChecks.Select(x => $"`- {x.Name}{x.Details}`")));
                }

                return(ReplyAsync(embed: embed.Build()));
            }

            embed = new LocalEmbedBuilder
            {
                Title = "Help"
            };

            var builder = new StringBuilder();

            foreach (var cmd in matchingCommands.Where(c => c.Command.Attributes.All(a => !(a is HiddenAttribute))))
            {
                builder.AppendLine($"**{cmd.Command.Description ?? "Undocumented."}**");
                builder.AppendLine(($"`{Context.Prefix}{cmd.Command.Name} {string.Join(" ", cmd.Command.Parameters.Select(GetUsage(cmd.Command)))}`".ToLowerInvariant()).TrimEnd());
                foreach (var param in cmd.Command.Parameters)
                {
                    builder.AppendLine($"`[{param.Name}]`: {param.Description ?? "Undocumented."}");
                }
                builder.AppendLine($"\n**Example:** `{cmd.Command.Remarks ?? "No example provided."}`\n");
            }

            embed.AddField("Usages", builder.ToString());

            var defaultCmd = matchingCommands.First().Command;

            var checks = CommandUtilities.EnumerateAllChecks(defaultCmd.Module).Cast <AbfCheckBaseAttribute>().ToArray();

            if (checks.Length > 0)
            {
                embed.AddField("Module Requirements", string.Join("\n", checks.Select(x => $"- `{x.Name}{x.Details}`")));
            }

            if (defaultCmd.Checks.Count > 0)
            {
                embed.AddField("Command Requirements", string.Join("\n", defaultCmd.Checks.Cast <AbfCheckBaseAttribute>().Select(x => $"- `{x.Name}{x.Details}`")));
            }

            return(ReplyAsync(embed: embed.Build()));
        }
Пример #23
0
        public async Task PoutAsync([Remainder] string?value = null)
        {
            if (string.IsNullOrEmpty(Credentials.WeebServicesToken))
            {
                await ReplyErrorAsync(Localization.ReactionsNoWeebApi);

                return;
            }

            if (value != null && value.Length > ReactionLimit)
            {
                await ReplyErrorAsync(Localization.ReactionsLimit);

                return;
            }

            var embed = new LocalEmbedBuilder
            {
                Color    = RiasUtilities.ConfirmColor,
                ImageUrl = await Service.GetReactionUrlAsync("pout"),
                Footer   = new LocalEmbedFooterBuilder().WithText($"{GetText(Localization.ReactionsPoweredBy)} weeb.sh")
            };

            if (value is null)
            {
                await Context.Channel.SendMessageAsync(GetText(Localization.ReactionsPout, Context.User.Mention), embed : embed.Build());
            }
            else
            {
                var user = ((CachedMember)Context.User).Nick ?? Context.User.Name;
                await Context.Channel.SendMessageAsync(GetText(Localization.ReactionsPoutAt, user, value.Replace("@everyone", "everyone")), embed : embed.Build());
            }
        }
Пример #24
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);
        }
Пример #25
0
        protected override async ValueTask AfterExecutedAsync(IResult result, DiscordCommandContext context)
        {
            var ctx = (AatroxCommandContext)context;

            if (result.IsSuccessful)
            {
                await ctx.EndAsync();

                return;
            }

            if (result is CommandNotFoundResult)
            {
                string?cmdName;
                var    index = 0;
                var    split = ctx.Message.Content.Substring(ctx.Prefix.ToString() !.Length)
                               .Split(Separator, StringSplitOptions.RemoveEmptyEntries);

                var maxIndex = split.Length;
                do
                {
                    string toLev = (index == 0 ? "" : Separator) + string.Join(Separator, split.Take(maxIndex));
                    maxIndex--;
                    //toLev += (index == 0 ? "" : Separator) + split[index];

                    cmdName = toLev.Levenshtein(this);
                    index++;
                } while (string.IsNullOrWhiteSpace(cmdName) && index < split.Length);

                if (string.IsNullOrWhiteSpace(cmdName))
                {
                    return;
                }

                maxIndex++;

                string?cmdParams = null;
                while (maxIndex < split.Length)
                {
                    cmdParams += " " + split[maxIndex++];
                }

                var tryResult = await ExecuteAsync(cmdName + cmdParams, ctx);

                if (tryResult.IsSuccessful)
                {
                    return;
                }

                result = tryResult;
            }

            await ctx.EndAsync();

            var str = new StringBuilder();

            switch (result)
            {
            case ChecksFailedResult err:
                str.AppendLine("The following check(s) failed:");
                foreach (var(check, error) in err.FailedChecks)
                {
                    str.AppendLine($"[`{(check as AatroxCheckAttribute)?.Name ?? check.GetType().Name}`]: `{error}`");
                }
                break;

            case TypeParseFailedResult err:
                str.AppendLine(err.Reason);
                break;

            case ArgumentParseFailedResult _:
                str.AppendLine($"The syntax of the command `{ctx.Command.FullAliases[0]}` was wrong.");
                break;

            case OverloadsFailedResult err:
                str.AppendLine($"I can't find any valid overload for the command `{ctx.Command.Name}`.");
                foreach (var overload in err.FailedOverloads)
                {
                    str.AppendLine($"[`{overload.Key.Name}`] -> `{overload.Value.Reason}`");
                }
                break;

            case ParameterChecksFailedResult err:
                str.AppendLine("The following parameter check(s) failed:");
                foreach (var(check, error) in err.FailedChecks)
                {
                    str.AppendLine($"[`{check.Parameter.Name}`]: `{error}`");
                }
                break;

            case ExecutionFailedResult _:     //this should be handled in the CommandErrored event or in the Custom Result case.
            case CommandNotFoundResult _:     //this is handled at the beginning of this method with levenshtein thing.
                break;

            case CommandOnCooldownResult err:
                var remainingTime = err.Cooldowns.OrderByDescending(x => x.RetryAfter).FirstOrDefault();
                str.AppendLine($"You're being rate limited! Please retry after {remainingTime.RetryAfter.Humanize()}.");
                break;

            default:
                str.AppendLine($"Unknown error: {result}");
                break;
            }

            if (str.Length == 0)
            {
                return;
            }

            var embed = new LocalEmbedBuilder
            {
                Color = _configuration.DefaultEmbedColor,
                Title = "Something went wrong!"
            };

            embed.WithFooter($"Type '{ctx.Prefix}help {ctx.Command?.FullAliases[0] ?? ctx.Command?.FullAliases[0] ?? ""}' for more information.");

            embed.AddField("__Command/Module__", ctx.Command?.Name ?? ctx.Command?.Module?.Name ?? "Unknown command...", true);
            embed.AddField("__Author__", ctx.User.FullName(), true);
            embed.AddField("__Error(s)__", str.ToString());

            _logger.Warn($"{ctx.User.Id} - {ctx.Guild.Id} ::> Command errored: {ctx.Command?.Name ?? "-unknown command-"}");
            await ctx.Channel.SendMessageAsync("", false, embed.Build());

            await ctx.DisposeAsync();
        }
Пример #26
0
        public async Task SleepyAsync()
        {
            if (string.IsNullOrEmpty(Credentials.WeebServicesToken))
            {
                await ReplyErrorAsync(Localization.ReactionsNoWeebApi);

                return;
            }

            var embed = new LocalEmbedBuilder
            {
                Color    = RiasUtilities.ConfirmColor,
                ImageUrl = await Service.GetReactionUrlAsync("sleepy"),
                Footer   = new LocalEmbedFooterBuilder().WithText($"{GetText(Localization.ReactionsPoweredBy)} weeb.sh")
            };

            await Context.Channel.SendMessageAsync(GetText(Localization.ReactionsSleepy, Context.User.Mention), embed : embed.Build());
        }
Пример #27
0
        public async Task HugAsync([Remainder] CachedMember member)
        {
            if (string.IsNullOrEmpty(Credentials.WeebServicesToken))
            {
                await ReplyErrorAsync(Localization.ReactionsNoWeebApi);

                return;
            }

            var embed = new LocalEmbedBuilder
            {
                Color    = RiasUtilities.ConfirmColor,
                ImageUrl = await Service.GetReactionUrlAsync("hug"),
                Footer   = new LocalEmbedFooterBuilder().WithText($"{GetText(Localization.ReactionsPoweredBy)} weeb.sh")
            };

            if (member.Id == Context.User.Id)
            {
                await Context.Channel.SendMessageAsync(GetText(Localization.ReactionsHugYou, Context.User.Mention), embed : embed.Build());
            }
            else
            {
                var user = ((CachedMember)Context.User).Nick ?? Context.User.Name;
                await Context.Channel.SendMessageAsync(GetText(Localization.ReactionsHuggedBy, member.Mention, user), embed : embed.Build());
            }
        }
Пример #28
0
        public async Task Eval([Remainder] string code)
        {
            var builder = new LocalEmbedBuilder
            {
                Title       = "Evaluating Code...",
                Color       = Color.DarkRed,
                Description = "Waiting for completion...",
                Author      = new LocalEmbedAuthorBuilder
                {
                    IconUrl = Context.User.GetAvatarUrl(),
                    Name    = Context.User.DisplayName
                },
                Timestamp    = DateTimeOffset.UtcNow,
                ThumbnailUrl = Context.Guild.CurrentMember.GetAvatarUrl()
            };
            var msg = await ReplyAsync(embed : builder);

            var sw     = Stopwatch.StartNew();
            var script = EvalService.Build(code);

            string snippet = string.Join(Environment.NewLine, script.Code.Split(Environment.NewLine.ToCharArray()).Where(line => !line.StartsWith("using")));

            var diagnostics     = script.Compile();
            var compilationTime = sw.ElapsedMilliseconds;

            if (diagnostics.Any(x => x.Severity == DiagnosticSeverity.Error))
            {
                builder.WithDescription($"Compilation finished in: {compilationTime}ms");
                builder.WithColor(Color.Red);
                builder.WithTitle("Failed Evaluation");

                builder.AddField("Code", $"```cs{Environment.NewLine}{snippet}```");
                builder.AddField("Compilation Errors", string.Join('\n', diagnostics.Select(x => $"{x}")));

                await msg.ModifyAsync(x => x.Embed = builder.Build());

                return;
            }
            sw.Restart();

            var context = new RoslynContext(Context, Services);

            try
            {
                var result = await script.RunAsync(context);

                sw.Stop();
                builder.WithColor(Color.Green);

                builder.WithDescription($"Code compiled in {compilationTime}ms and ran in {sw.ElapsedMilliseconds}ms");
                builder.WithTitle("Code Evaluated");
                builder.AddField("Code", $"```cs{Environment.NewLine}{snippet}```");

                if (!(result.ReturnValue is null))
                {
                    var sb     = new StringBuilder();
                    var type   = result.ReturnValue.GetType();
                    var rValue = result.ReturnValue;

                    switch (rValue)
                    {
                    case Color col:
                        builder.WithColor(col);
                        builder.AddField("Colour", $"{col.RawValue}");
                        break;

                    case string str:
                        builder.AddField($"{type}", $"\"{str}\"");
                        break;

                    case IEnumerable enumerable:

                        var list     = enumerable.Cast <object>().ToList();
                        var enumType = enumerable.GetType();

                        if (list.Count > 25)
                        {
                            builder.AddField($"{enumType}", $"Enumerable has more than 10 elements ({list.Count})");
                            break;
                        }

                        if (list.Count > 0)
                        {
                            sb.AppendLine("```css");

                            foreach (var element in list)
                            {
                                sb.Append('[').Append(element).AppendLine("]");
                            }

                            sb.AppendLine("```");
                        }
                        else
                        {
                            sb.AppendLine("Collection is empty");
                        }

                        builder.AddField($"{enumType}", sb.ToString());

                        break;

                    case Enum @enum:

                        builder.AddField($"{@enum.GetType()}", $"```\n{@enum.Humanize()}\n```");

                        break;

                    default:

                        var messages = rValue.Inspect();

                        if (type.IsValueType && messages.Count == 0)
                        {
                            builder.AddField($"{type}", rValue);
                        }

                        foreach (var message in messages)
                        {
                            await ReplyAsync($"```css\n{message}\n```");
                        }

                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                sw.Stop();


                builder.WithDescription($"Code evaluated in {sw.ElapsedMilliseconds}ms but there was a issue tho");
                builder.WithColor(Color.Red);
                builder.WithTitle("Failed Evaluation");
                builder.AddField("Code", $"```cs{Environment.NewLine}{snippet}```");

                var str = ex.ToString();

                builder.AddField("Exception", Format.Sanitize(str.Length >= 1000 ? str.Substring(0, 1000) : str));
            }
            finally
            {
                GC.Collect();
                GC.WaitForPendingFinalizers();
            }

            await msg.ModifyAsync(x => x.Embed = builder.Build());
        }
        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()));
        }
Пример #30
0
        public async ValueTask <AdminCommandResult> CreateSuggestionAsync([Remainder] string text)
        {
            if (!(await Context.Database.GetLoggingChannelAsync(Context.Guild.Id,
                                                                LogType.Suggestion) is { } suggestionChannel))
            {
                return(CommandErrorLocalized("suggestion_nochannel"));
            }

            var image  = new MemoryStream();
            var format = ImageFormat.Default;

            if (Context.Message.Attachments.FirstOrDefault() is { } attachment&&
                attachment.FileName.HasImageExtension(out format))
            {
                await using var stream = await Http.GetStreamAsync(attachment.Url);

                await stream.CopyToAsync(image);

                image.Seek(0, SeekOrigin.Begin);
            }

            if (format == ImageFormat.Default)
            {
                var match = StringExtensions.LazyImageLinkRegex.Match(text);
                if (match.Success && match.Value.HasImageExtension(out format))
                {
                    try
                    {
                        await using var stream = await Http.GetStreamAsync(match.Value);

                        await stream.CopyToAsync(image);

                        image.Seek(0, SeekOrigin.Begin);
                    }
                    catch { /* ignored */ }
                }
            }

            var suggestion = Context.Database.Suggestions.Add(new Suggestion(Context.Guild.Id, Context.User.Id, text, image, format))
                             .Entity;
            await Context.Database.SaveChangesAsync();

            var builder = new LocalEmbedBuilder()
                          .WithSuccessColor()
                          .WithAuthor(Context.User)
                          .WithDescription(text)
                          .WithFooter(Context.Localize("suggestion_id", suggestion.Id));

            RestUserMessage message;

            if (format != ImageFormat.Default)
            {
                message = await suggestionChannel.SendMessageAsync(new LocalAttachment(image, $"attachment.{format.ToString().ToLower()}"),
                                                                   embed : builder.WithImageUrl($"attachment://attachment.{format.ToString().ToLower()}").Build());
            }
            else
            {
                message = await suggestionChannel.SendMessageAsync(embed : builder.Build());
            }

            var upvote = (await Context.Database.SpecialEmojis.FindAsync(Context.Guild.Id.RawValue, EmojiType.Upvote))?.Emoji ??
                         EmojiTools.Upvote;
            var downvote = (await Context.Database.SpecialEmojis.FindAsync(Context.Guild.Id.RawValue, EmojiType.Downvote))?.Emoji ??
                           EmojiTools.Downvote;

            await message.AddReactionAsync(upvote);

            await message.AddReactionAsync(downvote);

            suggestion.SetMessageId(message.Id);
            Context.Database.Suggestions.Update(suggestion);
            await Context.Database.SaveChangesAsync();

            _ = Context.Message.DeleteAsync();
            return(CommandSuccessLocalized("suggestion_successful", args: suggestion.Id));
        }