diff --git a/AkkoBot/Data/Localization/Responses_en-US.yaml b/AkkoBot/Data/Localization/Responses_en-US.yaml index 2715ecf..9d69bd7 100644 --- a/AkkoBot/Data/Localization/Responses_en-US.yaml +++ b/AkkoBot/Data/Localization/Responses_en-US.yaml @@ -605,6 +605,7 @@ joinrole_limit: Limit of 3 join roles has been reached. joinrole_list_empty: There are no join roles. joinrole_list_title: List of Join Roles joinrole_removed: The {0} role has been removed from the list of join roles. +jump_to: Jump to kick: Kick kick_enum: kicked kick_notification: You have been kicked from the {0} server. @@ -628,12 +629,14 @@ log_emoji_edited_simple: Emoji {0} has been modified. log_emoji_title: Emoji updated log_ignore_add: Added {0} to the ignored list. log_ignore_remove: Removed {0} from the ignored list. +log_invalid: Log of type {0} is not valid. log_invite_created_title: Invite created log_invite_deleted_title: Invite deleted log_joiningalt_title: ❗Possible alt has joined log_joiningmember_title: User has joined log_leavingalt_title: ❗Possible alt has left log_leavingmember_title: User has left +log_list_desc: List of available guild logs. Logs that are currently active will have the channel they send messages to listed right next to them. Enabling/Disabling a log group affects all logs in it. log_list_title: Server Logs log_message_deleted_title: Message deleted log_message_edited_title: Message edited @@ -655,6 +658,8 @@ medium: Medium members: Members memory: Memory message: Message +message_pinned: Message pinned +message_unpinned: Message unpinned messages: Messages minutes: Minutes moderator: Moderator @@ -676,6 +681,7 @@ name: Name new_name: New name news: News nickname: Nickname +nickname_changed: Nickname Changed none: None notice_success: Notice added successfully. nsfw: NSFW @@ -739,6 +745,7 @@ perm_use_voice: Connect perm_use_voice_detection: Voice Detection perm_view_audit_log: View Audit Log permissions: Permissions +pinned_on: Pinned on poll: Poll poll_anonymous_error: There is an anonymous poll already active in this channel. poll_anonymous_footer: You can also use the {0} command in direct message to vote on this poll. @@ -844,6 +851,7 @@ undeafen_success: User {0} can now hear other users speaking in voice channels. unknown: Unknown unlockchannel_reason: Lockdown Lifted unmute_success: User {0} has been unmuted. +unpinned_on: Unpinned on unspecified: Unspecified unwarn_all: Removed all warnings from {0}. unwarn_failure: Infraction of ID {0} was not found. @@ -884,13 +892,4 @@ warnpl_punish: Punishment warnpl_title: Server Punishments with_votes: with {0} votes. x_times: '{0} times' -xid: ID of {0} {1} is {2}. - -nickname_changed: Nickname Changed -log_invalid: Log of type {0} is not valid. -message_pinned: Message pinned -message_unpinned: Message unpinned -pinned_on: Pinned on -unpinned_on: Unpinned on -jump_to: Jump to -log_list_desc: List of available guild logs. Logs that are currently active will have the channel they send messages to listed right next to them. Enabling/Disabling a log group affects all logs in it. \ No newline at end of file +xid: ID of {0} {1} is {2}. \ No newline at end of file diff --git a/AkkoBot/Data/Localization/Respostas_pt-BR.yaml b/AkkoBot/Data/Localization/Respostas_pt-BR.yaml index dc6c9d5..8634ead 100644 --- a/AkkoBot/Data/Localization/Respostas_pt-BR.yaml +++ b/AkkoBot/Data/Localization/Respostas_pt-BR.yaml @@ -605,6 +605,7 @@ joinrole_limit: O limite de 3 cargos de entrada foi atingido. joinrole_list_empty: Não há cargos de entrada. joinrole_list_title: Lista de Cargos de Entrada joinrole_removed: O cargo {0} foi removido da lista de cargos de entrada. +jump_to: Pular para kick: Expulsar kick_enum: expulso kick_notification: Você foi expulso do servidor {0}. @@ -628,12 +629,14 @@ log_emoji_edited_simple: Emoji {0} foi modificado. log_emoji_title: Emoji atualizado log_ignore_add: '{0} foi adicionado à lista de canais ignorados.' log_ignore_remove: '{0} foi removido da lista de canais ignorados.' +log_invalid: Log do tipo {0} não é válido. log_invite_created_title: Convite criado log_invite_deleted_title: Convite excluído log_joiningalt_title: ❗Possível alt entrou log_joiningmember_title: Usuário entrou log_leavingalt_title: ❗Possível alt saiu log_leavingmember_title: Usuário saiu +log_list_desc: Lista de logs de servidor disponíveis. Logs que estiverem ativos terão o canal para onde as mensagems são enviadas listado ao seu lado. Ativar/Desativar um grupo de logs terá efeito sobre todos os logs contidos nesse grupo. log_list_title: Registros do Servidor log_message_deleted_title: Mensagem excluída log_message_edited_title: Mensagem alterada @@ -655,6 +658,8 @@ medium: Médio members: Membros memory: Memória message: Mensagem +message_pinned: Menssagem fixada +message_unpinned: mensagem desafixada messages: Mensagens minutes: Minutos moderator: Moderador @@ -676,6 +681,7 @@ name: Nome new_name: Nome novo news: Anúncios nickname: Apelido +nickname_changed: Apelido Alterado none: Nenhum notice_success: Anotação adicionada com sucesso. nsfw: NSFW @@ -739,6 +745,7 @@ perm_use_voice: Conectar perm_use_voice_detection: Detecção de Voz perm_view_audit_log: Visualizar o Registro de Auditoria permissions: Permissões +pinned_on: Fixada em poll: Enquete poll_anonymous_error: Já existe uma enquete anônima ativa nesse canal. poll_anonymous_footer: Você também pode usar o comando {0} em mensagem direta para votar nessa enquete. @@ -844,6 +851,7 @@ undeafen_success: Usuário {0} pode ouvir outros usuários nos canais de voz nov unknown: Desconhecido unlockchannel_reason: Lockdown Suspenso unmute_success: Usuário {0} pode falar novamente. +unpinned_on: Desafixada em unspecified: Não especificado unwarn_all: Todas as advertências do usuário {0} foram removidas. unwarn_failure: A infração de ID {0} não foi encontrada. @@ -884,13 +892,4 @@ warnpl_punish: Punição warnpl_title: Punições do Servidor with_votes: com {0} votos. x_times: '{0} vezes' -xid: ID do {0} {1} é {2}. - -nickname_changed: Apelido Alterado -log_invalid: Log do tipo {0} não é válido. -message_pinned: Menssagem fixada -message_unpinned: mensagem desafixada -pinned_on: Fixada em -unpinned_on: Desafixada em -jump_to: Pular para -log_list_desc: Lista de logs de servidor disponíveis. Logs que estiverem ativos terão o canal para onde as mensagems são enviadas listado ao seu lado. Ativar/Desativar um grupo de logs terá efeito sobre todos os logs contidos nesse grupo. \ No newline at end of file +xid: ID do {0} {1} é {2}. \ No newline at end of file diff --git a/AkkoBot/Migrations/20220104075436_GuildLogExpansion.cs b/AkkoBot/Migrations/20220104075436_GuildLogExpansion.cs index ce6f88d..bcf376e 100644 --- a/AkkoBot/Migrations/20220104075436_GuildLogExpansion.cs +++ b/AkkoBot/Migrations/20220104075436_GuildLogExpansion.cs @@ -1,4 +1,4 @@ -using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Migrations; #nullable disable @@ -28,4 +28,4 @@ protected override void Down(MigrationBuilder migrationBuilder) oldType: "bigint"); } } -} +} \ No newline at end of file diff --git a/AkkoCore/Commands/Modules/Administration/GuildLogging.cs b/AkkoCore/Commands/Modules/Administration/GuildLogging.cs index 009bf67..ffed3e3 100644 --- a/AkkoCore/Commands/Modules/Administration/GuildLogging.cs +++ b/AkkoCore/Commands/Modules/Administration/GuildLogging.cs @@ -154,16 +154,15 @@ public async Task ListGuildLogsAsync(CommandContext context) var message = new SerializableDiscordEmbed() .WithTitle("log_list_title") .WithDescription("log_list_desc") + .AddField(GuildLogType.RoleEvents.ToString(), GetLogSubtypes(GuildLogType.RoleEvents), true) .AddField(GuildLogType.MessageEvents.ToString(), GetLogSubtypes(GuildLogType.MessageEvents), true) .AddField(GuildLogType.ChannelEvents.ToString(), GetLogSubtypes(GuildLogType.ChannelEvents), true) - .AddField(GuildLogType.RoleEvents.ToString(), GetLogSubtypes(GuildLogType.RoleEvents), true) .AddField(GuildLogType.MemberEvents.ToString(), GetLogSubtypes(GuildLogType.MemberEvents), true) - .AddField(GuildLogType.AltEvents.ToString(), GetLogSubtypes(GuildLogType.AltEvents), true) - .AddField(GuildLogType.PunishmentEvents.ToString(), GetLogSubtypes(GuildLogType.PunishmentEvents), true) .AddField(GuildLogType.VoiceEvents.ToString(), GetLogSubtypes(GuildLogType.VoiceEvents), true) - .AddField(GuildLogType.InviteEvents.ToString(), GetLogSubtypes(GuildLogType.InviteEvents), true) .AddField(GuildLogType.EmojiEvents.ToString(), GetLogSubtypes(GuildLogType.EmojiEvents), true) - .AddField(GuildLogType.PresenceEvents.ToString(), GetLogSubtypes(GuildLogType.PresenceEvents), true); + .AddField(GuildLogType.InviteEvents.ToString(), GetLogSubtypes(GuildLogType.InviteEvents), true) + .AddField(GuildLogType.AltEvents.ToString(), GetLogSubtypes(GuildLogType.AltEvents), true) + .AddField(GuildLogType.PunishmentEvents.ToString(), GetLogSubtypes(GuildLogType.PunishmentEvents), true); await context.RespondLocalizedAsync(message, false); diff --git a/AkkoCore/Commands/Modules/Administration/Services/GuildLogService.cs b/AkkoCore/Commands/Modules/Administration/Services/GuildLogService.cs index 2ef6fca..3f2bde9 100644 --- a/AkkoCore/Commands/Modules/Administration/Services/GuildLogService.cs +++ b/AkkoCore/Commands/Modules/Administration/Services/GuildLogService.cs @@ -38,12 +38,12 @@ public sealed class GuildLogService /// /// Contains the flags of the guild log types that are not supported for guild logging. /// - public const GuildLogType ForbiddenTypes = GuildLogType.MessageCreated | GuildLogType.UserStatusUpdated; + public const GuildLogType ForbiddenTypes = GuildLogType.MessageCreated | GuildLogType.PresenceEvents; /// /// Contains the flags of all groups of guild logs. /// - public static GuildLogType[] GuildLogTypeGroups { get; } = new[] + public static GuildLogType[] GuildLogTypeGroups { get; } = new[] { GuildLogType.None, GuildLogType.All, diff --git a/AkkoCore/Commands/Modules/Basic/BasicCommands.cs b/AkkoCore/Commands/Modules/Basic/BasicCommands.cs index 4428b27..fdf6fcb 100644 --- a/AkkoCore/Commands/Modules/Basic/BasicCommands.cs +++ b/AkkoCore/Commands/Modules/Basic/BasicCommands.cs @@ -4,7 +4,6 @@ using AkkoCore.Core.Abstractions; using AkkoCore.Extensions; using AkkoCore.Models.Serializable; -using AkkoCore.Services.Caching.Abstractions; using AkkoCore.Services.Events.Abstractions; using DSharpPlus; using DSharpPlus.CommandsNext; @@ -27,17 +26,15 @@ public sealed class BasicCommands : AkkoCommandModule, IDisposable private readonly ICommandHandler _commandHandler; private readonly IGlobalEventsHandler _globalEvents; - private readonly IDbCache _dbCache; private readonly ICogs _cogs; private readonly DiscordShardedClient _shardedClient; private readonly Credentials _creds; - public BasicCommands(ICommandHandler commandHandler, IGlobalEventsHandler globalEvents, IDbCache dbCache, + public BasicCommands(ICommandHandler commandHandler, IGlobalEventsHandler globalEvents, ICogs cogs, DiscordShardedClient shardedClient, Credentials creds) { _commandHandler = commandHandler; _globalEvents = globalEvents; - _dbCache = dbCache; _cogs = cogs; _shardedClient = shardedClient; _creds = creds; diff --git a/AkkoCore/Commands/Modules/Utilities/GuildEmojis.cs b/AkkoCore/Commands/Modules/Utilities/GuildEmojis.cs index d474051..a0b6857 100644 --- a/AkkoCore/Commands/Modules/Utilities/GuildEmojis.cs +++ b/AkkoCore/Commands/Modules/Utilities/GuildEmojis.cs @@ -41,7 +41,10 @@ public async Task CheckGuildEmojiAsync(CommandContext context) foreach (var emojiGroup in emojis) embed.AddField(AkkoConstants.ValidWhitespace, string.Join('\n', emojiGroup.Select(emoji => $"{emoji} {emoji.GetDiscordName()}")), true); - await context.RespondPaginatedByFieldsAsync(embed, 2); + if (embed.Fields?.Count > 0) + await context.RespondPaginatedByFieldsAsync(embed, 2); + else + await context.Message.CreateReactionAsync(AkkoStatics.FailureEmoji); } [Command("show"), Aliases("showemoji", "se")] diff --git a/AkkoCore/Common/DiscordEmbedComparer.cs b/AkkoCore/Common/DiscordEmbedComparer.cs index 54d3e99..5aaa507 100644 --- a/AkkoCore/Common/DiscordEmbedComparer.cs +++ b/AkkoCore/Common/DiscordEmbedComparer.cs @@ -26,30 +26,30 @@ public bool Equals(DiscordEmbed? x, DiscordEmbed? y) { return ReferenceEquals(x, y) || ((x is not null || y is null) && (x is null || y is not null) - && Equals(x!.Author?.Url?.AbsoluteUri, y!.Author?.Url?.AbsoluteUri) - && Equals(x.Author?.IconUrl?.ToString(), y.Author?.IconUrl?.ToString()) - && Equals(x.Author?.ProxyIconUrl?.ToString(), y.Author?.ProxyIconUrl?.ToString()) - && Equals(x.Author?.Name, y.Author?.Name) - && x.Color == y.Color - && Equals(x.Description, y.Description) - && Equals(x.Footer?.Text, y.Footer?.Text) - && Equals(x.Footer?.IconUrl?.ToString(), y.Footer?.IconUrl?.ToString()) - && Equals(x.Footer?.ProxyIconUrl?.ToString(), y.Footer?.ProxyIconUrl?.ToString()) - && x.Image?.Height == y.Image?.Height - && x.Image?.Width == y.Image?.Width - && Equals(x.Image?.Url?.ToString(), y.Image?.Url.ToString()) - && Equals(x.Image?.ProxyUrl.ToString(), y.Image?.ProxyUrl?.ToString()) - && Equals(x.Provider?.Url?.AbsoluteUri, y.Provider?.Url?.AbsoluteUri) - && Equals(x.Provider?.Name, y.Provider?.Name) - && x.Thumbnail?.Height == y.Thumbnail?.Height - && x.Thumbnail?.Width == y.Thumbnail?.Width - && Equals(x.Thumbnail?.Url?.ToString(), y.Thumbnail?.Url?.ToString()) - && Equals(x.Thumbnail?.ProxyUrl?.ToString(), y.Thumbnail?.ProxyUrl?.ToString()) - && x.Timestamp == y.Timestamp // Remove, maybe? - && Equals(x.Title, y.Title) - && x.Type == y.Type - && Equals(x.Url?.AbsoluteUri, y.Url?.AbsoluteUri) - && ((x.Fields is null && y.Fields is null) || (x.Fields is not null && y.Fields is not null)) - && x.Fields?.All(x => y.Fields?.Contains(x, _fieldComparer) is true) is not false); + && Equals(x!.Author?.Url?.AbsoluteUri, y!.Author?.Url?.AbsoluteUri) + && Equals(x.Author?.IconUrl?.ToString(), y.Author?.IconUrl?.ToString()) + && Equals(x.Author?.ProxyIconUrl?.ToString(), y.Author?.ProxyIconUrl?.ToString()) + && Equals(x.Author?.Name, y.Author?.Name) + && x.Color == y.Color + && Equals(x.Description, y.Description) + && Equals(x.Footer?.Text, y.Footer?.Text) + && Equals(x.Footer?.IconUrl?.ToString(), y.Footer?.IconUrl?.ToString()) + && Equals(x.Footer?.ProxyIconUrl?.ToString(), y.Footer?.ProxyIconUrl?.ToString()) + && x.Image?.Height == y.Image?.Height + && x.Image?.Width == y.Image?.Width + && Equals(x.Image?.Url?.ToString(), y.Image?.Url.ToString()) + && Equals(x.Image?.ProxyUrl.ToString(), y.Image?.ProxyUrl?.ToString()) + && Equals(x.Provider?.Url?.AbsoluteUri, y.Provider?.Url?.AbsoluteUri) + && Equals(x.Provider?.Name, y.Provider?.Name) + && x.Thumbnail?.Height == y.Thumbnail?.Height + && x.Thumbnail?.Width == y.Thumbnail?.Width + && Equals(x.Thumbnail?.Url?.ToString(), y.Thumbnail?.Url?.ToString()) + && Equals(x.Thumbnail?.ProxyUrl?.ToString(), y.Thumbnail?.ProxyUrl?.ToString()) + && x.Timestamp == y.Timestamp + && Equals(x.Title, y.Title) + && x.Type == y.Type + && Equals(x.Url?.AbsoluteUri, y.Url?.AbsoluteUri) + && ((x.Fields is null && y.Fields is null) || (x.Fields is not null && y.Fields is not null)) + && x.Fields?.All(x => y.Fields?.Contains(x, _fieldComparer) is true) is not false); } -} +} \ No newline at end of file diff --git a/AkkoCore/Common/DiscordEmbedFieldComparer.cs b/AkkoCore/Common/DiscordEmbedFieldComparer.cs index 2c25ca1..e290f17 100644 --- a/AkkoCore/Common/DiscordEmbedFieldComparer.cs +++ b/AkkoCore/Common/DiscordEmbedFieldComparer.cs @@ -1,7 +1,6 @@ using AkkoCore.Commands.Attributes; using DSharpPlus.Entities; using Microsoft.Extensions.DependencyInjection; -using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; @@ -20,8 +19,8 @@ public bool Equals(DiscordEmbedField? x, DiscordEmbedField? y) { return ReferenceEquals(x, y) || ((x is not null || y is null) && (x is null || y is not null) - && x!.Inline == y!.Inline - && Equals(x.Value, y.Value) - && Equals(x.Name, y.Name)); + && x!.Inline == y!.Inline + && Equals(x.Value, y.Value) + && Equals(x.Name, y.Name)); } -} +} \ No newline at end of file diff --git a/AkkoCore/Enums/EmojiActivity.cs b/AkkoCore/Enums/EmojiActivity.cs index e904d96..76d7e25 100644 --- a/AkkoCore/Enums/EmojiActivity.cs +++ b/AkkoCore/Enums/EmojiActivity.cs @@ -19,4 +19,4 @@ public enum EmojiActivity /// The emoji was deleted. /// Deleted -} +} \ No newline at end of file diff --git a/AkkoCore/Extensions/GuildEmojisUpdateEventArgsExt.cs b/AkkoCore/Extensions/GuildEmojisUpdateEventArgsExt.cs index 81b9041..8b9ee48 100644 --- a/AkkoCore/Extensions/GuildEmojisUpdateEventArgsExt.cs +++ b/AkkoCore/Extensions/GuildEmojisUpdateEventArgsExt.cs @@ -19,4 +19,4 @@ public static EmojiActivity GetStatus(this GuildEmojisUpdateEventArgs eventArgs) > 0 => EmojiActivity.Deleted }; } -} +} \ No newline at end of file diff --git a/AkkoCore/Services/Database/Enums/GuildLogType.cs b/AkkoCore/Services/Database/Enums/GuildLogType.cs index b799951..96fd4e4 100644 --- a/AkkoCore/Services/Database/Enums/GuildLogType.cs +++ b/AkkoCore/Services/Database/Enums/GuildLogType.cs @@ -18,7 +18,7 @@ public enum GuildLogType : long /// Unknown = 1L << 0, - /* Messages */ + /* Messages */ /// /// When a Discord message is created. @@ -258,7 +258,7 @@ public enum GuildLogType : long /// /// User activity, avatar and username changes. /// - PresenceEvents = UserActivityCreated | UserActivityUpdated | UserActivityRemoved | UserStatusUpdated | UserAvatarUpdated | UserNameUpdated, + PresenceEvents = UserActivityCreated | UserActivityUpdated | UserActivityRemoved | UserStatusUpdated | UserAvatarUpdated | UserNameUpdated, /// /// All events. diff --git a/AkkoCore/Services/Events/Common/GuildLogGenerator.cs b/AkkoCore/Services/Events/Common/GuildLogGenerator.cs index eb98133..88190a4 100644 --- a/AkkoCore/Services/Events/Common/GuildLogGenerator.cs +++ b/AkkoCore/Services/Events/Common/GuildLogGenerator.cs @@ -79,6 +79,7 @@ public DiscordWebhookBuilder GetMessageDeleteLog(DiscordMessage message) .WithDescription($"{_localizer.GetResponseString(settings.Locale, "channel")}: {message.Channel.Mention} | {message.Channel.Name}\n\n{message.Content}") .AddField("author_mention", message.Author.Mention, true) .AddField("deleted_on", DateTimeOffset.Now.ToDiscordTimestamp(), true) + .AddField("jump_to", Formatter.MaskedUrl('#' + message.Channel.Name, message.JumpLink), true) .WithFooter($"{_localizer.GetResponseString(settings.Locale, "id")}: {message.Id}") .WithLocalization(_localizer, settings.Locale); diff --git a/AkkoCore/Services/Events/GuildLogEventHandler.cs b/AkkoCore/Services/Events/GuildLogEventHandler.cs index 0b6f4e2..526a09f 100644 --- a/AkkoCore/Services/Events/GuildLogEventHandler.cs +++ b/AkkoCore/Services/Events/GuildLogEventHandler.cs @@ -19,7 +19,6 @@ using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; -using System.Reflection; using System.Runtime.CompilerServices; using System.Threading.Tasks; @@ -60,7 +59,7 @@ public Task CacheMessageOnCreationAsync(DiscordClient client, MessageCreateEvent { if (eventArgs.Guild is null || eventArgs.Message.Author?.IsBot is not false || !TryGetGuildLogs(eventArgs.Guild.Id, GuildLogType.MessageEvents, out var guildLogs) || !guildLogs.Any(x => x.IsActive)) - return Task.CompletedTask; + return Task.CompletedTask; if (!_akkoCache.GuildMessageCache.TryGetValue(eventArgs.Guild.Id, out var messageCache)) { @@ -103,8 +102,6 @@ public Task LogUpdatedMessageAsync(DiscordClient client, MessageUpdateEventArgs return DispatchLogAsync(client, eventArgs.Guild, guildLog, () => _logGenerator.GetMessageUpdateLog(eventArgs)); } - - public async Task LogDeletedMessageAsync(DiscordClient client, MessageDeleteEventArgs eventArgs) { if (eventArgs.Guild is null || eventArgs.Message.Author?.IsBot is not false