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()); }
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()); }
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()); }
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()); }
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()); }
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()); }
public static Task <RestUserMessage> EmbedMessageAsync(this ITextChannel channel, LocalEmbedBuilder builder) { if (builder.Color == null) { builder.Color = Color.Lavender; } return(channel.SendMessageAsync("", false, builder.Build())); }
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()); }
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())); }
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())); }
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()); }
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"; } }
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())); }
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()); }
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)); }
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()); }
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())); }
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()); } }
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); }
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(); }
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()); }
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()); } }
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())); }
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)); }