From dff6a57a920096b3f4c481dda4221c4e2067c537 Mon Sep 17 00:00:00 2001 From: Misha133 <61027276+Misha-133@users.noreply.github.com> Date: Sat, 15 Apr 2023 02:13:02 +0300 Subject: [PATCH] [Feature] `Audit Log Created` gateway event support (#2627) * add event to socket client * make `AuditLog` param optional * Some WIP audit log changes * api models * moar models * complete models * modelsss * forgot to push * oh lol forgot this too * api & rest guild method * revert VS being VS & formatting to file scoped namespace * socket entities * some work eh * moar stuff - switched to d.net's attribute for audit log deserialization * working socket guild updated event + reworked rest GuildInfo creation * a bit of refactoring + new models * +channel created * channel updated & channel deleted * refactor rest channel updated log + some nullable fixes * rest channel created + deleted logs * user banned socket log * kick + unban * moar log modelsssss * fixes & 4 more log types * overwrite logs * role logs * invite logs * webhook logs * switch to `ISocketAuditLogData` for socket log data * emote logs * move stuff around * move more stuff around * audit logs cache * scheduled event logs * thread logs * command permission update audit log * fetch scheduled event data from log * integration audit logs * sticker audit log data * stage instance audit logs * auto mod rule audit logs * fix * forgot couple props * command perm updated data from options * final automod ones * debugging goes away :( * merge cringe * ... * yup * fix xml doc * onboarding audit logs * changes --------- Co-authored-by: cat --- .../Entities/AuditLogs/ActionType.cs | 46 ++- .../Entities/AuditLogs/IAuditLogInfoModel.cs | 6 + .../Channels/ThreadArchiveDuration.cs | 6 - .../Entities/Guilds/IGuild.cs | 2 + .../AuditLogs/AutoModRuleInfoAuditLogModel.cs | 30 ++ .../API/AuditLogs/ChannelInfoAuditLogModel.cs | 57 +++ .../API/AuditLogs/GuildInfoAuditLogModel.cs | 82 +++++ .../AuditLogs/IntegrationInfoAuditLogModel.cs | 33 ++ .../API/AuditLogs/InviteInfoAuditLogModel.cs | 27 ++ .../API/AuditLogs/MemberInfoAuditLogModel.cs | 19 + .../API/AuditLogs/OnboardingAuditLogModel.cs | 15 + .../OnboardingPromptAuditLogModel.cs | 27 ++ .../API/AuditLogs/RoleInfoAuditLogModel.cs | 24 ++ .../ScheduledEventInfoAuditLogModel.cs | 43 +++ .../API/AuditLogs/StickerInfoAuditLogModel.cs | 15 + .../API/AuditLogs/ThreadInfoAuditLogModel.cs | 30 ++ .../API/AuditLogs/WebhookInfoAuditLogModel.cs | 18 + .../API/Common/ApplicationCommand.cs | 3 + src/Discord.Net.Rest/API/Common/AuditLog.cs | 9 + .../API/Common/AuditLogOptions.cs | 55 +-- src/Discord.Net.Rest/API/Common/Channel.cs | 2 +- .../API/Common/{ForumTags.cs => ForumTag.cs} | 2 +- .../Entities/AuditLogs/AuditLogHelper.cs | 171 +++++---- .../AutoModBlockedMessageAuditLogData.cs | 38 ++ .../AutoModFlaggedMessageAuditLogData.cs | 38 ++ .../AutoModRuleCreatedAuditLogData.cs | 31 ++ .../AutoModRuleDeletedAuditLogData.cs | 31 ++ .../AuditLogs/DataTypes/AutoModRuleInfo.cs | 113 ++++++ .../AutoModRuleUpdatedAuditLogData .cs | 45 +++ .../AutoModTimeoutUserAuditLogData.cs | 38 ++ .../AuditLogs/DataTypes/BanAuditLogData.cs | 51 ++- .../AuditLogs/DataTypes/BotAddAuditLogData.cs | 51 ++- .../DataTypes/ChannelCreateAuditLogData.cs | 256 ++++++++----- .../DataTypes/ChannelDeleteAuditLogData.cs | 251 ++++++++----- .../AuditLogs/DataTypes/ChannelInfo.cs | 94 ++++- .../DataTypes/ChannelUpdateAuditLogData.cs | 28 +- .../CommandPermissionUpdateAuditLogData.cs | 69 ++++ .../DataTypes/EmoteCreateAuditLogData.cs | 67 ++-- .../DataTypes/EmoteDeleteAuditLogData.cs | 68 ++-- .../DataTypes/EmoteUpdateAuditLogData.cs | 88 ++--- .../Entities/AuditLogs/DataTypes/GuildInfo.cs | 340 +++++++++++------- .../DataTypes/GuildUpdateAuditLogData.cs | 50 +-- .../IntegrationCreatedAuditLogData.cs | 39 ++ .../IntegrationDeletedAuditLogData.cs | 31 ++ .../AuditLogs/DataTypes/IntegrationInfo.cs | 69 ++++ .../IntegrationUpdatedAuditLogData.cs | 45 +++ .../DataTypes/InviteCreateAuditLogData.cs | 194 +++++----- .../DataTypes/InviteDeleteAuditLogData.cs | 194 +++++----- .../AuditLogs/DataTypes/InviteInfo.cs | 119 +++--- .../DataTypes/InviteUpdateAuditLogData.cs | 88 ++--- .../AuditLogs/DataTypes/KickAuditLogData.cs | 51 ++- .../DataTypes/MemberDisconnectAuditLogData.cs | 43 ++- .../AuditLogs/DataTypes/MemberInfo.cs | 92 +++-- .../DataTypes/MemberMoveAuditLogData.cs | 59 ++- .../DataTypes/MemberRoleAuditLogData.cs | 82 ++--- .../AuditLogs/DataTypes/MemberRoleEditInfo.cs | 69 ++-- .../DataTypes/MemberUpdateAuditLogData.cs | 108 +++--- .../MessageBulkDeleteAuditLogData.cs | 61 ++-- .../DataTypes/MessageDeleteAuditLogData.cs | 85 +++-- .../DataTypes/MessagePinAuditLogData.cs | 97 ++--- .../DataTypes/MessageUnpinAuditLogData.cs | 95 +++-- .../AuditLogs/DataTypes/OnboardingInfo.cs | 34 ++ .../OnboardingPromptCreatedAuditLogData.cs | 31 ++ .../DataTypes/OnboardingPromptInfo.cs | 56 +++ .../OnboardingPromptUpdatedAuditLogData.cs | 38 ++ .../OnboardingUpdatedAuditLogData.cs | 38 ++ .../DataTypes/OverwriteCreateAuditLogData.cs | 88 ++--- .../DataTypes/OverwriteDeleteAuditLogData.cs | 87 +++-- .../DataTypes/OverwriteUpdateAuditLogData.cs | 144 ++++---- .../AuditLogs/DataTypes/PruneAuditLogData.cs | 66 ++-- .../DataTypes/RoleCreateAuditLogData.cs | 91 ++--- .../DataTypes/RoleDeleteAuditLogData.cs | 90 ++--- .../AuditLogs/DataTypes/RoleEditInfo.cs | 132 ++++--- .../DataTypes/RoleUpdateAuditLogData.cs | 120 +++---- .../ScheduledEventCreateAuditLogData.cs | 227 +++++------- .../ScheduledEventDeleteAuditLogData.cs | 114 ++++-- .../AuditLogs/DataTypes/ScheduledEventInfo.cs | 145 ++++---- .../ScheduledEventUpdateAuditLogData.cs | 131 +++---- .../StageInstanceCreateAuditLogData.cs | 75 ++-- .../StageInstanceDeleteAuditLogData.cs | 75 ++-- .../StageInstanceUpdatedAuditLogData.cs | 71 ++-- .../DataTypes/StickerCreatedAuditLogData.cs | 29 ++ .../DataTypes/StickerDeletedAuditLogData.cs | 29 ++ .../AuditLogs/DataTypes/StickerInfo.cs | 31 ++ .../DataTypes/StickerUpdatedAuditLogData.cs | 35 ++ .../DataTypes/ThreadCreateAuditLogData.cs | 219 +++++------ .../DataTypes/ThreadDeleteAuditLogData.cs | 197 +++++----- .../AuditLogs/DataTypes/ThreadInfo.cs | 111 ++++-- .../DataTypes/ThreadUpdateAuditLogData.cs | 138 +++---- .../AuditLogs/DataTypes/UnbanAuditLogData.cs | 45 ++- .../DataTypes/WebhookCreateAuditLogData.cs | 154 ++++---- .../DataTypes/WebhookDeleteAuditLogData.cs | 132 ++++--- .../AuditLogs/DataTypes/WebhookInfo.cs | 73 ++-- .../DataTypes/WebhookUpdateAuditLogData.cs | 106 +++--- .../Entities/AuditLogs/JsonFieldAttribute.cs | 14 + .../Entities/AuditLogs/RestAuditLogEntry.cs | 2 +- .../Entities/Channels/RestForumChannel.cs | 2 +- .../Net/Converters/DiscordContractResolver.cs | 2 +- .../ApplicationCommandCreatedUpdatedEvent.cs | 2 - .../API/Gateway/AuditLogCreatedEvent.cs | 9 + .../BaseSocketClient.Events.cs | 15 + .../DiscordShardedClient.cs | 1 + .../DiscordSocketClient.cs | 20 ++ .../DiscordSocketConfig.cs | 6 + .../Entities/AuditLogs/AuditLogCache.cs | 83 +++++ ...SocketAutoModBlockedMessageAuditLogData.cs | 37 ++ ...SocketAutoModFlaggedMessageAuditLogData.cs | 37 ++ .../SocketAutoModRuleCreatedAuditLogData.cs | 30 ++ .../SocketAutoModRuleDeletedAuditLogData.cs | 30 ++ .../DataTypes/SocketAutoModRuleInfo.cs | 113 ++++++ .../SocketAutoModRuleUpdatedAuditLogData .cs | 36 ++ .../SocketAutoModTimeoutUserAuditLogData.cs | 37 ++ .../DataTypes/SocketBanAuditLogData.cs | 43 +++ .../DataTypes/SocketBotAddAuditLogData.cs | 42 +++ .../SocketChannelCreateAuditLogData.cs | 165 +++++++++ .../SocketChannelDeleteAuditLogData.cs | 182 ++++++++++ .../AuditLogs/DataTypes/SocketChannelInfo.cs | 142 ++++++++ .../SocketChannelUpdateAuditLogData.cs | 53 +++ ...cketCommandPermissionUpdateAuditLogData.cs | 63 ++++ .../SocketEmoteCreateAuditLogData.cs | 41 +++ .../SocketEmoteDeleteAuditLogData.cs | 41 +++ .../SocketEmoteUpdateAuditLogData.cs | 52 +++ .../AuditLogs/DataTypes/SocketGuildInfo.cs | 191 ++++++++++ .../SocketGuildUpdateAuditLogData.cs | 42 +++ .../SocketIntegrationCreatedAuditLogData.cs | 30 ++ .../SocketIntegrationDeletedAuditLogData.cs | 30 ++ .../DataTypes/SocketIntegrationInfo.cs | 69 ++++ .../SocketIntegrationUpdatedAuditLogData.cs | 36 ++ .../SocketInviteCreateAuditLogData.cs | 110 ++++++ .../SocketInviteDeleteAuditLogData.cs | 109 ++++++ .../AuditLogs/DataTypes/SocketInviteInfo.cs | 68 ++++ .../SocketInviteUpdateAuditLogData.cs | 42 +++ .../DataTypes/SocketKickAuditLogData.cs | 43 +++ .../SocketMemberDisconnectAuditLogData.cs | 27 ++ .../DataTypes/SocketMemberMoveAuditLogData.cs | 36 ++ .../DataTypes/SocketMemberRoleAuditLogData.cs | 58 +++ .../DataTypes/SocketMemberRoleEditInfo.cs | 36 ++ .../SocketMemberUpdateAuditLogData.cs | 65 ++++ .../SocketMessageBulkDeleteAuditLogData.cs | 37 ++ .../SocketMessageDeleteAuditLogData.cs | 62 ++++ .../DataTypes/SocketMessagePinAuditLogData.cs | 65 ++++ .../SocketMessageUnpinAuditLogData.cs | 64 ++++ .../DataTypes/SocketOnboardingInfo.cs | 35 ++ ...cketOnboardingPromptCreatedAuditLogData.cs | 30 ++ .../DataTypes/SocketOnboardingPromptInfo.cs | 56 +++ ...cketOnboardingPromptUpdatedAuditLogData.cs | 38 ++ .../SocketOnboardingUpdatedAuditLogData.cs | 37 ++ .../SocketOverwriteCreateAuditLogData.cs | 52 +++ .../SocketOverwriteDeleteAuditLogData.cs | 51 +++ .../SocketOverwriteUpdateAuditLogData.cs | 83 +++++ .../DataTypes/SocketPruneAuditLogData.cs | 39 ++ .../DataTypes/SocketRoleCreateAuditLogData.cs | 44 +++ .../DataTypes/SocketRoleDeleteAuditLogData.cs | 43 +++ .../AuditLogs/DataTypes/SocketRoleEditInfo.cs | 79 ++++ .../DataTypes/SocketRoleUpdateAuditLogData.cs | 51 +++ .../SocketScheduledEventCreateAuditLogData.cs | 88 +++++ .../SocketScheduledEventDeleteAuditLogData.cs | 97 +++++ .../DataTypes/SocketScheduledEventInfo.cs | 80 +++++ .../SocketScheduledEventUpdateAuditLogData.cs | 44 +++ .../AuditLogs/DataTypes/SocketStageInfo.cs | 23 ++ .../SocketStageInstanceCreateAuditLogData.cs | 41 +++ .../SocketStageInstanceDeleteAuditLogData.cs | 41 +++ .../SocketStageInstanceUpdatedAuditLogData.cs | 47 +++ .../SocketStickerCreatedAuditLogData.cs | 29 ++ .../SocketStickerDeletedAuditLogData.cs | 29 ++ .../AuditLogs/DataTypes/SocketStickerInfo.cs | 31 ++ .../SocketStickerUpdatedAuditLogData.cs | 35 ++ .../SocketThreadCreateAuditLogData.cs | 109 ++++++ .../SocketThreadDeleteAuditLogData.cs | 111 ++++++ .../AuditLogs/DataTypes/SocketThreadInfo.cs | 83 +++++ .../SocketThreadUpdateAuditLogData.cs | 51 +++ .../DataTypes/SocketUnbanAuditLogData.cs | 39 ++ .../SocketWebhookCreateAuditLogData.cs | 71 ++++ .../SocketWebhookDeleteAuditLogData.cs | 71 ++++ .../AuditLogs/DataTypes/SocketWebhookInfo.cs | 39 ++ .../SocketWebhookUpdateAuditLogData.cs | 44 +++ .../Entities/AuditLogs/ISocketAuditLogData.cs | 9 + .../Entities/AuditLogs/SocketAuditLogEntry.cs | 55 +++ .../AuditLogs/SocketAuditLogHelper.cs | 96 +++++ .../Entities/Channels/SocketForumChannel.cs | 2 +- .../Entities/Guilds/SocketGuild.cs | 32 +- 181 files changed, 8992 insertions(+), 2805 deletions(-) create mode 100644 src/Discord.Net.Core/Entities/AuditLogs/IAuditLogInfoModel.cs create mode 100644 src/Discord.Net.Rest/API/AuditLogs/AutoModRuleInfoAuditLogModel.cs create mode 100644 src/Discord.Net.Rest/API/AuditLogs/ChannelInfoAuditLogModel.cs create mode 100644 src/Discord.Net.Rest/API/AuditLogs/GuildInfoAuditLogModel.cs create mode 100644 src/Discord.Net.Rest/API/AuditLogs/IntegrationInfoAuditLogModel.cs create mode 100644 src/Discord.Net.Rest/API/AuditLogs/InviteInfoAuditLogModel.cs create mode 100644 src/Discord.Net.Rest/API/AuditLogs/MemberInfoAuditLogModel.cs create mode 100644 src/Discord.Net.Rest/API/AuditLogs/OnboardingAuditLogModel.cs create mode 100644 src/Discord.Net.Rest/API/AuditLogs/OnboardingPromptAuditLogModel.cs create mode 100644 src/Discord.Net.Rest/API/AuditLogs/RoleInfoAuditLogModel.cs create mode 100644 src/Discord.Net.Rest/API/AuditLogs/ScheduledEventInfoAuditLogModel.cs create mode 100644 src/Discord.Net.Rest/API/AuditLogs/StickerInfoAuditLogModel.cs create mode 100644 src/Discord.Net.Rest/API/AuditLogs/ThreadInfoAuditLogModel.cs create mode 100644 src/Discord.Net.Rest/API/AuditLogs/WebhookInfoAuditLogModel.cs rename src/Discord.Net.Rest/API/Common/{ForumTags.cs => ForumTag.cs} (95%) create mode 100644 src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/AutoModBlockedMessageAuditLogData.cs create mode 100644 src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/AutoModFlaggedMessageAuditLogData.cs create mode 100644 src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/AutoModRuleCreatedAuditLogData.cs create mode 100644 src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/AutoModRuleDeletedAuditLogData.cs create mode 100644 src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/AutoModRuleInfo.cs create mode 100644 src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/AutoModRuleUpdatedAuditLogData .cs create mode 100644 src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/AutoModTimeoutUserAuditLogData.cs create mode 100644 src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/CommandPermissionUpdateAuditLogData.cs create mode 100644 src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/IntegrationCreatedAuditLogData.cs create mode 100644 src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/IntegrationDeletedAuditLogData.cs create mode 100644 src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/IntegrationInfo.cs create mode 100644 src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/IntegrationUpdatedAuditLogData.cs create mode 100644 src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OnboardingInfo.cs create mode 100644 src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OnboardingPromptCreatedAuditLogData.cs create mode 100644 src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OnboardingPromptInfo.cs create mode 100644 src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OnboardingPromptUpdatedAuditLogData.cs create mode 100644 src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OnboardingUpdatedAuditLogData.cs create mode 100644 src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/StickerCreatedAuditLogData.cs create mode 100644 src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/StickerDeletedAuditLogData.cs create mode 100644 src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/StickerInfo.cs create mode 100644 src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/StickerUpdatedAuditLogData.cs create mode 100644 src/Discord.Net.Rest/Entities/AuditLogs/JsonFieldAttribute.cs create mode 100644 src/Discord.Net.WebSocket/API/Gateway/AuditLogCreatedEvent.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/AuditLogCache.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketAutoModBlockedMessageAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketAutoModFlaggedMessageAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketAutoModRuleCreatedAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketAutoModRuleDeletedAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketAutoModRuleInfo.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketAutoModRuleUpdatedAuditLogData .cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketAutoModTimeoutUserAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketBanAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketBotAddAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketChannelCreateAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketChannelDeleteAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketChannelInfo.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketChannelUpdateAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketCommandPermissionUpdateAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketEmoteCreateAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketEmoteDeleteAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketEmoteUpdateAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketGuildInfo.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketGuildUpdateAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketIntegrationCreatedAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketIntegrationDeletedAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketIntegrationInfo.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketIntegrationUpdatedAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketInviteCreateAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketInviteDeleteAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketInviteInfo.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketInviteUpdateAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketKickAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketMemberDisconnectAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketMemberMoveAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketMemberRoleAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketMemberRoleEditInfo.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketMemberUpdateAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketMessageBulkDeleteAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketMessageDeleteAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketMessagePinAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketMessageUnpinAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketOnboardingInfo.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketOnboardingPromptCreatedAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketOnboardingPromptInfo.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketOnboardingPromptUpdatedAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketOnboardingUpdatedAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketOverwriteCreateAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketOverwriteDeleteAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketOverwriteUpdateAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketPruneAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketRoleCreateAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketRoleDeleteAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketRoleEditInfo.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketRoleUpdateAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketScheduledEventCreateAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketScheduledEventDeleteAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketScheduledEventInfo.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketScheduledEventUpdateAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketStageInfo.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketStageInstanceCreateAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketStageInstanceDeleteAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketStageInstanceUpdatedAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketStickerCreatedAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketStickerDeletedAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketStickerInfo.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketStickerUpdatedAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketThreadCreateAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketThreadDeleteAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketThreadInfo.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketThreadUpdateAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketUnbanAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketWebhookCreateAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketWebhookDeleteAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketWebhookInfo.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketWebhookUpdateAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/ISocketAuditLogData.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/SocketAuditLogEntry.cs create mode 100644 src/Discord.Net.WebSocket/Entities/AuditLogs/SocketAuditLogHelper.cs diff --git a/src/Discord.Net.Core/Entities/AuditLogs/ActionType.cs b/src/Discord.Net.Core/Entities/AuditLogs/ActionType.cs index ad2d659e..a7e4efaa 100644 --- a/src/Discord.Net.Core/Entities/AuditLogs/ActionType.cs +++ b/src/Discord.Net.Core/Entities/AuditLogs/ActionType.cs @@ -205,6 +205,50 @@ namespace Discord /// /// A thread was deleted. /// - ThreadDelete = 112 + ThreadDelete = 112, + /// + /// Permissions were updated for a command. + /// + ApplicationCommandPermissionUpdate = 121, + + /// + /// Auto Moderation rule was created. + /// + AutoModerationRuleCreate = 140, + /// + /// Auto Moderation rule was updated. + /// + AutoModerationRuleUpdate = 141, + /// + /// Auto Moderation rule was deleted. + /// + AutoModerationRuleDelete = 142, + /// + /// Message was blocked by Auto Moderation. + /// + AutoModerationBlockMessage = 143, + /// + /// Message was flagged by Auto Moderation. + /// + AutoModerationFlagToChannel = 144, + /// + /// Member was timed out by Auto Moderation. + /// + AutoModerationUserCommunicationDisabled = 145, + + /// + /// Guild Onboarding Question was created. + /// + OnboardingQuestionCreated = 163, + + /// + /// Guild Onboarding Question was updated. + /// + OnboardingQuestionUpdated = 164, + + /// + /// Guild Onboarding was updated. + /// + OnboardingUpdated = 167 } } diff --git a/src/Discord.Net.Core/Entities/AuditLogs/IAuditLogInfoModel.cs b/src/Discord.Net.Core/Entities/AuditLogs/IAuditLogInfoModel.cs new file mode 100644 index 00000000..880c6e37 --- /dev/null +++ b/src/Discord.Net.Core/Entities/AuditLogs/IAuditLogInfoModel.cs @@ -0,0 +1,6 @@ +namespace Discord; + +public interface IAuditLogInfoModel +{ + +} diff --git a/src/Discord.Net.Core/Entities/Channels/ThreadArchiveDuration.cs b/src/Discord.Net.Core/Entities/Channels/ThreadArchiveDuration.cs index 2c8a0652..6c1b7a4c 100644 --- a/src/Discord.Net.Core/Entities/Channels/ThreadArchiveDuration.cs +++ b/src/Discord.Net.Core/Entities/Channels/ThreadArchiveDuration.cs @@ -17,17 +17,11 @@ namespace Discord /// /// Three days (4320 minutes). - /// - /// This option is explicitly available to nitro users. - /// /// ThreeDays = 4320, /// /// One week (10080 minutes). - /// - /// This option is explicitly available to nitro users. - /// /// OneWeek = 10080 } diff --git a/src/Discord.Net.Core/Entities/Guilds/IGuild.cs b/src/Discord.Net.Core/Entities/Guilds/IGuild.cs index 97ee481b..aec5bff1 100644 --- a/src/Discord.Net.Core/Entities/Guilds/IGuild.cs +++ b/src/Discord.Net.Core/Entities/Guilds/IGuild.cs @@ -7,6 +7,8 @@ using System.Threading.Tasks; namespace Discord { + // when adding properties to guilds please check if they are returned in audit log events and add them to the + // 'GuildInfo.cs' file for socket and rest audit logs. /// /// Represents a generic guild/server. /// diff --git a/src/Discord.Net.Rest/API/AuditLogs/AutoModRuleInfoAuditLogModel.cs b/src/Discord.Net.Rest/API/AuditLogs/AutoModRuleInfoAuditLogModel.cs new file mode 100644 index 00000000..452ff07f --- /dev/null +++ b/src/Discord.Net.Rest/API/AuditLogs/AutoModRuleInfoAuditLogModel.cs @@ -0,0 +1,30 @@ +using Discord.Rest; + +namespace Discord.API.AuditLogs; + +internal class AutoModRuleInfoAuditLogModel : IAuditLogInfoModel +{ + [JsonField("name")] + public string Name { get; set; } + + [JsonField("event_type")] + public AutoModEventType EventType { get; set; } + + [JsonField("trigger_type")] + public AutoModTriggerType TriggerType { get; set; } + + [JsonField("trigger_metadata")] + public TriggerMetadata TriggerMetadata { get; set; } + + [JsonField("actions")] + public AutoModAction[] Actions { get; set; } + + [JsonField("enabled")] + public bool Enabled { get; set; } + + [JsonField("exempt_roles")] + public ulong[] ExemptRoles { get; set; } + + [JsonField("exempt_channels")] + public ulong[] ExemptChannels { get; set; } +} diff --git a/src/Discord.Net.Rest/API/AuditLogs/ChannelInfoAuditLogModel.cs b/src/Discord.Net.Rest/API/AuditLogs/ChannelInfoAuditLogModel.cs new file mode 100644 index 00000000..75f04710 --- /dev/null +++ b/src/Discord.Net.Rest/API/AuditLogs/ChannelInfoAuditLogModel.cs @@ -0,0 +1,57 @@ +using Discord.Rest; + +namespace Discord.API.AuditLogs; + +internal class ChannelInfoAuditLogModel : IAuditLogInfoModel +{ + [JsonField("name")] + public string Name { get; set; } + + [JsonField("type")] + public ChannelType? Type { get; set; } + + [JsonField("permission_overwrites")] + public Overwrite[] Overwrites { get; set; } + + [JsonField("flags")] + public ChannelFlags? Flags { get; set; } + + [JsonField("default_thread_rate_limit_per_user")] + public int? DefaultThreadRateLimitPerUser { get; set; } + + [JsonField("default_auto_archive_duration")] + public ThreadArchiveDuration? DefaultArchiveDuration { get; set; } + + [JsonField("rate_limit_per_user")] + public int? RateLimitPerUser { get; set; } + + [JsonField("auto_archive_duration")] + public ThreadArchiveDuration? AutoArchiveDuration { get; set; } + + [JsonField("nsfw")] + public bool? IsNsfw { get; set; } + + [JsonField("topic")] + public string Topic { get; set; } + + // Forum channels + [JsonField("available_tags")] + public ForumTag[] AvailableTags { get; set; } + + [JsonField("default_reaction_emoji")] + public ForumReactionEmoji DefaultEmoji { get; set; } + + // Voice channels + + [JsonField("user_limit")] + public int? UserLimit { get; set; } + + [JsonField("rtc_region")] + public string Region { get; set; } + + [JsonField("video_quality_mode")] + public VideoQualityMode? VideoQualityMode { get; set; } + + [JsonField("bitrate")] + public int? Bitrate { get; set; } +} diff --git a/src/Discord.Net.Rest/API/AuditLogs/GuildInfoAuditLogModel.cs b/src/Discord.Net.Rest/API/AuditLogs/GuildInfoAuditLogModel.cs new file mode 100644 index 00000000..fd4a85fb --- /dev/null +++ b/src/Discord.Net.Rest/API/AuditLogs/GuildInfoAuditLogModel.cs @@ -0,0 +1,82 @@ +using Discord.Rest; + +namespace Discord.API.AuditLogs; + +public class GuildInfoAuditLogModel : IAuditLogInfoModel +{ + [JsonField("name")] + public string Name { get; set; } + + [JsonField("afk_timeout")] + public int? AfkTimeout { get; set; } + + [JsonField("widget_enabled")] + public bool? IsEmbeddable { get; set; } + + [JsonField("default_message_notifications")] + public DefaultMessageNotifications? DefaultMessageNotifications { get; set; } + + [JsonField("mfa_level")] + public MfaLevel? MfaLevel { get; set; } + + [JsonField("verification_level")] + public VerificationLevel? VerificationLevel { get; set; } + + [JsonField("explicit_content_filter")] + public ExplicitContentFilterLevel? ExplicitContentFilterLevel { get; set; } + + [JsonField("icon_hash")] + public string IconHash { get; set; } + + [JsonField("discovery_splash")] + public string DiscoverySplash { get; set; } + + [JsonField("splash")] + public string Splash { get; set; } + + [JsonField("afk_channel_id")] + public ulong? AfkChannelId { get; set; } + + [JsonField("widget_channel_id")] + public ulong? EmbeddedChannelId { get; set; } + + [JsonField("system_channel_id")] + public ulong? SystemChannelId { get; set; } + + [JsonField("rules_channel_id")] + public ulong? RulesChannelId { get; set; } + + [JsonField("public_updates_channel_id")] + public ulong? PublicUpdatesChannelId { get; set; } + + [JsonField("owner_id")] + public ulong? OwnerId { get; set; } + + [JsonField("application_id")] + public ulong? ApplicationId { get; set; } + + [JsonField("region")] + public string RegionId { get; set; } + + [JsonField("banner")] + public string Banner { get; set; } + + [JsonField("vanity_url_code")] + public string VanityUrl { get; set; } + + [JsonField("system_channel_flags")] + public SystemChannelMessageDeny? SystemChannelFlags { get; set; } + + [JsonField("description")] + public string Description { get; set; } + + [JsonField("preferred_locale")] + public string PreferredLocale { get; set; } + + [JsonField("nsfw_level")] + public NsfwLevel? NsfwLevel { get; set; } + + [JsonField("premium_progress_bar_enabled")] + public bool? ProgressBarEnabled { get; set; } + +} diff --git a/src/Discord.Net.Rest/API/AuditLogs/IntegrationInfoAuditLogModel.cs b/src/Discord.Net.Rest/API/AuditLogs/IntegrationInfoAuditLogModel.cs new file mode 100644 index 00000000..f63ab96d --- /dev/null +++ b/src/Discord.Net.Rest/API/AuditLogs/IntegrationInfoAuditLogModel.cs @@ -0,0 +1,33 @@ +using Discord.Rest; + +namespace Discord.API.AuditLogs; + +internal class IntegrationInfoAuditLogModel : IAuditLogInfoModel +{ + [JsonField("name")] + public string Name { get; set; } + + [JsonField("type")] + public string Type { get; set; } + + [JsonField("enabled")] + public bool? Enabled { get; set; } + + [JsonField("syncing")] + public bool? Syncing { get; set; } + + [JsonField("role_id")] + public ulong? RoleId { get; set; } + + [JsonField("enable_emoticons")] + public bool? EnableEmojis { get; set; } + + [JsonField("expire_behavior")] + public IntegrationExpireBehavior? ExpireBehavior { get; set; } + + [JsonField("expire_grace_period")] + public int? ExpireGracePeriod { get; set; } + + [JsonField("scopes")] + public string[] Scopes { get; set; } +} diff --git a/src/Discord.Net.Rest/API/AuditLogs/InviteInfoAuditLogModel.cs b/src/Discord.Net.Rest/API/AuditLogs/InviteInfoAuditLogModel.cs new file mode 100644 index 00000000..836d4ed2 --- /dev/null +++ b/src/Discord.Net.Rest/API/AuditLogs/InviteInfoAuditLogModel.cs @@ -0,0 +1,27 @@ +using Discord.Rest; + +namespace Discord.API.AuditLogs; + +internal class InviteInfoAuditLogModel : IAuditLogInfoModel +{ + [JsonField("code")] + public string Code { get; set; } + + [JsonField("channel_id")] + public ulong? ChannelId { get; set; } + + [JsonField("inviter_id")] + public ulong? InviterId { get; set; } + + [JsonField("uses")] + public int? Uses { get; set; } + + [JsonField("max_uses")] + public int? MaxUses { get; set; } + + [JsonField("max_age")] + public int? MaxAge { get; set; } + + [JsonField("temporary")] + public bool? Temporary { get; set; } +} diff --git a/src/Discord.Net.Rest/API/AuditLogs/MemberInfoAuditLogModel.cs b/src/Discord.Net.Rest/API/AuditLogs/MemberInfoAuditLogModel.cs new file mode 100644 index 00000000..f81cea2e --- /dev/null +++ b/src/Discord.Net.Rest/API/AuditLogs/MemberInfoAuditLogModel.cs @@ -0,0 +1,19 @@ +using Discord.Rest; +using System; + +namespace Discord.API.AuditLogs; + +internal class MemberInfoAuditLogModel : IAuditLogInfoModel +{ + [JsonField("nick")] + public string Nickname { get; set; } + + [JsonField("mute")] + public bool? IsMuted { get; set; } + + [JsonField("deaf")] + public bool? IsDeafened { get; set; } + + [JsonField("communication_disabled_until")] + public DateTimeOffset? TimeOutUntil { get; set; } +} diff --git a/src/Discord.Net.Rest/API/AuditLogs/OnboardingAuditLogModel.cs b/src/Discord.Net.Rest/API/AuditLogs/OnboardingAuditLogModel.cs new file mode 100644 index 00000000..5b36734a --- /dev/null +++ b/src/Discord.Net.Rest/API/AuditLogs/OnboardingAuditLogModel.cs @@ -0,0 +1,15 @@ +using Discord.Rest; + +namespace Discord.API.AuditLogs; + +internal class OnboardingAuditLogModel : IAuditLogInfoModel +{ + [JsonField("default_channel_ids")] + public ulong[] DefaultChannelIds { get; set; } + + [JsonField("prompts")] + public GuildOnboardingPrompt[] Prompts { get; set; } + + [JsonField("enabled")] + public bool? Enabled { get; set; } +} diff --git a/src/Discord.Net.Rest/API/AuditLogs/OnboardingPromptAuditLogModel.cs b/src/Discord.Net.Rest/API/AuditLogs/OnboardingPromptAuditLogModel.cs new file mode 100644 index 00000000..31eea7f9 --- /dev/null +++ b/src/Discord.Net.Rest/API/AuditLogs/OnboardingPromptAuditLogModel.cs @@ -0,0 +1,27 @@ +using Discord.Rest; + +namespace Discord.API.AuditLogs; + +internal class OnboardingPromptAuditLogModel : IAuditLogInfoModel +{ + [JsonField("id")] + public ulong? Id { get; set; } + + [JsonField("title")] + public string Title { get; set; } + + [JsonField("options")] + public GuildOnboardingPromptOption[] Options { get; set; } + + [JsonField("single_select")] + public bool? IsSingleSelect { get; set; } + + [JsonField("required")] + public bool? IsRequired { get; set; } + + [JsonField("in_onboarding")] + public bool? IsInOnboarding { get; set; } + + [JsonField("type")] + public GuildOnboardingPromptType? Type { get; set; } +} diff --git a/src/Discord.Net.Rest/API/AuditLogs/RoleInfoAuditLogModel.cs b/src/Discord.Net.Rest/API/AuditLogs/RoleInfoAuditLogModel.cs new file mode 100644 index 00000000..351a4eee --- /dev/null +++ b/src/Discord.Net.Rest/API/AuditLogs/RoleInfoAuditLogModel.cs @@ -0,0 +1,24 @@ +using Discord.Rest; + +namespace Discord.API.AuditLogs; + +internal class RoleInfoAuditLogModel : IAuditLogInfoModel +{ + [JsonField("name")] + public string Name { get; set; } + + [JsonField("color")] + public uint? Color { get; set; } + + [JsonField("hoist")] + public bool? Hoist { get; set; } + + [JsonField("permissions")] + public ulong? Permissions { get; set; } + + [JsonField("mentionable")] + public bool? IsMentionable { get; set; } + + [JsonField("icon_hash")] + public string IconHash { get; set; } +} diff --git a/src/Discord.Net.Rest/API/AuditLogs/ScheduledEventInfoAuditLogModel.cs b/src/Discord.Net.Rest/API/AuditLogs/ScheduledEventInfoAuditLogModel.cs new file mode 100644 index 00000000..a8f27626 --- /dev/null +++ b/src/Discord.Net.Rest/API/AuditLogs/ScheduledEventInfoAuditLogModel.cs @@ -0,0 +1,43 @@ +using Discord.Rest; +using System; + +namespace Discord.API.AuditLogs; + +internal class ScheduledEventInfoAuditLogModel : IAuditLogInfoModel +{ + [JsonField("channel_id")] + public ulong? ChannelId { get; set; } + + [JsonField("name")] + public string Name { get; set; } + + [JsonField("description")] + public string Description { get; set; } + + [JsonField("scheduled_start_time")] + public DateTimeOffset? StartTime { get; set; } + + [JsonField("scheduled_end_time")] + public DateTimeOffset? EndTime { get; set; } + + [JsonField("privacy_level")] + public GuildScheduledEventPrivacyLevel? PrivacyLevel { get; set; } + + [JsonField("status")] + public GuildScheduledEventStatus? EventStatus { get; set; } + + [JsonField("entity_type")] + public GuildScheduledEventType? EventType { get; set; } + + [JsonField("entity_id")] + public ulong? EntityId { get; set; } + + [JsonField("user_count")] + public int? UserCount { get; set; } + + [JsonField("location")] + public string Location { get; set; } + + [JsonField("image")] + public string Image { get; set; } +} diff --git a/src/Discord.Net.Rest/API/AuditLogs/StickerInfoAuditLogModel.cs b/src/Discord.Net.Rest/API/AuditLogs/StickerInfoAuditLogModel.cs new file mode 100644 index 00000000..38686743 --- /dev/null +++ b/src/Discord.Net.Rest/API/AuditLogs/StickerInfoAuditLogModel.cs @@ -0,0 +1,15 @@ +using Discord.Rest; + +namespace Discord.API.AuditLogs; + +internal class StickerInfoAuditLogModel : IAuditLogInfoModel +{ + [JsonField("name")] + public string Name { get; set; } + + [JsonField("tags")] + public string Tags { get; set; } + + [JsonField("description")] + public string Description { get; set; } +} diff --git a/src/Discord.Net.Rest/API/AuditLogs/ThreadInfoAuditLogModel.cs b/src/Discord.Net.Rest/API/AuditLogs/ThreadInfoAuditLogModel.cs new file mode 100644 index 00000000..5215d586 --- /dev/null +++ b/src/Discord.Net.Rest/API/AuditLogs/ThreadInfoAuditLogModel.cs @@ -0,0 +1,30 @@ +using Discord.Rest; + +namespace Discord.API.AuditLogs; + +internal class ThreadInfoAuditLogModel : IAuditLogInfoModel +{ + [JsonField("name")] + public string Name { get; set; } + + [JsonField("type")] + public ThreadType Type { get; set; } + + [JsonField("archived")] + public bool? IsArchived { get; set; } + + [JsonField("locked")] + public bool? IsLocked { get; set;} + + [JsonField("auto_archive_duration")] + public ThreadArchiveDuration? ArchiveDuration { get; set; } + + [JsonField("rate_limit_per_user")] + public int? SlowModeInterval { get; set; } + + [JsonField("flags")] + public ChannelFlags? ChannelFlags { get; set; } + + [JsonField("applied_tags")] + public ulong[] AppliedTags { get; set; } +} diff --git a/src/Discord.Net.Rest/API/AuditLogs/WebhookInfoAuditLogModel.cs b/src/Discord.Net.Rest/API/AuditLogs/WebhookInfoAuditLogModel.cs new file mode 100644 index 00000000..e8d8a193 --- /dev/null +++ b/src/Discord.Net.Rest/API/AuditLogs/WebhookInfoAuditLogModel.cs @@ -0,0 +1,18 @@ +using Discord.Rest; + +namespace Discord.API.AuditLogs; + +internal class WebhookInfoAuditLogModel : IAuditLogInfoModel +{ + [JsonField("channel_id")] + public ulong? ChannelId { get; set; } + + [JsonField("name")] + public string Name { get; set; } + + [JsonField("type")] + public WebhookType? Type { get; set; } + + [JsonField("avatar_hash")] + public string AvatarHash { get; set; } +} diff --git a/src/Discord.Net.Rest/API/Common/ApplicationCommand.cs b/src/Discord.Net.Rest/API/Common/ApplicationCommand.cs index 40bd0c1b..1b27e6e7 100644 --- a/src/Discord.Net.Rest/API/Common/ApplicationCommand.cs +++ b/src/Discord.Net.Rest/API/Common/ApplicationCommand.cs @@ -14,6 +14,9 @@ namespace Discord.API [JsonProperty("application_id")] public ulong ApplicationId { get; set; } + [JsonProperty("guild_id")] + public Optional GuildId { get; set; } + [JsonProperty("name")] public string Name { get; set; } diff --git a/src/Discord.Net.Rest/API/Common/AuditLog.cs b/src/Discord.Net.Rest/API/Common/AuditLog.cs index c8bd6d3e..f6264efd 100644 --- a/src/Discord.Net.Rest/API/Common/AuditLog.cs +++ b/src/Discord.Net.Rest/API/Common/AuditLog.cs @@ -18,5 +18,14 @@ namespace Discord.API [JsonProperty("audit_log_entries")] public AuditLogEntry[] Entries { get; set; } + + [JsonProperty("application_commands")] + public ApplicationCommand[] Commands { get; set; } + + [JsonProperty("auto_moderation_rules")] + public AutoModerationRule[] AutoModerationRules { get; set;} + + [JsonProperty("guild_scheduled_events")] + public GuildScheduledEvent[] GuildScheduledEvents { get; set; } } } diff --git a/src/Discord.Net.Rest/API/Common/AuditLogOptions.cs b/src/Discord.Net.Rest/API/Common/AuditLogOptions.cs index 1b0144cf..f91c6d32 100644 --- a/src/Discord.Net.Rest/API/Common/AuditLogOptions.cs +++ b/src/Discord.Net.Rest/API/Common/AuditLogOptions.cs @@ -1,28 +1,39 @@ using Newtonsoft.Json; -namespace Discord.API +namespace Discord.API; + +internal class AuditLogOptions { - internal class AuditLogOptions - { - [JsonProperty("count")] - public int? Count { get; set; } - [JsonProperty("channel_id")] - public ulong? ChannelId { get; set; } - [JsonProperty("message_id")] - public ulong? MessageId { get; set; } + [JsonProperty("count")] + public int? Count { get; set; } + [JsonProperty("channel_id")] + public ulong? ChannelId { get; set; } + [JsonProperty("message_id")] + public ulong? MessageId { get; set; } - //Prune - [JsonProperty("delete_member_days")] - public int? PruneDeleteMemberDays { get; set; } - [JsonProperty("members_removed")] - public int? PruneMembersRemoved { get; set; } + //Prune + [JsonProperty("delete_member_days")] + public int? PruneDeleteMemberDays { get; set; } + [JsonProperty("members_removed")] + public int? PruneMembersRemoved { get; set; } - //Overwrite Update - [JsonProperty("role_name")] - public string OverwriteRoleName { get; set; } - [JsonProperty("type")] - public PermissionTarget OverwriteType { get; set; } - [JsonProperty("id")] - public ulong? OverwriteTargetId { get; set; } - } + //Overwrite Update + [JsonProperty("role_name")] + public string OverwriteRoleName { get; set; } + [JsonProperty("type")] + public PermissionTarget OverwriteType { get; set; } + [JsonProperty("id")] + public ulong? OverwriteTargetId { get; set; } + + // App command perm update + [JsonProperty("application_id")] + public ulong? ApplicationId { get; set; } + + // Automod + + [JsonProperty("auto_moderation_rule_name")] + public string AutoModRuleName { get; set; } + + [JsonProperty("auto_moderation_rule_trigger_type")] + public AutoModTriggerType? AutoModRuleTriggerType { get; set; } } diff --git a/src/Discord.Net.Rest/API/Common/Channel.cs b/src/Discord.Net.Rest/API/Common/Channel.cs index 8ceaf2b0..bbfe432e 100644 --- a/src/Discord.Net.Rest/API/Common/Channel.cs +++ b/src/Discord.Net.Rest/API/Common/Channel.cs @@ -72,7 +72,7 @@ namespace Discord.API //ForumChannel [JsonProperty("available_tags")] - public Optional ForumTags { get; set; } + public Optional ForumTags { get; set; } [JsonProperty("applied_tags")] public Optional AppliedTags { get; set; } diff --git a/src/Discord.Net.Rest/API/Common/ForumTags.cs b/src/Discord.Net.Rest/API/Common/ForumTag.cs similarity index 95% rename from src/Discord.Net.Rest/API/Common/ForumTags.cs rename to src/Discord.Net.Rest/API/Common/ForumTag.cs index c4a1fa2a..d287bcbf 100644 --- a/src/Discord.Net.Rest/API/Common/ForumTags.cs +++ b/src/Discord.Net.Rest/API/Common/ForumTag.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace Discord.API { - internal class ForumTags + internal class ForumTag { [JsonProperty("id")] public ulong Id { get; set; } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/AuditLogHelper.cs b/src/Discord.Net.Rest/Entities/AuditLogs/AuditLogHelper.cs index 2b850924..8bc431ed 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/AuditLogHelper.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/AuditLogHelper.cs @@ -1,71 +1,122 @@ using System; using System.Collections.Generic; +using System.Linq; + +using AuditLogChange = Discord.API.AuditLogChange; using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +internal static class AuditLogHelper { - internal static class AuditLogHelper - { - private static readonly Dictionary> CreateMapping - = new Dictionary>() - { - [ActionType.GuildUpdated] = GuildUpdateAuditLogData.Create, - - [ActionType.ChannelCreated] = ChannelCreateAuditLogData.Create, - [ActionType.ChannelUpdated] = ChannelUpdateAuditLogData.Create, - [ActionType.ChannelDeleted] = ChannelDeleteAuditLogData.Create, - - [ActionType.OverwriteCreated] = OverwriteCreateAuditLogData.Create, - [ActionType.OverwriteUpdated] = OverwriteUpdateAuditLogData.Create, - [ActionType.OverwriteDeleted] = OverwriteDeleteAuditLogData.Create, - - [ActionType.Kick] = KickAuditLogData.Create, - [ActionType.Prune] = PruneAuditLogData.Create, - [ActionType.Ban] = BanAuditLogData.Create, - [ActionType.Unban] = UnbanAuditLogData.Create, - [ActionType.MemberUpdated] = MemberUpdateAuditLogData.Create, - [ActionType.MemberRoleUpdated] = MemberRoleAuditLogData.Create, - [ActionType.MemberMoved] = MemberMoveAuditLogData.Create, - [ActionType.MemberDisconnected] = MemberDisconnectAuditLogData.Create, - [ActionType.BotAdded] = BotAddAuditLogData.Create, - - [ActionType.RoleCreated] = RoleCreateAuditLogData.Create, - [ActionType.RoleUpdated] = RoleUpdateAuditLogData.Create, - [ActionType.RoleDeleted] = RoleDeleteAuditLogData.Create, - - [ActionType.InviteCreated] = InviteCreateAuditLogData.Create, - [ActionType.InviteUpdated] = InviteUpdateAuditLogData.Create, - [ActionType.InviteDeleted] = InviteDeleteAuditLogData.Create, - - [ActionType.WebhookCreated] = WebhookCreateAuditLogData.Create, - [ActionType.WebhookUpdated] = WebhookUpdateAuditLogData.Create, - [ActionType.WebhookDeleted] = WebhookDeleteAuditLogData.Create, - - [ActionType.EmojiCreated] = EmoteCreateAuditLogData.Create, - [ActionType.EmojiUpdated] = EmoteUpdateAuditLogData.Create, - [ActionType.EmojiDeleted] = EmoteDeleteAuditLogData.Create, - - [ActionType.MessageDeleted] = MessageDeleteAuditLogData.Create, - [ActionType.MessageBulkDeleted] = MessageBulkDeleteAuditLogData.Create, - [ActionType.MessagePinned] = MessagePinAuditLogData.Create, - [ActionType.MessageUnpinned] = MessageUnpinAuditLogData.Create, - - [ActionType.EventCreate] = ScheduledEventCreateAuditLogData.Create, - [ActionType.EventUpdate] = ScheduledEventUpdateAuditLogData.Create, - [ActionType.EventDelete] = ScheduledEventDeleteAuditLogData.Create, - - [ActionType.ThreadCreate] = ThreadCreateAuditLogData.Create, - [ActionType.ThreadUpdate] = ThreadUpdateAuditLogData.Create, - [ActionType.ThreadDelete] = ThreadDeleteAuditLogData.Create, - }; - - public static IAuditLogData CreateData(BaseDiscordClient discord, Model log, EntryModel entry) + private static readonly Dictionary> CreateMapping + = new () { - if (CreateMapping.TryGetValue(entry.Action, out var func)) - return func(discord, log, entry); + [ActionType.GuildUpdated] = GuildUpdateAuditLogData.Create, // log + [ActionType.ChannelCreated] = ChannelCreateAuditLogData.Create, + [ActionType.ChannelUpdated] = ChannelUpdateAuditLogData.Create, + [ActionType.ChannelDeleted] = ChannelDeleteAuditLogData.Create, - return null; + [ActionType.OverwriteCreated] = OverwriteCreateAuditLogData.Create, + [ActionType.OverwriteUpdated] = OverwriteUpdateAuditLogData.Create, + [ActionType.OverwriteDeleted] = OverwriteDeleteAuditLogData.Create, + + [ActionType.Kick] = KickAuditLogData.Create, + [ActionType.Prune] = PruneAuditLogData.Create, + [ActionType.Ban] = BanAuditLogData.Create, + [ActionType.Unban] = UnbanAuditLogData.Create, + [ActionType.MemberUpdated] = MemberUpdateAuditLogData.Create, + [ActionType.MemberRoleUpdated] = MemberRoleAuditLogData.Create, + [ActionType.MemberMoved] = MemberMoveAuditLogData.Create, + [ActionType.MemberDisconnected] = MemberDisconnectAuditLogData.Create, + [ActionType.BotAdded] = BotAddAuditLogData.Create, + + [ActionType.RoleCreated] = RoleCreateAuditLogData.Create, + [ActionType.RoleUpdated] = RoleUpdateAuditLogData.Create, + [ActionType.RoleDeleted] = RoleDeleteAuditLogData.Create, + + [ActionType.InviteCreated] = InviteCreateAuditLogData.Create, + [ActionType.InviteUpdated] = InviteUpdateAuditLogData.Create, + [ActionType.InviteDeleted] = InviteDeleteAuditLogData.Create, + + [ActionType.WebhookCreated] = WebhookCreateAuditLogData.Create, + [ActionType.WebhookUpdated] = WebhookUpdateAuditLogData.Create, + [ActionType.WebhookDeleted] = WebhookDeleteAuditLogData.Create, + + [ActionType.EmojiCreated] = EmoteCreateAuditLogData.Create, + [ActionType.EmojiUpdated] = EmoteUpdateAuditLogData.Create, + [ActionType.EmojiDeleted] = EmoteDeleteAuditLogData.Create, + + [ActionType.MessageDeleted] = MessageDeleteAuditLogData.Create, + [ActionType.MessageBulkDeleted] = MessageBulkDeleteAuditLogData.Create, + [ActionType.MessagePinned] = MessagePinAuditLogData.Create, + [ActionType.MessageUnpinned] = MessageUnpinAuditLogData.Create, + + [ActionType.EventCreate] = ScheduledEventCreateAuditLogData.Create, + [ActionType.EventUpdate] = ScheduledEventUpdateAuditLogData.Create, + [ActionType.EventDelete] = ScheduledEventDeleteAuditLogData.Create, + + [ActionType.ThreadCreate] = ThreadCreateAuditLogData.Create, + [ActionType.ThreadUpdate] = ThreadUpdateAuditLogData.Create, + [ActionType.ThreadDelete] = ThreadDeleteAuditLogData.Create, + + [ActionType.ApplicationCommandPermissionUpdate] = CommandPermissionUpdateAuditLogData.Create, + + [ActionType.IntegrationCreated] = IntegrationCreatedAuditLogData.Create, + [ActionType.IntegrationUpdated] = IntegrationUpdatedAuditLogData.Create, + [ActionType.IntegrationDeleted] = IntegrationDeletedAuditLogData.Create, + + [ActionType.StageInstanceCreated] = StageInstanceCreateAuditLogData.Create, + [ActionType.StageInstanceUpdated] = StageInstanceUpdatedAuditLogData.Create, + [ActionType.StageInstanceDeleted] = StageInstanceDeleteAuditLogData.Create, + + [ActionType.StickerCreated] = StickerCreatedAuditLogData.Create, + [ActionType.StickerUpdated] = StickerUpdatedAuditLogData.Create, + [ActionType.StickerDeleted] = StickerDeletedAuditLogData.Create, + + [ActionType.AutoModerationRuleCreate] = AutoModRuleCreatedAuditLogData.Create, + [ActionType.AutoModerationRuleUpdate] = AutoModRuleUpdatedAuditLogData.Create, + [ActionType.AutoModerationRuleDelete] = AutoModRuleDeletedAuditLogData.Create, + + [ActionType.AutoModerationBlockMessage] = AutoModBlockedMessageAuditLogData.Create, + [ActionType.AutoModerationFlagToChannel] = AutoModFlaggedMessageAuditLogData.Create, + [ActionType.AutoModerationUserCommunicationDisabled] = AutoModTimeoutUserAuditLogData.Create, + + [ActionType.OnboardingQuestionCreated] = OnboardingPromptCreatedAuditLogData.Create, + [ActionType.OnboardingQuestionUpdated] = OnboardingPromptUpdatedAuditLogData.Create, + [ActionType.OnboardingUpdated] = OnboardingUpdatedAuditLogData.Create, + }; + + public static IAuditLogData CreateData(BaseDiscordClient discord, EntryModel entry, Model log = null) + { + if (CreateMapping.TryGetValue(entry.Action, out var func)) + return func(discord, entry, log); + + return null; + } + + internal static (T, T) CreateAuditLogEntityInfo(AuditLogChange[] changes, BaseDiscordClient discord) where T : IAuditLogInfoModel + { + var oldModel = (T)Activator.CreateInstance(typeof(T))!; + var newModel = (T)Activator.CreateInstance(typeof(T))!; + + var props = typeof(T).GetProperties(); + + foreach (var property in props) + { + if (property.GetCustomAttributes(typeof(JsonFieldAttribute), true).FirstOrDefault() is not JsonFieldAttribute jsonAttr) + continue; + + var change = changes.FirstOrDefault(x => x.ChangedProperty == jsonAttr.FieldName); + + if (change is null) + continue; + + property.SetValue(oldModel, change.OldValue?.ToObject(property.PropertyType, discord.ApiClient.Serializer)); + property.SetValue(newModel, change.NewValue?.ToObject(property.PropertyType, discord.ApiClient.Serializer)); } + + return (oldModel, newModel); } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/AutoModBlockedMessageAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/AutoModBlockedMessageAuditLogData.cs new file mode 100644 index 00000000..c0b4a39d --- /dev/null +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/AutoModBlockedMessageAuditLogData.cs @@ -0,0 +1,38 @@ +using EntryModel = Discord.API.AuditLogEntry; +using Model = Discord.API.AuditLog; + +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to message getting blocked by automod. +/// +public class AutoModBlockedMessageAuditLogData : IAuditLogData +{ + internal AutoModBlockedMessageAuditLogData(ulong channelId, string autoModRuleName, AutoModTriggerType autoModRuleTriggerType) + { + ChannelId = channelId; + AutoModRuleName = autoModRuleName; + AutoModRuleTriggerType = autoModRuleTriggerType; + } + + internal static AutoModBlockedMessageAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log) + { + return new(entry.Options.ChannelId!.Value, entry.Options.AutoModRuleName, + entry.Options.AutoModRuleTriggerType!.Value); + } + + /// + /// Gets the channel the message was sent in. + /// + public ulong ChannelId { get; set; } + + /// + /// Gets the name of the auto moderation rule that got triggered. + /// + public string AutoModRuleName { get; set; } + + /// + /// Gets the trigger type of the auto moderation rule that got triggered. + /// + public AutoModTriggerType AutoModRuleTriggerType { get; set; } +} diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/AutoModFlaggedMessageAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/AutoModFlaggedMessageAuditLogData.cs new file mode 100644 index 00000000..5b0f13f8 --- /dev/null +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/AutoModFlaggedMessageAuditLogData.cs @@ -0,0 +1,38 @@ +using EntryModel = Discord.API.AuditLogEntry; +using Model = Discord.API.AuditLog; + +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to message getting flagged by automod. +/// +public class AutoModFlaggedMessageAuditLogData : IAuditLogData +{ + internal AutoModFlaggedMessageAuditLogData(ulong channelId, string autoModRuleName, AutoModTriggerType autoModRuleTriggerType) + { + ChannelId = channelId; + AutoModRuleName = autoModRuleName; + AutoModRuleTriggerType = autoModRuleTriggerType; + } + + internal static AutoModFlaggedMessageAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log) + { + return new(entry.Options.ChannelId!.Value, entry.Options.AutoModRuleName, + entry.Options.AutoModRuleTriggerType!.Value); + } + + /// + /// Gets the channel the message was sent in. + /// + public ulong ChannelId { get; set; } + + /// + /// Gets the name of the auto moderation rule that got triggered. + /// + public string AutoModRuleName { get; set; } + + /// + /// Gets the trigger type of the auto moderation rule that got triggered. + /// + public AutoModTriggerType AutoModRuleTriggerType { get; set; } +} diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/AutoModRuleCreatedAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/AutoModRuleCreatedAuditLogData.cs new file mode 100644 index 00000000..3ee382e3 --- /dev/null +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/AutoModRuleCreatedAuditLogData.cs @@ -0,0 +1,31 @@ +using Discord.API.AuditLogs; + +using EntryModel = Discord.API.AuditLogEntry; +using Model = Discord.API.AuditLog; + +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to an auto moderation rule creation. +/// +public class AutoModRuleCreatedAuditLogData : IAuditLogData +{ + private AutoModRuleCreatedAuditLogData(AutoModRuleInfo data) + { + Data = data; + } + + internal static AutoModRuleCreatedAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log) + { + var changes = entry.Changes; + + var (_, data) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new AutoModRuleCreatedAuditLogData(new (data)); + } + + /// + /// Gets the auto moderation rule information after the changes. + /// + public AutoModRuleInfo Data { get; } +} diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/AutoModRuleDeletedAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/AutoModRuleDeletedAuditLogData.cs new file mode 100644 index 00000000..5e127643 --- /dev/null +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/AutoModRuleDeletedAuditLogData.cs @@ -0,0 +1,31 @@ +using Discord.API.AuditLogs; + +using EntryModel = Discord.API.AuditLogEntry; +using Model = Discord.API.AuditLog; + +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to an auto moderation rule removal. +/// +public class AutoModRuleDeletedAuditLogData : IAuditLogData +{ + private AutoModRuleDeletedAuditLogData(AutoModRuleInfo data) + { + Data = data; + } + + internal static AutoModRuleDeletedAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log) + { + var changes = entry.Changes; + + var (data, _) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new AutoModRuleDeletedAuditLogData(new (data)); + } + + /// + /// Gets the auto moderation rule information before the changes. + /// + public AutoModRuleInfo Data { get; } +} diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/AutoModRuleInfo.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/AutoModRuleInfo.cs new file mode 100644 index 00000000..98b0d721 --- /dev/null +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/AutoModRuleInfo.cs @@ -0,0 +1,113 @@ +using Discord.API.AuditLogs; + +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; + +namespace Discord.Rest; + +/// +/// Represents information for an auto moderation rule. +/// +public class AutoModRuleInfo +{ + internal AutoModRuleInfo(AutoModRuleInfoAuditLogModel model) + { + Actions = model.Actions?.Select(x => new AutoModRuleAction( + x.Type, + x.Metadata.GetValueOrDefault()?.ChannelId.ToNullable(), + x.Metadata.GetValueOrDefault()?.DurationSeconds.ToNullable(), + x.Metadata.IsSpecified + ? x.Metadata.Value.CustomMessage.IsSpecified + ? x.Metadata.Value.CustomMessage.Value + : null + : null + )).ToImmutableArray(); + KeywordFilter = model.TriggerMetadata?.KeywordFilter.GetValueOrDefault(Array.Empty())?.ToImmutableArray(); + Presets = model.TriggerMetadata?.Presets.GetValueOrDefault(Array.Empty())?.ToImmutableArray(); + RegexPatterns = model.TriggerMetadata?.RegexPatterns.GetValueOrDefault(Array.Empty())?.ToImmutableArray(); + AllowList = model.TriggerMetadata?.AllowList.GetValueOrDefault(Array.Empty())?.ToImmutableArray(); + MentionTotalLimit = model.TriggerMetadata?.MentionLimit.IsSpecified ?? false + ? model.TriggerMetadata?.MentionLimit.Value + : null; + Name = model.Name; + Enabled = model.Enabled; + ExemptRoles = model.ExemptRoles?.ToImmutableArray(); + ExemptChannels = model.ExemptChannels?.ToImmutableArray(); + TriggerType = model.TriggerType; + EventType = model.EventType; + } + + /// + /// + /// if this property is not mentioned in this entry. + /// + public string Name { get; set; } + + /// + /// + /// if this property is not mentioned in this entry. + /// + public AutoModEventType? EventType { get; set; } + + /// + /// + /// if this property is not mentioned in this entry. + /// + public AutoModTriggerType? TriggerType { get; set; } + + /// + /// + /// if this property is not mentioned in this entry. + /// + public bool? Enabled { get; set; } + + /// + /// + /// if this property is not mentioned in this entry. + /// + public IReadOnlyCollection ExemptRoles { get; set; } + + /// + /// + /// if this property is not mentioned in this entry. + /// + public IReadOnlyCollection ExemptChannels { get; set; } + + /// + /// + /// if this property is not mentioned in this entry. + /// + public IReadOnlyCollection KeywordFilter { get; } + + /// + /// + /// if this property is not mentioned in this entry. + /// + public IReadOnlyCollection RegexPatterns { get; } + + /// + /// + /// if this property is not mentioned in this entry. + /// + public IReadOnlyCollection AllowList { get; } + + /// + /// + /// if this property is not mentioned in this entry. + /// + public IReadOnlyCollection Presets { get; } + + /// + /// + /// if this property is not mentioned in this entry. + /// + public int? MentionTotalLimit { get; } + + /// + /// + /// if this property is not mentioned in this entry. + /// + public IReadOnlyCollection Actions { get; private set; } +} diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/AutoModRuleUpdatedAuditLogData .cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/AutoModRuleUpdatedAuditLogData .cs new file mode 100644 index 00000000..ef173b14 --- /dev/null +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/AutoModRuleUpdatedAuditLogData .cs @@ -0,0 +1,45 @@ +using Discord.API.AuditLogs; +using System.Linq; +using EntryModel = Discord.API.AuditLogEntry; +using Model = Discord.API.AuditLog; + +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to an auto moderation rule update. +/// +public class AutoModRuleUpdatedAuditLogData : IAuditLogData +{ + private AutoModRuleUpdatedAuditLogData(AutoModRuleInfo before, AutoModRuleInfo after, IAutoModRule rule) + { + Before = before; + After = after; + Rule = rule; + } + + internal static AutoModRuleUpdatedAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log) + { + var changes = entry.Changes; + + var (before, after) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + var rule = RestAutoModRule.Create(discord, log.AutoModerationRules.FirstOrDefault(x => x.Id == entry.TargetId)); + + return new AutoModRuleUpdatedAuditLogData(new (before), new(after), rule); + } + + /// + /// Gets the auto moderation rule the changes correspond to. + /// + public IAutoModRule Rule { get; } + + /// + /// Gets the auto moderation rule information before the changes. + /// + public AutoModRuleInfo Before { get; } + + /// + /// Gets the auto moderation rule information after the changes. + /// + public AutoModRuleInfo After { get; } +} diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/AutoModTimeoutUserAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/AutoModTimeoutUserAuditLogData.cs new file mode 100644 index 00000000..ced0dadb --- /dev/null +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/AutoModTimeoutUserAuditLogData.cs @@ -0,0 +1,38 @@ +using EntryModel = Discord.API.AuditLogEntry; +using Model = Discord.API.AuditLog; + +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to user getting in timeout by automod. +/// +public class AutoModTimeoutUserAuditLogData : IAuditLogData +{ + internal AutoModTimeoutUserAuditLogData(ulong channelId, string autoModRuleName, AutoModTriggerType autoModRuleTriggerType) + { + ChannelId = channelId; + AutoModRuleName = autoModRuleName; + AutoModRuleTriggerType = autoModRuleTriggerType; + } + + internal static AutoModTimeoutUserAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log) + { + return new(entry.Options.ChannelId!.Value, entry.Options.AutoModRuleName, + entry.Options.AutoModRuleTriggerType!.Value); + } + + /// + /// Gets the channel the message was sent in. + /// + public ulong ChannelId { get; set; } + + /// + /// Gets the name of the auto moderation rule that got triggered. + /// + public string AutoModRuleName { get; set; } + + /// + /// Gets the trigger type of the auto moderation rule that got triggered. + /// + public AutoModTriggerType AutoModRuleTriggerType { get; set; } +} diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/BanAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/BanAuditLogData.cs index 3a599ca0..1c9bfa04 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/BanAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/BanAuditLogData.cs @@ -2,33 +2,32 @@ using System.Linq; using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to a ban. +/// +public class BanAuditLogData : IAuditLogData { - /// - /// Contains a piece of audit log data related to a ban. - /// - public class BanAuditLogData : IAuditLogData + private BanAuditLogData(IUser user) { - private BanAuditLogData(IUser user) - { - Target = user; - } - - internal static BanAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - var userInfo = log.Users.FirstOrDefault(x => x.Id == entry.TargetId); - return new BanAuditLogData((userInfo != null) ? RestUser.Create(discord, userInfo) : null); - } - - /// - /// Gets the user that was banned. - /// - /// - /// Will be if the user is a 'Deleted User#....' because Discord does send user data for deleted users. - /// - /// - /// A user object representing the banned user. - /// - public IUser Target { get; } + Target = user; } + + internal static BanAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log = null) + { + var userInfo = log.Users.FirstOrDefault(x => x.Id == entry.TargetId); + return new BanAuditLogData((userInfo != null) ? RestUser.Create(discord, userInfo) : null); + } + + /// + /// Gets the user that was banned. + /// + /// + /// Will be if the user is a 'Deleted User#....' because Discord does send user data for deleted users. + /// + /// + /// A user object representing the banned user. + /// + public IUser Target { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/BotAddAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/BotAddAuditLogData.cs index 3e9394e8..2d5b21e4 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/BotAddAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/BotAddAuditLogData.cs @@ -2,33 +2,32 @@ using System.Linq; using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to a adding a bot to a guild. +/// +public class BotAddAuditLogData : IAuditLogData { - /// - /// Contains a piece of audit log data related to a adding a bot to a guild. - /// - public class BotAddAuditLogData : IAuditLogData + private BotAddAuditLogData(IUser bot) { - private BotAddAuditLogData(IUser bot) - { - Target = bot; - } - - internal static BotAddAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - var userInfo = log.Users.FirstOrDefault(x => x.Id == entry.TargetId); - return new BotAddAuditLogData((userInfo != null) ? RestUser.Create(discord, userInfo) : null); - } - - /// - /// Gets the bot that was added. - /// - /// - /// Will be if the bot is a 'Deleted User#....' because Discord does send user data for deleted users. - /// - /// - /// A user object representing the bot. - /// - public IUser Target { get; } + Target = bot; } + + internal static BotAddAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log) + { + var userInfo = log.Users.FirstOrDefault(x => x.Id == entry.TargetId); + return new BotAddAuditLogData((userInfo != null) ? RestUser.Create(discord, userInfo) : null); + } + + /// + /// Gets the bot that was added. + /// + /// + /// Will be if the bot is a 'Deleted User#....' because Discord does send user data for deleted users. + /// + /// + /// A user object representing the bot. + /// + public IUser Target { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ChannelCreateAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ChannelCreateAuditLogData.cs index 07e90bce..6cd2d4ea 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ChannelCreateAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ChannelCreateAuditLogData.cs @@ -1,104 +1,176 @@ +using Discord.API.AuditLogs; + using System.Collections.Generic; +using System.Collections.Immutable; using System.Linq; using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to a channel creation. +/// +public class ChannelCreateAuditLogData : IAuditLogData { - /// - /// Contains a piece of audit log data related to a channel creation. - /// - public class ChannelCreateAuditLogData : IAuditLogData + private ChannelCreateAuditLogData(ChannelInfoAuditLogModel model, EntryModel entry) { - private ChannelCreateAuditLogData(ulong id, string name, ChannelType type, int? rateLimit, bool? nsfw, int? bitrate, IReadOnlyCollection overwrites) + ChannelId = entry.TargetId!.Value; + ChannelName = model.Name; + ChannelType = model.Type!.Value; + SlowModeInterval = model.RateLimitPerUser; + IsNsfw = model.IsNsfw; + Bitrate = model.Bitrate; + Topic = model.Topic; + AutoArchiveDuration = model.AutoArchiveDuration; + DefaultSlowModeInterval = model.DefaultThreadRateLimitPerUser; + DefaultAutoArchiveDuration = model.DefaultArchiveDuration; + + AvailableTags = model.AvailableTags?.Select(x => new ForumTag(x.Id, + x.Name, + x.EmojiId.GetValueOrDefault(null), + x.EmojiName.GetValueOrDefault(null), + x.Moderated)).ToImmutableArray(); + + + if (model.DefaultEmoji is not null) { - ChannelId = id; - ChannelName = name; - ChannelType = type; - SlowModeInterval = rateLimit; - IsNsfw = nsfw; - Bitrate = bitrate; - Overwrites = overwrites; + if (model.DefaultEmoji.EmojiId.HasValue && model.DefaultEmoji.EmojiId.Value != 0) + DefaultReactionEmoji = new Emote(model.DefaultEmoji.EmojiId.GetValueOrDefault(), null, false); + else if (model.DefaultEmoji.EmojiName.IsSpecified) + DefaultReactionEmoji = new Emoji(model.DefaultEmoji.EmojiName.Value); + else + DefaultReactionEmoji = null; } + else + DefaultReactionEmoji = null; - internal static ChannelCreateAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - var changes = entry.Changes; - - var overwritesModel = changes.FirstOrDefault(x => x.ChangedProperty == "permission_overwrites"); - var typeModel = changes.FirstOrDefault(x => x.ChangedProperty == "type"); - var nameModel = changes.FirstOrDefault(x => x.ChangedProperty == "name"); - var rateLimitPerUserModel = changes.FirstOrDefault(x => x.ChangedProperty == "rate_limit_per_user"); - var nsfwModel = changes.FirstOrDefault(x => x.ChangedProperty == "nsfw"); - var bitrateModel = changes.FirstOrDefault(x => x.ChangedProperty == "bitrate"); - - var overwrites = overwritesModel.NewValue.ToObject(discord.ApiClient.Serializer) - .Select(x => new Overwrite(x.TargetId, x.TargetType, new OverwritePermissions(x.Allow, x.Deny))) - .ToList(); - var type = typeModel.NewValue.ToObject(discord.ApiClient.Serializer); - var name = nameModel.NewValue.ToObject(discord.ApiClient.Serializer); - int? rateLimitPerUser = rateLimitPerUserModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - bool? nsfw = nsfwModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - int? bitrate = bitrateModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - var id = entry.TargetId.Value; - - return new ChannelCreateAuditLogData(id, name, type, rateLimitPerUser, nsfw, bitrate, overwrites.ToReadOnlyCollection()); - } - - /// - /// Gets the snowflake ID of the created channel. - /// - /// - /// A representing the snowflake identifier for the created channel. - /// - public ulong ChannelId { get; } - /// - /// Gets the name of the created channel. - /// - /// - /// A string containing the name of the created channel. - /// - public string ChannelName { get; } - /// - /// Gets the type of the created channel. - /// - /// - /// The type of channel that was created. - /// - public ChannelType ChannelType { get; } - /// - /// Gets the current slow-mode delay of the created channel. - /// - /// - /// An representing the time in seconds required before the user can send another - /// message; 0 if disabled. - /// null if this is not mentioned in this entry. - /// - public int? SlowModeInterval { get; } - /// - /// Gets the value that indicates whether the created channel is NSFW. - /// - /// - /// true if the created channel has the NSFW flag enabled; otherwise false. - /// null if this is not mentioned in this entry. - /// - public bool? IsNsfw { get; } - /// - /// Gets the bit-rate that the clients in the created voice channel are requested to use. - /// - /// - /// An representing the bit-rate (bps) that the created voice channel defines and requests the - /// client(s) to use. - /// null if this is not mentioned in this entry. - /// - public int? Bitrate { get; } - /// - /// Gets a collection of permission overwrites that was assigned to the created channel. - /// - /// - /// A collection of permission , containing the permission overwrites that were - /// assigned to the created channel. - /// - public IReadOnlyCollection Overwrites { get; } + VideoQualityMode = model.VideoQualityMode; + RtcRegion = model.Region; + Flags = model.Flags; + UserLimit = model.UserLimit; + Overwrites = model.Overwrites?.Select(x => new Overwrite(x.TargetId, x.TargetType, new OverwritePermissions(x.Allow, x.Deny))) + .ToImmutableArray(); } + + internal static ChannelCreateAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log = null) + { + var changes = entry.Changes; + + var (_, data) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new ChannelCreateAuditLogData(data, entry); + } + + /// + /// Gets the snowflake ID of the created channel. + /// + /// + /// A representing the snowflake identifier for the created channel. + /// + public ulong ChannelId { get; } + + /// + /// Gets the name of the created channel. + /// + /// + /// A string containing the name of the created channel. + /// + public string ChannelName { get; } + + /// + /// Gets the type of the created channel. + /// + /// + /// The type of channel that was created. + /// + public ChannelType ChannelType { get; } + + /// + /// Gets the current slow-mode delay of the created channel. + /// + /// + /// An representing the time in seconds required before the user can send another + /// message; 0 if disabled. + /// null if this is not mentioned in this entry. + /// + public int? SlowModeInterval { get; } + + /// + /// Gets the value that indicates whether the created channel is NSFW. + /// + /// + /// true if the created channel has the NSFW flag enabled; otherwise false. + /// null if this is not mentioned in this entry. + /// + public bool? IsNsfw { get; } + + /// + /// Gets the bit-rate that the clients in the created voice channel are requested to use. + /// + /// + /// An representing the bit-rate (bps) that the created voice channel defines and requests the + /// client(s) to use. + /// null if this is not mentioned in this entry. + /// + public int? Bitrate { get; } + + /// + /// Gets a collection of permission overwrites that was assigned to the created channel. + /// + /// + /// A collection of permission , containing the permission overwrites that were + /// assigned to the created channel. + /// + public IReadOnlyCollection Overwrites { get; } + + /// + /// Gets the thread archive duration that was set in the created channel. + /// + public ThreadArchiveDuration? AutoArchiveDuration { get; } + + /// + /// Gets the default thread archive duration that was set in the created channel. + /// + public ThreadArchiveDuration? DefaultAutoArchiveDuration { get; } + + /// + /// Gets the default slow mode interval that will be set in child threads in the channel. + /// + public int? DefaultSlowModeInterval { get; } + + /// + /// Gets the topic that was set in the created channel. + /// + public string Topic { get; } + + /// + /// Gets tags available in the created forum channel. + /// + public IReadOnlyCollection AvailableTags { get; } + + /// + /// Gets the default reaction added to posts in the created forum channel. + /// + public IEmote DefaultReactionEmoji { get; } + + /// + /// Gets the user limit configured in the created voice channel. + /// + public int? UserLimit { get; } + + /// + /// Gets the video quality mode configured in the created voice channel. + /// + public VideoQualityMode? VideoQualityMode { get; } + + /// + /// Gets the region configured in the created voice channel. + /// + public string RtcRegion { get; } + + /// + /// Gets channel flags configured for the created channel. + /// + public ChannelFlags? Flags { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ChannelDeleteAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ChannelDeleteAuditLogData.cs index d70b48ce..5ba1da50 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ChannelDeleteAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ChannelDeleteAuditLogData.cs @@ -1,102 +1,175 @@ +using Discord.API.AuditLogs; + using System.Collections.Generic; +using System.Collections.Immutable; using System.Linq; using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to a channel deletion. +/// +public class ChannelDeleteAuditLogData : IAuditLogData { - /// - /// Contains a piece of audit log data related to a channel deletion. - /// - public class ChannelDeleteAuditLogData : IAuditLogData + private ChannelDeleteAuditLogData(ChannelInfoAuditLogModel model, EntryModel entry) { - private ChannelDeleteAuditLogData(ulong id, string name, ChannelType type, int? rateLimit, bool? nsfw, int? bitrate, IReadOnlyCollection overwrites) + ChannelId = entry.TargetId!.Value; + ChannelType = model.Type!.Value; + ChannelName = model.Name; + + Topic = model.Topic; + IsNsfw = model.IsNsfw; + Bitrate = model.Bitrate; + DefaultArchiveDuration = model.DefaultArchiveDuration; + SlowModeInterval = model.RateLimitPerUser; + + ForumTags = model.AvailableTags?.Select( + x => new ForumTag(x.Id, + x.Name, + x.EmojiId.GetValueOrDefault(null), + x.EmojiName.GetValueOrDefault(null), + x.Moderated)).ToImmutableArray(); + + if (model.DefaultEmoji is not null) { - ChannelId = id; - ChannelName = name; - ChannelType = type; - SlowModeInterval = rateLimit; - IsNsfw = nsfw; - Bitrate = bitrate; - Overwrites = overwrites; + if (model.DefaultEmoji.EmojiId.HasValue && model.DefaultEmoji.EmojiId.Value != 0) + DefaultReactionEmoji = new Emote(model.DefaultEmoji.EmojiId.GetValueOrDefault(), null, false); + else if (model.DefaultEmoji.EmojiName.IsSpecified) + DefaultReactionEmoji = new Emoji(model.DefaultEmoji.EmojiName.Value); + else + DefaultReactionEmoji = null; } + else + DefaultReactionEmoji = null; + AutoArchiveDuration = model.AutoArchiveDuration; + DefaultSlowModeInterval = model.DefaultThreadRateLimitPerUser; - internal static ChannelDeleteAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - var changes = entry.Changes; + VideoQualityMode = model.VideoQualityMode; + RtcRegion = model.Region; + Flags = model.Flags; + UserLimit = model.UserLimit; - var overwritesModel = changes.FirstOrDefault(x => x.ChangedProperty == "permission_overwrites"); - var typeModel = changes.FirstOrDefault(x => x.ChangedProperty == "type"); - var nameModel = changes.FirstOrDefault(x => x.ChangedProperty == "name"); - var rateLimitPerUserModel = changes.FirstOrDefault(x => x.ChangedProperty == "rate_limit_per_user"); - var nsfwModel = changes.FirstOrDefault(x => x.ChangedProperty == "nsfw"); - var bitrateModel = changes.FirstOrDefault(x => x.ChangedProperty == "bitrate"); - - var overwrites = overwritesModel.OldValue.ToObject(discord.ApiClient.Serializer) - .Select(x => new Overwrite(x.TargetId, x.TargetType, new OverwritePermissions(x.Allow, x.Deny))) - .ToList(); - var type = typeModel.OldValue.ToObject(discord.ApiClient.Serializer); - var name = nameModel.OldValue.ToObject(discord.ApiClient.Serializer); - int? rateLimitPerUser = rateLimitPerUserModel?.OldValue?.ToObject(discord.ApiClient.Serializer); - bool? nsfw = nsfwModel?.OldValue?.ToObject(discord.ApiClient.Serializer); - int? bitrate = bitrateModel?.OldValue?.ToObject(discord.ApiClient.Serializer); - var id = entry.TargetId.Value; - - return new ChannelDeleteAuditLogData(id, name, type, rateLimitPerUser, nsfw, bitrate, overwrites.ToReadOnlyCollection()); - } - - /// - /// Gets the snowflake ID of the deleted channel. - /// - /// - /// A representing the snowflake identifier for the deleted channel. - /// - public ulong ChannelId { get; } - /// - /// Gets the name of the deleted channel. - /// - /// - /// A string containing the name of the deleted channel. - /// - public string ChannelName { get; } - /// - /// Gets the type of the deleted channel. - /// - /// - /// The type of channel that was deleted. - /// - public ChannelType ChannelType { get; } - /// - /// Gets the slow-mode delay of the deleted channel. - /// - /// - /// An representing the time in seconds required before the user can send another - /// message; 0 if disabled. - /// null if this is not mentioned in this entry. - /// - public int? SlowModeInterval { get; } - /// - /// Gets the value that indicates whether the deleted channel was NSFW. - /// - /// - /// true if this channel had the NSFW flag enabled; otherwise false. - /// null if this is not mentioned in this entry. - /// - public bool? IsNsfw { get; } - /// - /// Gets the bit-rate of this channel if applicable. - /// - /// - /// An representing the bit-rate set of the voice channel. - /// null if this is not mentioned in this entry. - /// - public int? Bitrate { get; } - /// - /// Gets a collection of permission overwrites that was assigned to the deleted channel. - /// - /// - /// A collection of permission . - /// - public IReadOnlyCollection Overwrites { get; } + Overwrites = model.Overwrites?.Select(x + => new Overwrite(x.TargetId, + x.TargetType, + new OverwritePermissions(x.Allow, x.Deny))).ToImmutableArray(); } + + internal static ChannelDeleteAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log = null) + { + var changes = entry.Changes; + + var (data, _) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new ChannelDeleteAuditLogData(data, entry); + } + + /// + /// Gets the snowflake ID of the deleted channel. + /// + /// + /// A representing the snowflake identifier for the deleted channel. + /// + public ulong ChannelId { get; } + /// + /// Gets the name of the deleted channel. + /// + /// + /// A string containing the name of the deleted channel. + /// + public string ChannelName { get; } + /// + /// Gets the type of the deleted channel. + /// + /// + /// The type of channel that was deleted. + /// + public ChannelType ChannelType { get; } + /// + /// Gets the slow-mode delay of the deleted channel. + /// + /// + /// An representing the time in seconds required before the user can send another + /// message; 0 if disabled. + /// null if this is not mentioned in this entry. + /// + public int? SlowModeInterval { get; } + /// + /// Gets the value that indicates whether the deleted channel was NSFW. + /// + /// + /// true if this channel had the NSFW flag enabled; otherwise false. + /// null if this is not mentioned in this entry. + /// + public bool? IsNsfw { get; } + /// + /// Gets the bit-rate of this channel if applicable. + /// + /// + /// An representing the bit-rate set of the voice channel. + /// null if this is not mentioned in this entry. + /// + public int? Bitrate { get; } + /// + /// Gets a collection of permission overwrites that was assigned to the deleted channel. + /// + /// + /// A collection of permission . + /// + public IReadOnlyCollection Overwrites { get; } + /// + /// Gets the user limit configured in the created voice channel. + /// + public int? UserLimit { get; } + + /// + /// Gets the video quality mode configured in the created voice channel. + /// + public VideoQualityMode? VideoQualityMode { get; } + + /// + /// Gets the region configured in the created voice channel. + /// + public string RtcRegion { get; } + + /// + /// Gets channel flags configured for the created channel. + /// + public ChannelFlags? Flags { get; } + + /// + /// Gets the thread archive duration that was configured for the created channel. + /// + public ThreadArchiveDuration? AutoArchiveDuration { get; } + + /// + /// Gets the default slow mode interval that was configured for the channel. + /// + public int? DefaultSlowModeInterval { get; } + + /// + /// + /// if the value was not specified in this entry.. + /// + public ThreadArchiveDuration? DefaultArchiveDuration { get; } + + /// + /// + /// if the value was not specified in this entry.. + /// + public IReadOnlyCollection ForumTags { get; } + + /// + /// + /// if the value was not specified in this entry.. + /// + public string Topic { get; } + + /// + /// + /// if the value was not specified in this entry.. + /// + public IEmote DefaultReactionEmoji { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ChannelInfo.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ChannelInfo.cs index f50d9eeb..dce7534f 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ChannelInfo.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ChannelInfo.cs @@ -1,3 +1,8 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using Model = Discord.API.AuditLogs.ChannelInfoAuditLogModel; + namespace Discord.Rest { /// @@ -5,14 +10,41 @@ namespace Discord.Rest /// public struct ChannelInfo { - internal ChannelInfo(string name, string topic, int? rateLimit, bool? nsfw, int? bitrate, ChannelType? type) + internal ChannelInfo(Model model) { - Name = name; - Topic = topic; - SlowModeInterval = rateLimit; - IsNsfw = nsfw; - Bitrate = bitrate; - ChannelType = type; + Name = model.Name; + Topic = model.Topic; + IsNsfw = model.IsNsfw; + Bitrate = model.Bitrate; + DefaultArchiveDuration = model.DefaultArchiveDuration; + ChannelType = model.Type; + SlowModeInterval = model.RateLimitPerUser; + + ForumTags = model.AvailableTags?.Select( + x => new ForumTag(x.Id, + x.Name, + x.EmojiId.GetValueOrDefault(null), + x.EmojiName.GetValueOrDefault(null), + x.Moderated)).ToImmutableArray(); + + if (model.DefaultEmoji is not null) + { + if (model.DefaultEmoji.EmojiId.HasValue && model.DefaultEmoji.EmojiId.Value != 0) + DefaultReactionEmoji = new Emote(model.DefaultEmoji.EmojiId.GetValueOrDefault(), null, false); + else if (model.DefaultEmoji.EmojiName.IsSpecified) + DefaultReactionEmoji = new Emoji(model.DefaultEmoji.EmojiName.Value); + else + DefaultReactionEmoji = null; + } + else + DefaultReactionEmoji = null; + AutoArchiveDuration = model.AutoArchiveDuration; + DefaultSlowModeInterval = model.DefaultThreadRateLimitPerUser; + + VideoQualityMode = model.VideoQualityMode; + RtcRegion = model.Region; + Flags = model.Flags; + UserLimit = model.UserLimit; } /// @@ -61,5 +93,53 @@ namespace Discord.Rest /// The channel type of this channel; null if not applicable. /// public ChannelType? ChannelType { get; } + + /// + /// + /// if the value was not updated in this entry. + /// + public ThreadArchiveDuration? DefaultArchiveDuration { get; } + + /// + /// + /// if the value was not updated in this entry. + /// + public IReadOnlyCollection ForumTags { get; } + + /// + /// + /// if the value was not updated in this entry. + /// + public IEmote DefaultReactionEmoji { get; } + + /// + /// Gets the user limit configured in the created voice channel. + /// + public int? UserLimit { get; } + + /// + /// Gets the video quality mode configured in the created voice channel. + /// + public VideoQualityMode? VideoQualityMode { get; } + + /// + /// Gets the region configured in the created voice channel. + /// + public string RtcRegion { get; } + + /// + /// Gets channel flags configured for the created channel. + /// + public ChannelFlags? Flags { get; } + + /// + /// Gets the thread archive duration that was set in the created channel. + /// + public ThreadArchiveDuration? AutoArchiveDuration { get; } + + /// + /// Gets the default slow mode interval that will be set in child threads in the channel. + /// + public int? DefaultSlowModeInterval { get; } } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ChannelUpdateAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ChannelUpdateAuditLogData.cs index 90b69c4f..e97b7582 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ChannelUpdateAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ChannelUpdateAuditLogData.cs @@ -1,3 +1,4 @@ +using Discord.API.AuditLogs; using System.Linq; using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; @@ -16,34 +17,13 @@ namespace Discord.Rest After = after; } - internal static ChannelUpdateAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) + internal static ChannelUpdateAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log = null) { var changes = entry.Changes; - var nameModel = changes.FirstOrDefault(x => x.ChangedProperty == "name"); - var topicModel = changes.FirstOrDefault(x => x.ChangedProperty == "topic"); - var rateLimitPerUserModel = changes.FirstOrDefault(x => x.ChangedProperty == "rate_limit_per_user"); - var nsfwModel = changes.FirstOrDefault(x => x.ChangedProperty == "nsfw"); - var bitrateModel = changes.FirstOrDefault(x => x.ChangedProperty == "bitrate"); - var typeModel = changes.FirstOrDefault(x => x.ChangedProperty == "type"); + var (before, after) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); - string oldName = nameModel?.OldValue?.ToObject(discord.ApiClient.Serializer), - newName = nameModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - string oldTopic = topicModel?.OldValue?.ToObject(discord.ApiClient.Serializer), - newTopic = topicModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - int? oldRateLimitPerUser = rateLimitPerUserModel?.OldValue?.ToObject(discord.ApiClient.Serializer), - newRateLimitPerUser = rateLimitPerUserModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - bool? oldNsfw = nsfwModel?.OldValue?.ToObject(discord.ApiClient.Serializer), - newNsfw = nsfwModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - int? oldBitrate = bitrateModel?.OldValue?.ToObject(discord.ApiClient.Serializer), - newBitrate = bitrateModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - ChannelType? oldType = typeModel?.OldValue?.ToObject(discord.ApiClient.Serializer), - newType = typeModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - - var before = new ChannelInfo(oldName, oldTopic, oldRateLimitPerUser, oldNsfw, oldBitrate, oldType); - var after = new ChannelInfo(newName, newTopic, newRateLimitPerUser, newNsfw, newBitrate, newType); - - return new ChannelUpdateAuditLogData(entry.TargetId.Value, before, after); + return new ChannelUpdateAuditLogData(entry.TargetId!.Value, new ChannelInfo(before), new ChannelInfo(after)); } /// diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/CommandPermissionUpdateAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/CommandPermissionUpdateAuditLogData.cs new file mode 100644 index 00000000..614235dc --- /dev/null +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/CommandPermissionUpdateAuditLogData.cs @@ -0,0 +1,69 @@ +using Discord.API; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; + +using EntryModel = Discord.API.AuditLogEntry; +using Model = Discord.API.AuditLog; + +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to an application command permission update. +/// +public class CommandPermissionUpdateAuditLogData : IAuditLogData +{ + internal CommandPermissionUpdateAuditLogData(IReadOnlyCollection before, IReadOnlyCollection after, + IApplicationCommand command, ulong appId) + { + Before = before; + After = after; + ApplicationCommand = command; + ApplicationId = appId; + } + + internal static CommandPermissionUpdateAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log) + { + var changes = entry.Changes; + + var before = new List(); + var after = new List(); + + foreach (var change in changes) + { + var oldValue = change.OldValue?.ToObject(); + var newValue = change.NewValue?.ToObject(); + + if (oldValue is not null) + before.Add(new ApplicationCommandPermission(oldValue.Id, oldValue.Type, oldValue.Permission)); + + if (newValue is not null) + after.Add(new ApplicationCommandPermission(newValue.Id, newValue.Type, newValue.Permission)); + } + + var command = log.Commands.FirstOrDefault(x => x.Id == entry.TargetId); + var appCommand = RestApplicationCommand.Create(discord, command, command?.GuildId.IsSpecified ?? false ? command.GuildId.Value : null); + + return new(before.ToImmutableArray(), after.ToImmutableArray(), appCommand, entry.Options.ApplicationId!.Value); + } + + /// + /// Gets the ID of the app whose permissions were targeted. + /// + public ulong ApplicationId { get; set; } + + /// + /// Gets the application command which permissions were updated. + /// + public IApplicationCommand ApplicationCommand { get; } + + /// + /// Gets values of the permissions before the change if available. + /// + public IReadOnlyCollection Before { get; } + + /// + /// Gets values of the permissions after the change if available. + /// + public IReadOnlyCollection After { get; } +} diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/EmoteCreateAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/EmoteCreateAuditLogData.cs index 4a0716de..7f73b6ea 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/EmoteCreateAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/EmoteCreateAuditLogData.cs @@ -1,41 +1,42 @@ using System.Linq; + using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to an emoji creation. +/// +public class EmoteCreateAuditLogData : IAuditLogData { - /// - /// Contains a piece of audit log data related to an emoji creation. - /// - public class EmoteCreateAuditLogData : IAuditLogData + private EmoteCreateAuditLogData(ulong id, string name) { - private EmoteCreateAuditLogData(ulong id, string name) - { - EmoteId = id; - Name = name; - } - - internal static EmoteCreateAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - var change = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "name"); - - var emoteName = change.NewValue?.ToObject(discord.ApiClient.Serializer); - return new EmoteCreateAuditLogData(entry.TargetId.Value, emoteName); - } - - /// - /// Gets the snowflake ID of the created emoji. - /// - /// - /// A representing the snowflake identifier for the created emoji. - /// - public ulong EmoteId { get; } - /// - /// Gets the name of the created emoji. - /// - /// - /// A string containing the name of the created emoji. - /// - public string Name { get; } + EmoteId = id; + Name = name; } + + internal static EmoteCreateAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log) + { + var change = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "name"); + + var emoteName = change.NewValue?.ToObject(discord.ApiClient.Serializer); + return new EmoteCreateAuditLogData(entry.TargetId.Value, emoteName); + } + + /// + /// Gets the snowflake ID of the created emoji. + /// + /// + /// A representing the snowflake identifier for the created emoji. + /// + public ulong EmoteId { get; } + + /// + /// Gets the name of the created emoji. + /// + /// + /// A string containing the name of the created emoji. + /// + public string Name { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/EmoteDeleteAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/EmoteDeleteAuditLogData.cs index 3e58f3c1..2051586c 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/EmoteDeleteAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/EmoteDeleteAuditLogData.cs @@ -2,41 +2,41 @@ using System.Linq; using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to an emoji deletion. +/// +public class EmoteDeleteAuditLogData : IAuditLogData { - /// - /// Contains a piece of audit log data related to an emoji deletion. - /// - public class EmoteDeleteAuditLogData : IAuditLogData + private EmoteDeleteAuditLogData(ulong id, string name) { - private EmoteDeleteAuditLogData(ulong id, string name) - { - EmoteId = id; - Name = name; - } - - internal static EmoteDeleteAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - var change = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "name"); - - var emoteName = change.OldValue?.ToObject(discord.ApiClient.Serializer); - - return new EmoteDeleteAuditLogData(entry.TargetId.Value, emoteName); - } - - /// - /// Gets the snowflake ID of the deleted emoji. - /// - /// - /// A representing the snowflake identifier for the deleted emoji. - /// - public ulong EmoteId { get; } - /// - /// Gets the name of the deleted emoji. - /// - /// - /// A string containing the name of the deleted emoji. - /// - public string Name { get; } + EmoteId = id; + Name = name; } + + internal static EmoteDeleteAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log) + { + var change = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "name"); + + var emoteName = change.OldValue?.ToObject(discord.ApiClient.Serializer); + + return new EmoteDeleteAuditLogData(entry.TargetId.Value, emoteName); + } + + /// + /// Gets the snowflake ID of the deleted emoji. + /// + /// + /// A representing the snowflake identifier for the deleted emoji. + /// + public ulong EmoteId { get; } + + /// + /// Gets the name of the deleted emoji. + /// + /// + /// A string containing the name of the deleted emoji. + /// + public string Name { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/EmoteUpdateAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/EmoteUpdateAuditLogData.cs index 0603e4b3..9e626ed6 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/EmoteUpdateAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/EmoteUpdateAuditLogData.cs @@ -1,51 +1,53 @@ using System.Linq; + using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to an emoji update. +/// +public class EmoteUpdateAuditLogData : IAuditLogData { - /// - /// Contains a piece of audit log data related to an emoji update. - /// - public class EmoteUpdateAuditLogData : IAuditLogData + private EmoteUpdateAuditLogData(ulong id, string oldName, string newName) { - private EmoteUpdateAuditLogData(ulong id, string oldName, string newName) - { - EmoteId = id; - OldName = oldName; - NewName = newName; - } - - internal static EmoteUpdateAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - var change = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "name"); - - var newName = change.NewValue?.ToObject(discord.ApiClient.Serializer); - var oldName = change.OldValue?.ToObject(discord.ApiClient.Serializer); - - return new EmoteUpdateAuditLogData(entry.TargetId.Value, oldName, newName); - } - - /// - /// Gets the snowflake ID of the updated emoji. - /// - /// - /// A representing the snowflake identifier of the updated emoji. - /// - public ulong EmoteId { get; } - /// - /// Gets the new name of the updated emoji. - /// - /// - /// A string containing the new name of the updated emoji. - /// - public string NewName { get; } - /// - /// Gets the old name of the updated emoji. - /// - /// - /// A string containing the old name of the updated emoji. - /// - public string OldName { get; } + EmoteId = id; + OldName = oldName; + NewName = newName; } + + internal static EmoteUpdateAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log) + { + var change = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "name"); + + var newName = change.NewValue?.ToObject(discord.ApiClient.Serializer); + var oldName = change.OldValue?.ToObject(discord.ApiClient.Serializer); + + return new EmoteUpdateAuditLogData(entry.TargetId.Value, oldName, newName); + } + + /// + /// Gets the snowflake ID of the updated emoji. + /// + /// + /// A representing the snowflake identifier of the updated emoji. + /// + public ulong EmoteId { get; } + + /// + /// Gets the new name of the updated emoji. + /// + /// + /// A string containing the new name of the updated emoji. + /// + public string NewName { get; } + + /// + /// Gets the old name of the updated emoji. + /// + /// + /// A string containing the old name of the updated emoji. + /// + public string OldName { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/GuildInfo.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/GuildInfo.cs index 85c7ac43..099da3ef 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/GuildInfo.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/GuildInfo.cs @@ -1,128 +1,218 @@ -namespace Discord.Rest -{ - /// - /// Represents information for a guild. - /// - public struct GuildInfo - { - internal GuildInfo(int? afkTimeout, DefaultMessageNotifications? defaultNotifs, - ulong? afkChannel, string name, string region, string icon, - VerificationLevel? verification, IUser owner, MfaLevel? mfa, ExplicitContentFilterLevel? filter, - ulong? systemChannel, ulong? widgetChannel, bool? widget) - { - AfkTimeout = afkTimeout; - DefaultMessageNotifications = defaultNotifs; - AfkChannelId = afkChannel; - Name = name; - RegionId = region; - IconHash = icon; - VerificationLevel = verification; - Owner = owner; - MfaLevel = mfa; - ExplicitContentFilter = filter; - SystemChannelId = systemChannel; - EmbedChannelId = widgetChannel; - IsEmbeddable = widget; - } +using Model = Discord.API.AuditLogs.GuildInfoAuditLogModel; - /// - /// Gets the amount of time (in seconds) a user must be inactive in a voice channel for until they are - /// automatically moved to the AFK voice channel. - /// - /// - /// An representing the amount of time in seconds for a user to be marked as inactive - /// and moved into the AFK voice channel. - /// null if this is not mentioned in this entry. - /// - public int? AfkTimeout { get; } - /// - /// Gets the default message notifications for users who haven't explicitly set their notification settings. - /// - /// - /// The default message notifications setting of this guild. - /// null if this is not mentioned in this entry. - /// - public DefaultMessageNotifications? DefaultMessageNotifications { get; } - /// - /// Gets the ID of the AFK voice channel for this guild. - /// - /// - /// A representing the snowflake identifier of the AFK voice channel; null if - /// none is set. - /// - public ulong? AfkChannelId { get; } - /// - /// Gets the name of this guild. - /// - /// - /// A string containing the name of this guild. - /// - public string Name { get; } - /// - /// Gets the ID of the region hosting this guild's voice channels. - /// - public string RegionId { get; } - /// - /// Gets the ID of this guild's icon. - /// - /// - /// A string containing the identifier for the splash image; null if none is set. - /// - public string IconHash { get; } - /// - /// Gets the level of requirements a user must fulfill before being allowed to post messages in this guild. - /// - /// - /// The level of requirements. - /// null if this is not mentioned in this entry. - /// - public VerificationLevel? VerificationLevel { get; } - /// - /// Gets the owner of this guild. - /// - /// - /// A user object representing the owner of this guild. - /// - public IUser Owner { get; } - /// - /// Gets the level of Multi-Factor Authentication requirements a user must fulfill before being allowed to - /// perform administrative actions in this guild. - /// - /// - /// The level of MFA requirement. - /// null if this is not mentioned in this entry. - /// - public MfaLevel? MfaLevel { get; } - /// - /// Gets the level of content filtering applied to user's content in a Guild. - /// - /// - /// The level of explicit content filtering. - /// - public ExplicitContentFilterLevel? ExplicitContentFilter { get; } - /// - /// Gets the ID of the channel where system messages are sent. - /// - /// - /// A representing the snowflake identifier of the channel where system - /// messages are sent; null if none is set. - /// - public ulong? SystemChannelId { get; } - /// - /// Gets the ID of the widget embed channel of this guild. - /// - /// - /// A representing the snowflake identifier of the embedded channel found within the - /// widget settings of this guild; null if none is set. - /// - public ulong? EmbedChannelId { get; } - /// - /// Gets a value that indicates whether this guild is embeddable (i.e. can use widget). - /// - /// - /// true if this guild can be embedded via widgets; otherwise false. - /// null if this is not mentioned in this entry. - /// - public bool? IsEmbeddable { get; } +namespace Discord.Rest; + +/// +/// Represents information for a guild. +/// +public struct GuildInfo +{ + internal GuildInfo(Model model, IUser owner) + { + Owner = owner; + + Name = model.Name; + AfkTimeout = model.AfkTimeout.GetValueOrDefault(); + IsEmbeddable = model.IsEmbeddable; + DefaultMessageNotifications = model.DefaultMessageNotifications; + MfaLevel = model.MfaLevel; + Description = model.Description; + PreferredLocale = model.PreferredLocale; + IconHash = model.IconHash; + OwnerId = model.OwnerId; + AfkChannelId = model.AfkChannelId; + ApplicationId = model.ApplicationId; + BannerId = model.Banner; + DiscoverySplashId = model.DiscoverySplash; + EmbedChannelId = model.EmbeddedChannelId; + ExplicitContentFilter = model.ExplicitContentFilterLevel; + IsBoostProgressBarEnabled = model.ProgressBarEnabled; + NsfwLevel = model.NsfwLevel; + PublicUpdatesChannelId = model.PublicUpdatesChannelId; + RegionId = model.RegionId; + RulesChannelId = model.RulesChannelId; + SplashId = model.Splash; + SystemChannelFlags = model.SystemChannelFlags; + SystemChannelId = model.SystemChannelId; + VanityURLCode = model.VanityUrl; + VerificationLevel = model.VerificationLevel; } + + /// + /// + /// if the value was not updated in this entry. + /// + public string DiscoverySplashId { get; } + + /// + /// + /// if the value was not updated in this entry. + /// + public string SplashId { get; } + + /// + /// + /// if the value was not updated in this entry. + /// + public ulong? RulesChannelId { get; } + + /// + /// + /// if the value was not updated in this entry. + /// + public ulong? PublicUpdatesChannelId { get; } + + /// + /// + /// if the value was not updated in this entry. + /// + public ulong? OwnerId { get; } + + /// + /// + /// if the value was not updated in this entry. + /// + public ulong? ApplicationId { get; } + + /// + /// + /// if the value was not updated in this entry. + /// + public string BannerId { get; } + + /// + /// + /// if the value was not updated in this entry. + /// + public string VanityURLCode { get; } + + /// + /// + /// if the value was not updated in this entry. + /// + public SystemChannelMessageDeny? SystemChannelFlags { get; } + + /// + /// + /// if the value was not updated in this entry. + /// + public string Description { get; } + + /// + /// + /// if the value was not updated in this entry. + /// + public string PreferredLocale { get; } + + /// + /// + /// if the value was not updated in this entry. + /// + public NsfwLevel? NsfwLevel { get; } + + /// + /// + /// if the value was not updated in this entry. + /// + public bool? IsBoostProgressBarEnabled { get; } + + /// + /// Gets the amount of time (in seconds) a user must be inactive in a voice channel for until they are + /// automatically moved to the AFK voice channel. + /// + /// + /// An representing the amount of time in seconds for a user to be marked as inactive + /// and moved into the AFK voice channel. + /// null if this is not mentioned in this entry. + /// + public int? AfkTimeout { get; } + /// + /// Gets the default message notifications for users who haven't explicitly set their notification settings. + /// + /// + /// The default message notifications setting of this guild. + /// null if this is not mentioned in this entry. + /// + public DefaultMessageNotifications? DefaultMessageNotifications { get; } + /// + /// Gets the ID of the AFK voice channel for this guild. + /// + /// + /// A representing the snowflake identifier of the AFK voice channel; null if + /// none is set. + /// + public ulong? AfkChannelId { get; } + /// + /// Gets the name of this guild. + /// + /// + /// A string containing the name of this guild. + /// + public string Name { get; } + /// + /// Gets the ID of the region hosting this guild's voice channels. + /// + public string RegionId { get; } + /// + /// Gets the ID of this guild's icon. + /// + /// + /// A string containing the identifier for the splash image; null if none is set. + /// + public string IconHash { get; } + /// + /// Gets the level of requirements a user must fulfill before being allowed to post messages in this guild. + /// + /// + /// The level of requirements. + /// null if this is not mentioned in this entry. + /// + public VerificationLevel? VerificationLevel { get; } + /// + /// Gets the owner of this guild. + /// + /// + /// A user object representing the owner of this guild. + /// + public IUser Owner { get; } + /// + /// Gets the level of Multi-Factor Authentication requirements a user must fulfill before being allowed to + /// perform administrative actions in this guild. + /// + /// + /// The level of MFA requirement. + /// null if this is not mentioned in this entry. + /// + public MfaLevel? MfaLevel { get; } + /// + /// Gets the level of content filtering applied to user's content in a Guild. + /// + /// + /// The level of explicit content filtering. + /// + public ExplicitContentFilterLevel? ExplicitContentFilter { get; } + /// + /// Gets the ID of the channel where system messages are sent. + /// + /// + /// A representing the snowflake identifier of the channel where system + /// messages are sent; null if none is set. + /// + public ulong? SystemChannelId { get; } + /// + /// Gets the ID of the widget embed channel of this guild. + /// + /// + /// A representing the snowflake identifier of the embedded channel found within the + /// widget settings of this guild; null if none is set. + /// + public ulong? EmbedChannelId { get; } + /// + /// Gets a value that indicates whether this guild is embeddable (i.e. can use widget). + /// + /// + /// true if this guild can be embedded via widgets; otherwise false. + /// null if this is not mentioned in this entry. + /// + public bool? IsEmbeddable { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/GuildUpdateAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/GuildUpdateAuditLogData.cs index 45673e97..008b2e7f 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/GuildUpdateAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/GuildUpdateAuditLogData.cs @@ -1,3 +1,4 @@ +using Discord.API.AuditLogs; using System.Linq; using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; @@ -15,50 +16,14 @@ namespace Discord.Rest After = after; } - internal static GuildUpdateAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) + internal static GuildUpdateAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log = null) { var changes = entry.Changes; - - var afkTimeoutModel = changes.FirstOrDefault(x => x.ChangedProperty == "afk_timeout"); - var defaultMessageNotificationsModel = changes.FirstOrDefault(x => x.ChangedProperty == "default_message_notifications"); - var afkChannelModel = changes.FirstOrDefault(x => x.ChangedProperty == "afk_channel_id"); - var nameModel = changes.FirstOrDefault(x => x.ChangedProperty == "name"); - var regionIdModel = changes.FirstOrDefault(x => x.ChangedProperty == "region"); - var iconHashModel = changes.FirstOrDefault(x => x.ChangedProperty == "icon_hash"); - var verificationLevelModel = changes.FirstOrDefault(x => x.ChangedProperty == "verification_level"); + var ownerIdModel = changes.FirstOrDefault(x => x.ChangedProperty == "owner_id"); - var mfaLevelModel = changes.FirstOrDefault(x => x.ChangedProperty == "mfa_level"); - var contentFilterModel = changes.FirstOrDefault(x => x.ChangedProperty == "explicit_content_filter"); - var systemChannelIdModel = changes.FirstOrDefault(x => x.ChangedProperty == "system_channel_id"); - var widgetChannelIdModel = changes.FirstOrDefault(x => x.ChangedProperty == "widget_channel_id"); - var widgetEnabledModel = changes.FirstOrDefault(x => x.ChangedProperty == "widget_enabled"); - int? oldAfkTimeout = afkTimeoutModel?.OldValue?.ToObject(discord.ApiClient.Serializer), - newAfkTimeout = afkTimeoutModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - DefaultMessageNotifications? oldDefaultMessageNotifications = defaultMessageNotificationsModel?.OldValue?.ToObject(discord.ApiClient.Serializer), - newDefaultMessageNotifications = defaultMessageNotificationsModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - ulong? oldAfkChannelId = afkChannelModel?.OldValue?.ToObject(discord.ApiClient.Serializer), - newAfkChannelId = afkChannelModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - string oldName = nameModel?.OldValue?.ToObject(discord.ApiClient.Serializer), - newName = nameModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - string oldRegionId = regionIdModel?.OldValue?.ToObject(discord.ApiClient.Serializer), - newRegionId = regionIdModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - string oldIconHash = iconHashModel?.OldValue?.ToObject(discord.ApiClient.Serializer), - newIconHash = iconHashModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - VerificationLevel? oldVerificationLevel = verificationLevelModel?.OldValue?.ToObject(discord.ApiClient.Serializer), - newVerificationLevel = verificationLevelModel?.NewValue?.ToObject(discord.ApiClient.Serializer); ulong? oldOwnerId = ownerIdModel?.OldValue?.ToObject(discord.ApiClient.Serializer), newOwnerId = ownerIdModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - MfaLevel? oldMfaLevel = mfaLevelModel?.OldValue?.ToObject(discord.ApiClient.Serializer), - newMfaLevel = mfaLevelModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - ExplicitContentFilterLevel? oldContentFilter = contentFilterModel?.OldValue?.ToObject(discord.ApiClient.Serializer), - newContentFilter = contentFilterModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - ulong? oldSystemChannelId = systemChannelIdModel?.OldValue?.ToObject(discord.ApiClient.Serializer), - newSystemChannelId = systemChannelIdModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - ulong? oldWidgetChannelId = widgetChannelIdModel?.OldValue?.ToObject(discord.ApiClient.Serializer), - newWidgetChannelId = widgetChannelIdModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - bool? oldWidgetEnabled = widgetEnabledModel?.OldValue?.ToObject(discord.ApiClient.Serializer), - newWidgetEnabled = widgetEnabledModel?.NewValue?.ToObject(discord.ApiClient.Serializer); IUser oldOwner = null; if (oldOwnerId != null) @@ -74,14 +39,9 @@ namespace Discord.Rest newOwner = RestUser.Create(discord, newOwnerInfo); } - var before = new GuildInfo(oldAfkTimeout, oldDefaultMessageNotifications, - oldAfkChannelId, oldName, oldRegionId, oldIconHash, oldVerificationLevel, oldOwner, - oldMfaLevel, oldContentFilter, oldSystemChannelId, oldWidgetChannelId, oldWidgetEnabled); - var after = new GuildInfo(newAfkTimeout, newDefaultMessageNotifications, - newAfkChannelId, newName, newRegionId, newIconHash, newVerificationLevel, newOwner, - newMfaLevel, newContentFilter, newSystemChannelId, newWidgetChannelId, newWidgetEnabled); + var (before, after) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); - return new GuildUpdateAuditLogData(before, after); + return new GuildUpdateAuditLogData(new(before, oldOwner), new(after, newOwner)); } /// diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/IntegrationCreatedAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/IntegrationCreatedAuditLogData.cs new file mode 100644 index 00000000..0f575814 --- /dev/null +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/IntegrationCreatedAuditLogData.cs @@ -0,0 +1,39 @@ +using Discord.API.AuditLogs; +using System.Linq; +using EntryModel = Discord.API.AuditLogEntry; +using Model = Discord.API.AuditLog; + +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to an integration authorization. +/// +public class IntegrationCreatedAuditLogData : IAuditLogData +{ + internal IntegrationCreatedAuditLogData(IntegrationInfo info, IIntegration integration) + { + Integration = integration; + Data = info; + } + + internal static IntegrationCreatedAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log) + { + var changes = entry.Changes; + + var (_, data) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + var integration = RestIntegration.Create(discord, null, log.Integrations.FirstOrDefault(x => x.Id == entry.TargetId)); + + return new(new IntegrationInfo(data), integration); + } + + /// + /// Gets the partial integration the changes correspond to. + /// + public IIntegration Integration { get; } + + /// + /// Gets the integration information after the changes. + /// + public IntegrationInfo Data { get; } +} diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/IntegrationDeletedAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/IntegrationDeletedAuditLogData.cs new file mode 100644 index 00000000..894c32fa --- /dev/null +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/IntegrationDeletedAuditLogData.cs @@ -0,0 +1,31 @@ +using Discord.API.AuditLogs; +using System.Linq; +using EntryModel = Discord.API.AuditLogEntry; +using Model = Discord.API.AuditLog; + +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to an integration removal. +/// +public class IntegrationDeletedAuditLogData : IAuditLogData +{ + internal IntegrationDeletedAuditLogData(IntegrationInfo info) + { + Data = info; + } + + internal static IntegrationDeletedAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log) + { + var changes = entry.Changes; + + var (data, _) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new(new IntegrationInfo(data)); + } + + /// + /// Gets the integration information before the changes. + /// + public IntegrationInfo Data { get; } +} diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/IntegrationInfo.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/IntegrationInfo.cs new file mode 100644 index 00000000..55f3f64a --- /dev/null +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/IntegrationInfo.cs @@ -0,0 +1,69 @@ +using Discord.API.AuditLogs; +using System.Collections.Generic; +using System.Collections.Immutable; + +namespace Discord.Rest; + +/// +/// Represents information for an integration. +/// +public class IntegrationInfo +{ + internal IntegrationInfo(IntegrationInfoAuditLogModel model) + { + Name = model.Name; + Type = model.Type; + EnableEmojis = model.EnableEmojis; + Enabled = model.Enabled; + Scopes = model.Scopes?.ToImmutableArray(); + ExpireBehavior = model.ExpireBehavior; + ExpireGracePeriod = model.ExpireGracePeriod; + Syncing = model.Syncing; + RoleId = model.RoleId; + } + + /// + /// Gets the name of the integration. if the property was not mentioned in this audit log. + /// + public string Name { get; set; } + + /// + /// Gets the type of the integration. if the property was not mentioned in this audit log. + /// + public string Type { get; set; } + + /// + /// Gets if the integration is enabled. if the property was not mentioned in this audit log. + /// + public bool? Enabled { get; set; } + + /// + /// Gets if syncing is enabled for this integration. if the property was not mentioned in this audit log. + /// + public bool? Syncing { get; set; } + + /// + /// Gets the id of the role that this integration uses for subscribers. if the property was not mentioned in this audit log. + /// + public ulong? RoleId { get; set; } + + /// + /// Gets whether emoticons should be synced for this integration. if the property was not mentioned in this audit log. + /// + public bool? EnableEmojis { get; set; } + + /// + /// Gets the behavior of expiring subscribers. if the property was not mentioned in this audit log. + /// + public IntegrationExpireBehavior? ExpireBehavior { get; set; } + + /// + /// Gets the grace period (in days) before expiring subscribers. if the property was not mentioned in this audit log. + /// + public int? ExpireGracePeriod { get; set; } + + /// + /// Gets the scopes the application has been authorized for. if the property was not mentioned in this audit log. + /// + public IReadOnlyCollection Scopes { get; set; } +} diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/IntegrationUpdatedAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/IntegrationUpdatedAuditLogData.cs new file mode 100644 index 00000000..9f4665ab --- /dev/null +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/IntegrationUpdatedAuditLogData.cs @@ -0,0 +1,45 @@ +using Discord.API.AuditLogs; +using System.Linq; +using EntryModel = Discord.API.AuditLogEntry; +using Model = Discord.API.AuditLog; + +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to an integration update. +/// +public class IntegrationUpdatedAuditLogData : IAuditLogData +{ + internal IntegrationUpdatedAuditLogData(IntegrationInfo before, IntegrationInfo after, IIntegration integration) + { + Before = before; + After = after; + Integration = integration; + } + + internal static IntegrationUpdatedAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log) + { + var changes = entry.Changes; + + var (before, after) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + var integration = RestIntegration.Create(discord, null, log.Integrations.FirstOrDefault(x => x.Id == entry.TargetId)); + + return new(new IntegrationInfo(before), new IntegrationInfo(after), integration); + } + + /// + /// Gets the partial integration the changes correspond to. + /// + public IIntegration Integration { get; } + + /// + /// Gets the integration information before the changes. + /// + public IntegrationInfo Before { get; } + + /// + /// Gets the integration information after the changes. + /// + public IntegrationInfo After { get; } +} diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/InviteCreateAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/InviteCreateAuditLogData.cs index 21b8410c..bce9e916 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/InviteCreateAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/InviteCreateAuditLogData.cs @@ -1,108 +1,102 @@ +using Discord.API.AuditLogs; using System.Linq; + using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to an invite creation. +/// +public class InviteCreateAuditLogData : IAuditLogData { - /// - /// Contains a piece of audit log data related to an invite creation. - /// - public class InviteCreateAuditLogData : IAuditLogData + private InviteCreateAuditLogData(InviteInfoAuditLogModel model, IUser inviter) { - private InviteCreateAuditLogData(int maxAge, string code, bool temporary, IUser inviter, ulong channelId, int uses, int maxUses) - { - MaxAge = maxAge; - Code = code; - Temporary = temporary; - Creator = inviter; - ChannelId = channelId; - Uses = uses; - MaxUses = maxUses; - } - - internal static InviteCreateAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - var changes = entry.Changes; - - var maxAgeModel = changes.FirstOrDefault(x => x.ChangedProperty == "max_age"); - var codeModel = changes.FirstOrDefault(x => x.ChangedProperty == "code"); - var temporaryModel = changes.FirstOrDefault(x => x.ChangedProperty == "temporary"); - var inviterIdModel = changes.FirstOrDefault(x => x.ChangedProperty == "inviter_id"); - var channelIdModel = changes.FirstOrDefault(x => x.ChangedProperty == "channel_id"); - var usesModel = changes.FirstOrDefault(x => x.ChangedProperty == "uses"); - var maxUsesModel = changes.FirstOrDefault(x => x.ChangedProperty == "max_uses"); - - var maxAge = maxAgeModel.NewValue.ToObject(discord.ApiClient.Serializer); - var code = codeModel.NewValue.ToObject(discord.ApiClient.Serializer); - var temporary = temporaryModel.NewValue.ToObject(discord.ApiClient.Serializer); - var channelId = channelIdModel.NewValue.ToObject(discord.ApiClient.Serializer); - var uses = usesModel.NewValue.ToObject(discord.ApiClient.Serializer); - var maxUses = maxUsesModel.NewValue.ToObject(discord.ApiClient.Serializer); - - RestUser inviter = null; - if (inviterIdModel != null) - { - var inviterId = inviterIdModel.NewValue.ToObject(discord.ApiClient.Serializer); - var inviterInfo = log.Users.FirstOrDefault(x => x.Id == inviterId); - inviter = (inviterInfo != null) ? RestUser.Create(discord, inviterInfo) : null; - } - - return new InviteCreateAuditLogData(maxAge, code, temporary, inviter, channelId, uses, maxUses); - } - - /// - /// Gets the time (in seconds) until the invite expires. - /// - /// - /// An representing the time in seconds until this invite expires. - /// - public int MaxAge { get; } - /// - /// Gets the unique identifier for this invite. - /// - /// - /// A string containing the invite code (e.g. FTqNnyS). - /// - public string Code { get; } - /// - /// Gets a value that determines whether the invite is a temporary one. - /// - /// - /// true if users accepting this invite will be removed from the guild when they log off; otherwise - /// false. - /// - public bool Temporary { get; } - /// - /// Gets the user that created this invite if available. - /// - /// - /// Will be if the user is a 'Deleted User#....' because Discord does send user data for deleted users. - /// - /// - /// A user that created this invite or . - /// - public IUser Creator { get; } - /// - /// Gets the ID of the channel this invite is linked to. - /// - /// - /// A representing the channel snowflake identifier that the invite points to. - /// - public ulong ChannelId { get; } - /// - /// Gets the number of times this invite has been used. - /// - /// - /// An representing the number of times this invite was used. - /// - public int Uses { get; } - /// - /// Gets the max number of uses this invite may have. - /// - /// - /// An representing the number of uses this invite may be accepted until it is removed - /// from the guild; null if none is set. - /// - public int MaxUses { get; } + MaxAge = model.MaxAge!.Value; + Code = model.Code; + Temporary = model.Temporary!.Value; + Creator = inviter; + ChannelId = model.ChannelId!.Value; + Uses = model.Uses!.Value; + MaxUses = model.MaxUses!.Value; } + + internal static InviteCreateAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log) + { + var changes = entry.Changes; + + var (_, data) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + RestUser inviter = null; + + if (data.InviterId is not null) + { + var inviterInfo = log.Users.FirstOrDefault(x => x.Id == data.InviterId); + inviter = (inviterInfo != null) ? RestUser.Create(discord, inviterInfo) : null; + } + + return new InviteCreateAuditLogData(data, inviter); + } + + /// + /// Gets the time (in seconds) until the invite expires. + /// + /// + /// An representing the time in seconds until this invite expires. + /// + public int MaxAge { get; } + + /// + /// Gets the unique identifier for this invite. + /// + /// + /// A string containing the invite code (e.g. FTqNnyS). + /// + public string Code { get; } + + /// + /// Gets a value that determines whether the invite is a temporary one. + /// + /// + /// true if users accepting this invite will be removed from the guild when they log off; otherwise + /// false. + /// + public bool Temporary { get; } + + /// + /// Gets the user that created this invite if available. + /// + /// + /// Will be if the user is a 'Deleted User#....' because Discord does send user data for deleted users. + /// + /// + /// A user that created this invite or . + /// + public IUser Creator { get; } + + /// + /// Gets the ID of the channel this invite is linked to. + /// + /// + /// A representing the channel snowflake identifier that the invite points to. + /// + public ulong ChannelId { get; } + + /// + /// Gets the number of times this invite has been used. + /// + /// + /// An representing the number of times this invite was used. + /// + public int Uses { get; } + + /// + /// Gets the max number of uses this invite may have. + /// + /// + /// An representing the number of uses this invite may be accepted until it is removed + /// from the guild; null if none is set. + /// + public int MaxUses { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/InviteDeleteAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/InviteDeleteAuditLogData.cs index af5c929d..9698bdab 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/InviteDeleteAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/InviteDeleteAuditLogData.cs @@ -1,108 +1,102 @@ +using Discord.API.AuditLogs; using System.Linq; + using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to an invite removal. +/// +public class InviteDeleteAuditLogData : IAuditLogData { - /// - /// Contains a piece of audit log data related to an invite removal. - /// - public class InviteDeleteAuditLogData : IAuditLogData + private InviteDeleteAuditLogData(InviteInfoAuditLogModel model, IUser inviter) { - private InviteDeleteAuditLogData(int maxAge, string code, bool temporary, IUser inviter, ulong channelId, int uses, int maxUses) - { - MaxAge = maxAge; - Code = code; - Temporary = temporary; - Creator = inviter; - ChannelId = channelId; - Uses = uses; - MaxUses = maxUses; - } - - internal static InviteDeleteAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - var changes = entry.Changes; - - var maxAgeModel = changes.FirstOrDefault(x => x.ChangedProperty == "max_age"); - var codeModel = changes.FirstOrDefault(x => x.ChangedProperty == "code"); - var temporaryModel = changes.FirstOrDefault(x => x.ChangedProperty == "temporary"); - var inviterIdModel = changes.FirstOrDefault(x => x.ChangedProperty == "inviter_id"); - var channelIdModel = changes.FirstOrDefault(x => x.ChangedProperty == "channel_id"); - var usesModel = changes.FirstOrDefault(x => x.ChangedProperty == "uses"); - var maxUsesModel = changes.FirstOrDefault(x => x.ChangedProperty == "max_uses"); - - var maxAge = maxAgeModel.OldValue.ToObject(discord.ApiClient.Serializer); - var code = codeModel.OldValue.ToObject(discord.ApiClient.Serializer); - var temporary = temporaryModel.OldValue.ToObject(discord.ApiClient.Serializer); - var channelId = channelIdModel.OldValue.ToObject(discord.ApiClient.Serializer); - var uses = usesModel.OldValue.ToObject(discord.ApiClient.Serializer); - var maxUses = maxUsesModel.OldValue.ToObject(discord.ApiClient.Serializer); - - RestUser inviter = null; - if (inviterIdModel != null) - { - var inviterId = inviterIdModel.OldValue.ToObject(discord.ApiClient.Serializer); - var inviterInfo = log.Users.FirstOrDefault(x => x.Id == inviterId); - inviter = (inviterInfo != null) ? RestUser.Create(discord, inviterInfo) : null; - } - - return new InviteDeleteAuditLogData(maxAge, code, temporary, inviter, channelId, uses, maxUses); - } - - /// - /// Gets the time (in seconds) until the invite expires. - /// - /// - /// An representing the time in seconds until this invite expires. - /// - public int MaxAge { get; } - /// - /// Gets the unique identifier for this invite. - /// - /// - /// A string containing the invite code (e.g. FTqNnyS). - /// - public string Code { get; } - /// - /// Gets a value that indicates whether the invite is a temporary one. - /// - /// - /// true if users accepting this invite will be removed from the guild when they log off; otherwise - /// false. - /// - public bool Temporary { get; } - /// - /// Gets the user that created this invite if available. - /// - /// - /// Will be if the user is a 'Deleted User#....' because Discord does send user data for deleted users. - /// - /// - /// A user that created this invite or . - /// - public IUser Creator { get; } - /// - /// Gets the ID of the channel this invite is linked to. - /// - /// - /// A representing the channel snowflake identifier that the invite points to. - /// - public ulong ChannelId { get; } - /// - /// Gets the number of times this invite has been used. - /// - /// - /// An representing the number of times this invite has been used. - /// - public int Uses { get; } - /// - /// Gets the max number of uses this invite may have. - /// - /// - /// An representing the number of uses this invite may be accepted until it is removed - /// from the guild; null if none is set. - /// - public int MaxUses { get; } + MaxAge = model.MaxAge!.Value; + Code = model.Code; + Temporary = model.Temporary!.Value; + Creator = inviter; + ChannelId = model.ChannelId!.Value; + Uses = model.Uses!.Value; + MaxUses = model.MaxUses!.Value; } + + internal static InviteDeleteAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log) + { + var changes = entry.Changes; + + var (data, _) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + RestUser inviter = null; + + if (data.InviterId != null) + { + var inviterInfo = log.Users.FirstOrDefault(x => x.Id == data.InviterId); + inviter = (inviterInfo != null) ? RestUser.Create(discord, inviterInfo) : null; + } + + return new InviteDeleteAuditLogData(data, inviter); + } + + /// + /// Gets the time (in seconds) until the invite expires. + /// + /// + /// An representing the time in seconds until this invite expires. + /// + public int MaxAge { get; } + + /// + /// Gets the unique identifier for this invite. + /// + /// + /// A string containing the invite code (e.g. FTqNnyS). + /// + public string Code { get; } + + /// + /// Gets a value that indicates whether the invite is a temporary one. + /// + /// + /// true if users accepting this invite will be removed from the guild when they log off; otherwise + /// false. + /// + public bool Temporary { get; } + + /// + /// Gets the user that created this invite if available. + /// + /// + /// Will be if the user is a 'Deleted User#....' because Discord does send user data for deleted users. + /// + /// + /// A user that created this invite or . + /// + public IUser Creator { get; } + + /// + /// Gets the ID of the channel this invite is linked to. + /// + /// + /// A representing the channel snowflake identifier that the invite points to. + /// + public ulong ChannelId { get; } + + /// + /// Gets the number of times this invite has been used. + /// + /// + /// An representing the number of times this invite has been used. + /// + public int Uses { get; } + + /// + /// Gets the max number of uses this invite may have. + /// + /// + /// An representing the number of uses this invite may be accepted until it is removed + /// from the guild; null if none is set. + /// + public int MaxUses { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/InviteInfo.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/InviteInfo.cs index aaad362d..1a3a7c56 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/InviteInfo.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/InviteInfo.cs @@ -1,57 +1,68 @@ -namespace Discord.Rest -{ - /// - /// Represents information for an invite. - /// - public struct InviteInfo - { - internal InviteInfo(int? maxAge, string code, bool? temporary, ulong? channelId, int? maxUses) - { - MaxAge = maxAge; - Code = code; - Temporary = temporary; - ChannelId = channelId; - MaxUses = maxUses; - } +using Model = Discord.API.AuditLogs.InviteInfoAuditLogModel; - /// - /// Gets the time (in seconds) until the invite expires. - /// - /// - /// An representing the time in seconds until this invite expires; null if this - /// invite never expires or not specified. - /// - public int? MaxAge { get; } - /// - /// Gets the unique identifier for this invite. - /// - /// - /// A string containing the invite code (e.g. FTqNnyS). - /// - public string Code { get; } - /// - /// Gets a value that indicates whether the invite is a temporary one. - /// - /// - /// true if users accepting this invite will be removed from the guild when they log off, - /// false if not; null if not specified. - /// - public bool? Temporary { get; } - /// - /// Gets the ID of the channel this invite is linked to. - /// - /// - /// A representing the channel snowflake identifier that the invite points to; - /// null if not specified. - /// - public ulong? ChannelId { get; } - /// - /// Gets the max number of uses this invite may have. - /// - /// - /// An representing the number of uses this invite may be accepted until it is removed - /// from the guild; null if none is specified. - /// - public int? MaxUses { get; } +namespace Discord.Rest; + +/// +/// Represents information for an invite. +/// +public struct InviteInfo +{ + internal InviteInfo(Model model) + { + MaxAge = model.MaxAge; + Code = model.Code; + Temporary = model.Temporary; + ChannelId = model.ChannelId; + MaxUses = model.MaxUses; + CreatorId = model.InviterId; } + + /// + /// Gets the time (in seconds) until the invite expires. + /// + /// + /// An representing the time in seconds until this invite expires; null if this + /// invite never expires or not specified. + /// + public int? MaxAge { get; } + + /// + /// Gets the unique identifier for this invite. + /// + /// + /// A string containing the invite code (e.g. FTqNnyS). + /// + public string Code { get; } + + /// + /// Gets a value that indicates whether the invite is a temporary one. + /// + /// + /// true if users accepting this invite will be removed from the guild when they log off, + /// false if not; null if not specified. + /// + public bool? Temporary { get; } + + /// + /// Gets the ID of the channel this invite is linked to. + /// + /// + /// A representing the channel snowflake identifier that the invite points to; + /// null if not specified. + /// + public ulong? ChannelId { get; } + + /// + /// Gets the max number of uses this invite may have. + /// + /// + /// An representing the number of uses this invite may be accepted until it is removed + /// from the guild; null if none is specified. + /// + public int? MaxUses { get; } + + /// + /// Gets the id of the user created this invite. + /// + public ulong? CreatorId { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/InviteUpdateAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/InviteUpdateAuditLogData.cs index 5d282666..766a35bd 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/InviteUpdateAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/InviteUpdateAuditLogData.cs @@ -1,60 +1,44 @@ +using Discord.API.AuditLogs; + using System.Linq; using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data relating to an invite update. +/// +public class InviteUpdateAuditLogData : IAuditLogData { - /// - /// Contains a piece of audit log data relating to an invite update. - /// - public class InviteUpdateAuditLogData : IAuditLogData + private InviteUpdateAuditLogData(InviteInfo before, InviteInfo after) { - private InviteUpdateAuditLogData(InviteInfo before, InviteInfo after) - { - Before = before; - After = after; - } - - internal static InviteUpdateAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - var changes = entry.Changes; - - var maxAgeModel = changes.FirstOrDefault(x => x.ChangedProperty == "max_age"); - var codeModel = changes.FirstOrDefault(x => x.ChangedProperty == "code"); - var temporaryModel = changes.FirstOrDefault(x => x.ChangedProperty == "temporary"); - var channelIdModel = changes.FirstOrDefault(x => x.ChangedProperty == "channel_id"); - var maxUsesModel = changes.FirstOrDefault(x => x.ChangedProperty == "max_uses"); - - int? oldMaxAge = maxAgeModel?.OldValue?.ToObject(discord.ApiClient.Serializer), - newMaxAge = maxAgeModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - string oldCode = codeModel?.OldValue?.ToObject(discord.ApiClient.Serializer), - newCode = codeModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - bool? oldTemporary = temporaryModel?.OldValue?.ToObject(discord.ApiClient.Serializer), - newTemporary = temporaryModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - ulong? oldChannelId = channelIdModel?.OldValue?.ToObject(discord.ApiClient.Serializer), - newChannelId = channelIdModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - int? oldMaxUses = maxUsesModel?.OldValue?.ToObject(discord.ApiClient.Serializer), - newMaxUses = maxUsesModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - - var before = new InviteInfo(oldMaxAge, oldCode, oldTemporary, oldChannelId, oldMaxUses); - var after = new InviteInfo(newMaxAge, newCode, newTemporary, newChannelId, newMaxUses); - - return new InviteUpdateAuditLogData(before, after); - } - - /// - /// Gets the invite information before the changes. - /// - /// - /// An information object containing the original invite information before the changes were made. - /// - public InviteInfo Before { get; } - /// - /// Gets the invite information after the changes. - /// - /// - /// An information object containing the invite information after the changes were made. - /// - public InviteInfo After { get; } + Before = before; + After = after; } + + internal static InviteUpdateAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log) + { + var changes = entry.Changes; + + var (before, after) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new InviteUpdateAuditLogData(new(before), new(after)); + } + + /// + /// Gets the invite information before the changes. + /// + /// + /// An information object containing the original invite information before the changes were made. + /// + public InviteInfo Before { get; } + + /// + /// Gets the invite information after the changes. + /// + /// + /// An information object containing the invite information after the changes were made. + /// + public InviteInfo After { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/KickAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/KickAuditLogData.cs index 02ec8a10..99b385d8 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/KickAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/KickAuditLogData.cs @@ -2,33 +2,32 @@ using System.Linq; using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to a kick. +/// +public class KickAuditLogData : IAuditLogData { - /// - /// Contains a piece of audit log data related to a kick. - /// - public class KickAuditLogData : IAuditLogData + private KickAuditLogData(RestUser user) { - private KickAuditLogData(RestUser user) - { - Target = user; - } - - internal static KickAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - var userInfo = log.Users.FirstOrDefault(x => x.Id == entry.TargetId); - return new KickAuditLogData((userInfo != null) ? RestUser.Create(discord, userInfo) : null); - } - - /// - /// Gets the user that was kicked. - /// - /// - /// Will be if the user is a 'Deleted User#....' because Discord does send user data for deleted users. - /// - /// - /// A user object representing the kicked user. - /// - public IUser Target { get; } + Target = user; } + + internal static KickAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log = null) + { + var userInfo = log.Users.FirstOrDefault(x => x.Id == entry.TargetId); + return new KickAuditLogData((userInfo != null) ? RestUser.Create(discord, userInfo) : null); + } + + /// + /// Gets the user that was kicked. + /// + /// + /// Will be if the user is a 'Deleted User#....' because Discord does send user data for deleted users. + /// + /// + /// A user object representing the kicked user. + /// + public IUser Target { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberDisconnectAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberDisconnectAuditLogData.cs index 4181d9e9..a04c1af9 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberDisconnectAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberDisconnectAuditLogData.cs @@ -1,29 +1,28 @@ using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to disconnecting members from voice channels. +/// +public class MemberDisconnectAuditLogData : IAuditLogData { - /// - /// Contains a piece of audit log data related to disconnecting members from voice channels. - /// - public class MemberDisconnectAuditLogData : IAuditLogData + private MemberDisconnectAuditLogData(int count) { - private MemberDisconnectAuditLogData(int count) - { - MemberCount = count; - } - - internal static MemberDisconnectAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - return new MemberDisconnectAuditLogData(entry.Options.Count.Value); - } - - /// - /// Gets the number of members that were disconnected. - /// - /// - /// An representing the number of members that were disconnected from a voice channel. - /// - public int MemberCount { get; } + MemberCount = count; } + + internal static MemberDisconnectAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log) + { + return new MemberDisconnectAuditLogData(entry.Options.Count.Value); + } + + /// + /// Gets the number of members that were disconnected. + /// + /// + /// An representing the number of members that were disconnected from a voice channel. + /// + public int MemberCount { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberInfo.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberInfo.cs index ffa316fa..58c4e7b8 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberInfo.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberInfo.cs @@ -1,41 +1,57 @@ -namespace Discord.Rest -{ - /// - /// Represents information for a member. - /// - public struct MemberInfo - { - internal MemberInfo(string nick, bool? deaf, bool? mute) - { - Nickname = nick; - Deaf = deaf; - Mute = mute; - } +using Discord.API.AuditLogs; +using System; - /// - /// Gets the nickname of the updated member. - /// - /// - /// A string representing the nickname of the updated member; null if none is set. - /// - public string Nickname { get; } - /// - /// Gets a value that indicates whether the updated member is deafened by the guild. - /// - /// - /// true if the updated member is deafened (i.e. not permitted to listen to or speak to others) by the guild; - /// otherwise false. - /// null if this is not mentioned in this entry. - /// - public bool? Deaf { get; } - /// - /// Gets a value that indicates whether the updated member is muted (i.e. not permitted to speak via voice) by the - /// guild. - /// - /// - /// true if the updated member is muted by the guild; otherwise false. - /// null if this is not mentioned in this entry. - /// - public bool? Mute { get; } +namespace Discord.Rest; + +/// +/// Represents information for a member. +/// +public struct MemberInfo +{ + internal MemberInfo(MemberInfoAuditLogModel model) + { + Nickname = model.Nickname; + Deaf = model.IsDeafened; + Mute = model.IsMuted; + TimedOutUntil = model.TimeOutUntil; } + + /// + /// Gets the nickname of the updated member. + /// + /// + /// A string representing the nickname of the updated member; if none is set. + /// + public string Nickname { get; } + + /// + /// Gets a value that indicates whether the updated member is deafened by the guild. + /// + /// + /// if the updated member is deafened (i.e. not permitted to listen to or speak to others) by the guild; + /// otherwise . + /// if this is not mentioned in this entry. + /// + public bool? Deaf { get; } + + /// + /// Gets a value that indicates whether the updated member is muted (i.e. not permitted to speak via voice) by the + /// guild. + /// + /// + /// if the updated member is muted by the guild; otherwise . + /// if this is not mentioned in this entry. + /// + public bool? Mute { get; } + + /// + /// Gets the date and time that indicates if and for how long the updated user has been timed out. + /// + /// + /// or a timestamp in the past if the user is not timed out. + /// + /// + /// A indicating how long the user will be timed out for. + /// + public DateTimeOffset? TimedOutUntil { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberMoveAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberMoveAuditLogData.cs index cd60d0f2..c33019b0 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberMoveAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberMoveAuditLogData.cs @@ -1,37 +1,36 @@ using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to moving members between voice channels. +/// +public class MemberMoveAuditLogData : IAuditLogData { - /// - /// Contains a piece of audit log data related to moving members between voice channels. - /// - public class MemberMoveAuditLogData : IAuditLogData + private MemberMoveAuditLogData(ulong channelId, int count) { - private MemberMoveAuditLogData(ulong channelId, int count) - { - ChannelId = channelId; - MemberCount = count; - } - - internal static MemberMoveAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - return new MemberMoveAuditLogData(entry.Options.ChannelId.Value, entry.Options.Count.Value); - } - - /// - /// Gets the ID of the channel that the members were moved to. - /// - /// - /// A representing the snowflake identifier for the channel that the members were moved to. - /// - public ulong ChannelId { get; } - /// - /// Gets the number of members that were moved. - /// - /// - /// An representing the number of members that were moved to another voice channel. - /// - public int MemberCount { get; } + ChannelId = channelId; + MemberCount = count; } + + internal static MemberMoveAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log = null) + { + return new MemberMoveAuditLogData(entry.Options.ChannelId.Value, entry.Options.Count.Value); + } + + /// + /// Gets the ID of the channel that the members were moved to. + /// + /// + /// A representing the snowflake identifier for the channel that the members were moved to. + /// + public ulong ChannelId { get; } + /// + /// Gets the number of members that were moved. + /// + /// + /// An representing the number of members that were moved to another voice channel. + /// + public int MemberCount { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberRoleAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberRoleAuditLogData.cs index 339c6150..27000f09 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberRoleAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberRoleAuditLogData.cs @@ -3,48 +3,48 @@ using System.Linq; using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to a change in a guild member's roles. +/// +public class MemberRoleAuditLogData : IAuditLogData { - /// - /// Contains a piece of audit log data related to a change in a guild member's roles. - /// - public class MemberRoleAuditLogData : IAuditLogData + private MemberRoleAuditLogData(IReadOnlyCollection roles, IUser target) { - private MemberRoleAuditLogData(IReadOnlyCollection roles, IUser target) - { - Roles = roles; - Target = target; - } - - internal static MemberRoleAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - var changes = entry.Changes; - - var roleInfos = changes.SelectMany(x => x.NewValue.ToObject(discord.ApiClient.Serializer), - (model, role) => new { model.ChangedProperty, Role = role }) - .Select(x => new MemberRoleEditInfo(x.Role.Name, x.Role.Id, x.ChangedProperty == "$add")) - .ToList(); - - var userInfo = log.Users.FirstOrDefault(x => x.Id == entry.TargetId); - RestUser user = (userInfo != null) ? RestUser.Create(discord, userInfo) : null; - - return new MemberRoleAuditLogData(roleInfos.ToReadOnlyCollection(), user); - } - - /// - /// Gets a collection of role changes that were performed on the member. - /// - /// - /// A read-only collection of , containing the roles that were changed on - /// the member. - /// - public IReadOnlyCollection Roles { get; } - /// - /// Gets the user that the roles changes were performed on. - /// - /// - /// A user object representing the user that the role changes were performed on. - /// - public IUser Target { get; } + Roles = roles; + Target = target; } + + internal static MemberRoleAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log = null) + { + var changes = entry.Changes; + + var roleInfos = changes.SelectMany(x => x.NewValue.ToObject(discord.ApiClient.Serializer), + (model, role) => new { model.ChangedProperty, Role = role }) + .Select(x => new MemberRoleEditInfo(x.Role.Name, x.Role.Id, x.ChangedProperty == "$add")) + .ToList(); + + var userInfo = log.Users.FirstOrDefault(x => x.Id == entry.TargetId); + RestUser user = (userInfo != null) ? RestUser.Create(discord, userInfo) : null; + + return new MemberRoleAuditLogData(roleInfos.ToReadOnlyCollection(), user); + } + + /// + /// Gets a collection of role changes that were performed on the member. + /// + /// + /// A read-only collection of , containing the roles that were changed on + /// the member. + /// + public IReadOnlyCollection Roles { get; } + + /// + /// Gets the user that the roles changes were performed on. + /// + /// + /// A user object representing the user that the role changes were performed on. + /// + public IUser Target { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberRoleEditInfo.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberRoleEditInfo.cs index b0abf2d9..dd178d38 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberRoleEditInfo.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberRoleEditInfo.cs @@ -1,37 +1,38 @@ -namespace Discord.Rest -{ - /// - /// An information object representing a change in one of a guild member's roles. - /// - public struct MemberRoleEditInfo - { - internal MemberRoleEditInfo(string name, ulong roleId, bool added) - { - Name = name; - RoleId = roleId; - Added = added; - } +namespace Discord.Rest; - /// - /// Gets the name of the role that was changed. - /// - /// - /// A string containing the name of the role that was changed. - /// - public string Name { get; } - /// - /// Gets the ID of the role that was changed. - /// - /// - /// A representing the snowflake identifier of the role that was changed. - /// - public ulong RoleId { get; } - /// - /// Gets a value that indicates whether the role was added to the user. - /// - /// - /// true if the role was added to the user; otherwise false. - /// - public bool Added { get; } +/// +/// An information object representing a change in one of a guild member's roles. +/// +public struct MemberRoleEditInfo +{ + internal MemberRoleEditInfo(string name, ulong roleId, bool added) + { + Name = name; + RoleId = roleId; + Added = added; } + + /// + /// Gets the name of the role that was changed. + /// + /// + /// A string containing the name of the role that was changed. + /// + public string Name { get; } + + /// + /// Gets the ID of the role that was changed. + /// + /// + /// A representing the snowflake identifier of the role that was changed. + /// + public ulong RoleId { get; } + + /// + /// Gets a value that indicates whether the role was added to the user. + /// + /// + /// true if the role was added to the user; otherwise false. + /// + public bool Added { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberUpdateAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberUpdateAuditLogData.cs index 57dca0f4..b2da83e0 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberUpdateAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MemberUpdateAuditLogData.cs @@ -1,68 +1,56 @@ +using Discord.API.AuditLogs; using System.Linq; using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to a change in a guild member. +/// +public class MemberUpdateAuditLogData : IAuditLogData { - /// - /// Contains a piece of audit log data related to a change in a guild member. - /// - public class MemberUpdateAuditLogData : IAuditLogData + private MemberUpdateAuditLogData(IUser target, MemberInfo before, MemberInfo after) { - private MemberUpdateAuditLogData(IUser target, MemberInfo before, MemberInfo after) - { - Target = target; - Before = before; - After = after; - } - - internal static MemberUpdateAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - var changes = entry.Changes; - - var nickModel = changes.FirstOrDefault(x => x.ChangedProperty == "nick"); - var deafModel = changes.FirstOrDefault(x => x.ChangedProperty == "deaf"); - var muteModel = changes.FirstOrDefault(x => x.ChangedProperty == "mute"); - - string oldNick = nickModel?.OldValue?.ToObject(discord.ApiClient.Serializer), - newNick = nickModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - bool? oldDeaf = deafModel?.OldValue?.ToObject(discord.ApiClient.Serializer), - newDeaf = deafModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - bool? oldMute = muteModel?.OldValue?.ToObject(discord.ApiClient.Serializer), - newMute = muteModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - - var targetInfo = log.Users.FirstOrDefault(x => x.Id == entry.TargetId); - RestUser user = (targetInfo != null) ? RestUser.Create(discord, targetInfo) : null; - - var before = new MemberInfo(oldNick, oldDeaf, oldMute); - var after = new MemberInfo(newNick, newDeaf, newMute); - - return new MemberUpdateAuditLogData(user, before, after); - } - - /// - /// Gets the user that the changes were performed on. - /// - /// - /// Will be if the user is a 'Deleted User#....' because Discord does send user data for deleted users. - /// - /// - /// A user object representing the user who the changes were performed on. - /// - public IUser Target { get; } - /// - /// Gets the member information before the changes. - /// - /// - /// An information object containing the original member information before the changes were made. - /// - public MemberInfo Before { get; } - /// - /// Gets the member information after the changes. - /// - /// - /// An information object containing the member information after the changes were made. - /// - public MemberInfo After { get; } + Target = target; + Before = before; + After = after; } + + internal static MemberUpdateAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log = null) + { + var changes = entry.Changes; + + var (before, after) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + var targetInfo = log.Users.FirstOrDefault(x => x.Id == entry.TargetId); + RestUser user = (targetInfo != null) ? RestUser.Create(discord, targetInfo) : null; + + return new MemberUpdateAuditLogData(user, new MemberInfo(before), new MemberInfo(after)); + } + + /// + /// Gets the user that the changes were performed on. + /// + /// + /// Will be if the user is a 'Deleted User#....' because Discord does send user data for deleted users. + /// + /// + /// A user object representing the user who the changes were performed on. + /// + public IUser Target { get; } + /// + /// Gets the member information before the changes. + /// + /// + /// An information object containing the original member information before the changes were made. + /// + public MemberInfo Before { get; } + /// + /// Gets the member information after the changes. + /// + /// + /// An information object containing the member information after the changes were made. + /// + public MemberInfo After { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MessageBulkDeleteAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MessageBulkDeleteAuditLogData.cs index ed6563d3..878cd252 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MessageBulkDeleteAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MessageBulkDeleteAuditLogData.cs @@ -1,38 +1,37 @@ using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to message deletion(s). +/// +public class MessageBulkDeleteAuditLogData : IAuditLogData { - /// - /// Contains a piece of audit log data related to message deletion(s). - /// - public class MessageBulkDeleteAuditLogData : IAuditLogData + private MessageBulkDeleteAuditLogData(ulong channelId, int count) { - private MessageBulkDeleteAuditLogData(ulong channelId, int count) - { - ChannelId = channelId; - MessageCount = count; - } - - internal static MessageBulkDeleteAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - return new MessageBulkDeleteAuditLogData(entry.TargetId.Value, entry.Options.Count.Value); - } - - /// - /// Gets the ID of the channel that the messages were deleted from. - /// - /// - /// A representing the snowflake identifier for the channel that the messages were - /// deleted from. - /// - public ulong ChannelId { get; } - /// - /// Gets the number of messages that were deleted. - /// - /// - /// An representing the number of messages that were deleted from the channel. - /// - public int MessageCount { get; } + ChannelId = channelId; + MessageCount = count; } + + internal static MessageBulkDeleteAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log) + { + return new MessageBulkDeleteAuditLogData(entry.TargetId.Value, entry.Options.Count.Value); + } + + /// + /// Gets the ID of the channel that the messages were deleted from. + /// + /// + /// A representing the snowflake identifier for the channel that the messages were + /// deleted from. + /// + public ulong ChannelId { get; } + /// + /// Gets the number of messages that were deleted. + /// + /// + /// An representing the number of messages that were deleted from the channel. + /// + public int MessageCount { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MessageDeleteAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MessageDeleteAuditLogData.cs index a4672326..7281afe9 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MessageDeleteAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MessageDeleteAuditLogData.cs @@ -3,50 +3,49 @@ using System.Linq; using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to message deletion(s). +/// +public class MessageDeleteAuditLogData : IAuditLogData { - /// - /// Contains a piece of audit log data related to message deletion(s). - /// - public class MessageDeleteAuditLogData : IAuditLogData + private MessageDeleteAuditLogData(ulong channelId, int count, IUser user) { - private MessageDeleteAuditLogData(ulong channelId, int count, IUser user) - { - ChannelId = channelId; - MessageCount = count; - Target = user; - } - - internal static MessageDeleteAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - var userInfo = log.Users.FirstOrDefault(x => x.Id == entry.TargetId); - return new MessageDeleteAuditLogData(entry.Options.ChannelId.Value, entry.Options.Count.Value, userInfo != null ? RestUser.Create(discord, userInfo) : null); - } - - /// - /// Gets the number of messages that were deleted. - /// - /// - /// An representing the number of messages that were deleted from the channel. - /// - public int MessageCount { get; } - /// - /// Gets the ID of the channel that the messages were deleted from. - /// - /// - /// A representing the snowflake identifier for the channel that the messages were - /// deleted from. - /// - public ulong ChannelId { get; } - /// - /// Gets the user of the messages that were deleted. - /// - /// - /// Will be if the user is a 'Deleted User#....' because Discord does send user data for deleted users. - /// - /// - /// A user object representing the user that created the deleted messages. - /// - public IUser Target { get; } + ChannelId = channelId; + MessageCount = count; + Target = user; } + + internal static MessageDeleteAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log) + { + var userInfo = log.Users.FirstOrDefault(x => x.Id == entry.TargetId); + return new MessageDeleteAuditLogData(entry.Options.ChannelId.Value, entry.Options.Count.Value, userInfo != null ? RestUser.Create(discord, userInfo) : null); + } + + /// + /// Gets the number of messages that were deleted. + /// + /// + /// An representing the number of messages that were deleted from the channel. + /// + public int MessageCount { get; } + /// + /// Gets the ID of the channel that the messages were deleted from. + /// + /// + /// A representing the snowflake identifier for the channel that the messages were + /// deleted from. + /// + public ulong ChannelId { get; } + /// + /// Gets the user of the messages that were deleted. + /// + /// + /// Will be if the user is a 'Deleted User#....' because Discord does send user data for deleted users. + /// + /// + /// A user object representing the user that created the deleted messages. + /// + public IUser Target { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MessagePinAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MessagePinAuditLogData.cs index b740af46..d8cadb93 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MessagePinAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MessagePinAuditLogData.cs @@ -2,55 +2,56 @@ using System.Linq; using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to a pinned message. +/// +public class MessagePinAuditLogData : IAuditLogData { - /// - /// Contains a piece of audit log data related to a pinned message. - /// - public class MessagePinAuditLogData : IAuditLogData + private MessagePinAuditLogData(ulong messageId, ulong channelId, IUser user) { - private MessagePinAuditLogData(ulong messageId, ulong channelId, IUser user) - { - MessageId = messageId; - ChannelId = channelId; - Target = user; - } - - internal static MessagePinAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - RestUser user = null; - if (entry.TargetId.HasValue) - { - var userInfo = log.Users.FirstOrDefault(x => x.Id == entry.TargetId); - user = (userInfo != null) ? RestUser.Create(discord, userInfo) : null; - } - - return new MessagePinAuditLogData(entry.Options.MessageId.Value, entry.Options.ChannelId.Value, user); - } - - /// - /// Gets the ID of the messages that was pinned. - /// - /// - /// A representing the snowflake identifier for the messages that was pinned. - /// - public ulong MessageId { get; } - /// - /// Gets the ID of the channel that the message was pinned from. - /// - /// - /// A representing the snowflake identifier for the channel that the message was pinned from. - /// - public ulong ChannelId { get; } - /// - /// Gets the user of the message that was pinned if available. - /// - /// - /// Will be if the user is a 'Deleted User#....' because Discord does send user data for deleted users. - /// - /// - /// A user object representing the user that created the pinned message or . - /// - public IUser Target { get; } + MessageId = messageId; + ChannelId = channelId; + Target = user; } + + internal static MessagePinAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log) + { + RestUser user = null; + if (entry.TargetId.HasValue) + { + var userInfo = log.Users.FirstOrDefault(x => x.Id == entry.TargetId); + user = (userInfo != null) ? RestUser.Create(discord, userInfo) : null; + } + + return new MessagePinAuditLogData(entry.Options.MessageId!.Value, entry.Options.ChannelId!.Value, user); + } + + /// + /// Gets the ID of the messages that was pinned. + /// + /// + /// A representing the snowflake identifier for the messages that was pinned. + /// + public ulong MessageId { get; } + + /// + /// Gets the ID of the channel that the message was pinned from. + /// + /// + /// A representing the snowflake identifier for the channel that the message was pinned from. + /// + public ulong ChannelId { get; } + + /// + /// Gets the user of the message that was pinned if available. + /// + /// + /// Will be if the user is a 'Deleted User#....' because Discord does send user data for deleted users. + /// + /// + /// A user object representing the user that created the pinned message or . + /// + public IUser Target { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MessageUnpinAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MessageUnpinAuditLogData.cs index 654f3e02..3526980e 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MessageUnpinAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/MessageUnpinAuditLogData.cs @@ -2,55 +2,54 @@ using System.Linq; using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to an unpinned message. +/// +public class MessageUnpinAuditLogData : IAuditLogData { - /// - /// Contains a piece of audit log data related to an unpinned message. - /// - public class MessageUnpinAuditLogData : IAuditLogData + private MessageUnpinAuditLogData(ulong messageId, ulong channelId, IUser user) { - private MessageUnpinAuditLogData(ulong messageId, ulong channelId, IUser user) - { - MessageId = messageId; - ChannelId = channelId; - Target = user; - } - - internal static MessageUnpinAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - RestUser user = null; - if (entry.TargetId.HasValue) - { - var userInfo = log.Users.FirstOrDefault(x => x.Id == entry.TargetId); - user = (userInfo != null) ? RestUser.Create(discord, userInfo) : null; - } - - return new MessageUnpinAuditLogData(entry.Options.MessageId.Value, entry.Options.ChannelId.Value, user); - } - - /// - /// Gets the ID of the messages that was unpinned. - /// - /// - /// A representing the snowflake identifier for the messages that was unpinned. - /// - public ulong MessageId { get; } - /// - /// Gets the ID of the channel that the message was unpinned from. - /// - /// - /// A representing the snowflake identifier for the channel that the message was unpinned from. - /// - public ulong ChannelId { get; } - /// - /// Gets the user of the message that was unpinned if available. - /// - /// - /// Will be if the user is a 'Deleted User#....' because Discord does send user data for deleted users. - /// - /// - /// A user object representing the user that created the unpinned message or . - /// - public IUser Target { get; } + MessageId = messageId; + ChannelId = channelId; + Target = user; } + + internal static MessageUnpinAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log) + { + RestUser user = null; + if (entry.TargetId.HasValue) + { + var userInfo = log.Users.FirstOrDefault(x => x.Id == entry.TargetId); + user = (userInfo != null) ? RestUser.Create(discord, userInfo) : null; + } + + return new MessageUnpinAuditLogData(entry.Options.MessageId.Value, entry.Options.ChannelId.Value, user); + } + + /// + /// Gets the ID of the messages that was unpinned. + /// + /// + /// A representing the snowflake identifier for the messages that was unpinned. + /// + public ulong MessageId { get; } + /// + /// Gets the ID of the channel that the message was unpinned from. + /// + /// + /// A representing the snowflake identifier for the channel that the message was unpinned from. + /// + public ulong ChannelId { get; } + /// + /// Gets the user of the message that was unpinned if available. + /// + /// + /// Will be if the user is a 'Deleted User#....' because Discord does send user data for deleted users. + /// + /// + /// A user object representing the user that created the unpinned message or . + /// + public IUser Target { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OnboardingInfo.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OnboardingInfo.cs new file mode 100644 index 00000000..b7dc5db1 --- /dev/null +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OnboardingInfo.cs @@ -0,0 +1,34 @@ +using Discord.API.AuditLogs; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; + +namespace Discord.Rest; + +public class OnboardingInfo +{ + internal OnboardingInfo(OnboardingAuditLogModel model, BaseDiscordClient discord) + { + Prompts = model.Prompts?.Select(x => new RestGuildOnboardingPrompt(discord, x.Id, x)).ToImmutableArray(); + DefaultChannelIds = model.DefaultChannelIds; + IsEnabled = model.Enabled; + } + + /// + /// + /// if this property is not mentioned in this entry. + /// + IReadOnlyCollection Prompts { get; } + + /// + /// + /// if this property is not mentioned in this entry. + /// + IReadOnlyCollection DefaultChannelIds { get; } + + /// + /// + /// if this property is not mentioned in this entry. + /// + bool? IsEnabled { get; } +} diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OnboardingPromptCreatedAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OnboardingPromptCreatedAuditLogData.cs new file mode 100644 index 00000000..a6167b91 --- /dev/null +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OnboardingPromptCreatedAuditLogData.cs @@ -0,0 +1,31 @@ +using Discord.API.AuditLogs; + +using EntryModel = Discord.API.AuditLogEntry; +using Model = Discord.API.AuditLog; + +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to an onboarding prompt creation. +/// +public class OnboardingPromptCreatedAuditLogData : IAuditLogData +{ + internal OnboardingPromptCreatedAuditLogData(OnboardingPromptInfo data) + { + Data = data; + } + + internal static OnboardingPromptCreatedAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log = null) + { + var changes = entry.Changes; + + var (_, data) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new OnboardingPromptCreatedAuditLogData(new(data, discord)); + } + + /// + /// Gets the onboarding prompt information after the changes. + /// + OnboardingPromptInfo Data { get; set; } +} diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OnboardingPromptInfo.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OnboardingPromptInfo.cs new file mode 100644 index 00000000..a28564c0 --- /dev/null +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OnboardingPromptInfo.cs @@ -0,0 +1,56 @@ +using Discord.API.AuditLogs; + +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; + +namespace Discord.Rest; + +public class OnboardingPromptInfo +{ + internal OnboardingPromptInfo(OnboardingPromptAuditLogModel model, BaseDiscordClient discord) + { + Title = model.Title; + IsSingleSelect = model.IsSingleSelect; + IsRequired = model.IsRequired; + IsInOnboarding = model.IsInOnboarding; + Type = model.Type; + Options = model.Options?.Select(x => new RestGuildOnboardingPromptOption(discord, x.Id, x)).ToImmutableArray(); + } + + /// + /// + /// if this property is not mentioned in this entry. + /// + string Title { get; } + + /// + /// + /// if this property is not mentioned in this entry. + /// + bool? IsSingleSelect { get; } + + /// + /// + /// if this property is not mentioned in this entry. + /// + bool? IsRequired { get; } + + /// + /// + /// if this property is not mentioned in this entry. + /// + bool? IsInOnboarding { get; } + + /// + /// + /// if this property is not mentioned in this entry. + /// + GuildOnboardingPromptType? Type { get; } + + /// + /// + /// if this property is not mentioned in this entry. + /// + IReadOnlyCollection Options { get; } +} diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OnboardingPromptUpdatedAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OnboardingPromptUpdatedAuditLogData.cs new file mode 100644 index 00000000..899fb670 --- /dev/null +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OnboardingPromptUpdatedAuditLogData.cs @@ -0,0 +1,38 @@ +using Discord.API.AuditLogs; + +using EntryModel = Discord.API.AuditLogEntry; +using Model = Discord.API.AuditLog; + +namespace Discord.Rest; + + +/// +/// Contains a piece of audit log data related to an onboarding prompt update. +/// +public class OnboardingPromptUpdatedAuditLogData : IAuditLogData +{ + internal OnboardingPromptUpdatedAuditLogData(OnboardingPromptInfo before, OnboardingPromptInfo after) + { + Before = before; + After = after; + } + + internal static OnboardingPromptUpdatedAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log = null) + { + var changes = entry.Changes; + + var (before, after) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new OnboardingPromptUpdatedAuditLogData(new(before, discord), new(after, discord)); + } + + /// + /// Gets the onboarding prompt information after the changes. + /// + OnboardingPromptInfo After { get; set; } + + /// + /// Gets the onboarding prompt information before the changes. + /// + OnboardingPromptInfo Before { get; set; } +} diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OnboardingUpdatedAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OnboardingUpdatedAuditLogData.cs new file mode 100644 index 00000000..3dbc3210 --- /dev/null +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OnboardingUpdatedAuditLogData.cs @@ -0,0 +1,38 @@ +using Discord.API.AuditLogs; + +using EntryModel = Discord.API.AuditLogEntry; +using Model = Discord.API.AuditLog; + +namespace Discord.Rest; + + +/// +/// Contains a piece of audit log data related to a guild update. +/// +public class OnboardingUpdatedAuditLogData : IAuditLogData +{ + internal OnboardingUpdatedAuditLogData(OnboardingInfo before, OnboardingInfo after) + { + Before = before; + After = after; + } + + internal static OnboardingUpdatedAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log = null) + { + var changes = entry.Changes; + + var (before, after) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new OnboardingUpdatedAuditLogData(new(before, discord), new(after, discord)); + } + + /// + /// Gets the onboarding information after the changes. + /// + OnboardingInfo After { get; set; } + + /// + /// Gets the onboarding information before the changes. + /// + OnboardingInfo Before { get; set; } +} diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OverwriteCreateAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OverwriteCreateAuditLogData.cs index 3990f643..67a6d6b1 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OverwriteCreateAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OverwriteCreateAuditLogData.cs @@ -1,52 +1,52 @@ using System.Linq; + using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data for a permissions overwrite creation. +/// +public class OverwriteCreateAuditLogData : IAuditLogData { - /// - /// Contains a piece of audit log data for a permissions overwrite creation. - /// - public class OverwriteCreateAuditLogData : IAuditLogData + private OverwriteCreateAuditLogData(ulong channelId, Overwrite overwrite) { - private OverwriteCreateAuditLogData(ulong channelId, Overwrite overwrite) - { - ChannelId = channelId; - Overwrite = overwrite; - } - - internal static OverwriteCreateAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - var changes = entry.Changes; - - var denyModel = changes.FirstOrDefault(x => x.ChangedProperty == "deny"); - var allowModel = changes.FirstOrDefault(x => x.ChangedProperty == "allow"); - - var deny = denyModel.NewValue.ToObject(discord.ApiClient.Serializer); - var allow = allowModel.NewValue.ToObject(discord.ApiClient.Serializer); - - var permissions = new OverwritePermissions(allow, deny); - - var id = entry.Options.OverwriteTargetId.Value; - var type = entry.Options.OverwriteType; - - return new OverwriteCreateAuditLogData(entry.TargetId.Value, new Overwrite(id, type, permissions)); - } - - /// - /// Gets the ID of the channel that the overwrite was created from. - /// - /// - /// A representing the snowflake identifier for the channel that the overwrite was - /// created from. - /// - public ulong ChannelId { get; } - /// - /// Gets the permission overwrite object that was created. - /// - /// - /// An object representing the overwrite that was created. - /// - public Overwrite Overwrite { get; } + ChannelId = channelId; + Overwrite = overwrite; } + + internal static OverwriteCreateAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log = null) + { + var changes = entry.Changes; + + var denyModel = changes.FirstOrDefault(x => x.ChangedProperty == "deny"); + var allowModel = changes.FirstOrDefault(x => x.ChangedProperty == "allow"); + + var deny = denyModel.NewValue.ToObject(discord.ApiClient.Serializer); + var allow = allowModel.NewValue.ToObject(discord.ApiClient.Serializer); + + var permissions = new OverwritePermissions(allow, deny); + + var id = entry.Options.OverwriteTargetId.Value; + var type = entry.Options.OverwriteType; + + return new OverwriteCreateAuditLogData(entry.TargetId.Value, new Overwrite(id, type, permissions)); + } + + /// + /// Gets the ID of the channel that the overwrite was created from. + /// + /// + /// A representing the snowflake identifier for the channel that the overwrite was + /// created from. + /// + public ulong ChannelId { get; } + /// + /// Gets the permission overwrite object that was created. + /// + /// + /// An object representing the overwrite that was created. + /// + public Overwrite Overwrite { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OverwriteDeleteAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OverwriteDeleteAuditLogData.cs index a959c301..ba72c970 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OverwriteDeleteAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OverwriteDeleteAuditLogData.cs @@ -2,51 +2,50 @@ using System.Linq; using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to the deletion of a permission overwrite. +/// +public class OverwriteDeleteAuditLogData : IAuditLogData { - /// - /// Contains a piece of audit log data related to the deletion of a permission overwrite. - /// - public class OverwriteDeleteAuditLogData : IAuditLogData + private OverwriteDeleteAuditLogData(ulong channelId, Overwrite deletedOverwrite) { - private OverwriteDeleteAuditLogData(ulong channelId, Overwrite deletedOverwrite) - { - ChannelId = channelId; - Overwrite = deletedOverwrite; - } - - internal static OverwriteDeleteAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - var changes = entry.Changes; - - var denyModel = changes.FirstOrDefault(x => x.ChangedProperty == "deny"); - var allowModel = changes.FirstOrDefault(x => x.ChangedProperty == "allow"); - - var deny = denyModel.OldValue.ToObject(discord.ApiClient.Serializer); - var allow = allowModel.OldValue.ToObject(discord.ApiClient.Serializer); - - var permissions = new OverwritePermissions(allow, deny); - - var id = entry.Options.OverwriteTargetId.Value; - var type = entry.Options.OverwriteType; - - return new OverwriteDeleteAuditLogData(entry.TargetId.Value, new Overwrite(id, type, permissions)); - } - - /// - /// Gets the ID of the channel that the overwrite was deleted from. - /// - /// - /// A representing the snowflake identifier for the channel that the overwrite was - /// deleted from. - /// - public ulong ChannelId { get; } - /// - /// Gets the permission overwrite object that was deleted. - /// - /// - /// An object representing the overwrite that was deleted. - /// - public Overwrite Overwrite { get; } + ChannelId = channelId; + Overwrite = deletedOverwrite; } + + internal static OverwriteDeleteAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log = null) + { + var changes = entry.Changes; + + var denyModel = changes.FirstOrDefault(x => x.ChangedProperty == "deny"); + var allowModel = changes.FirstOrDefault(x => x.ChangedProperty == "allow"); + + var deny = denyModel.OldValue.ToObject(discord.ApiClient.Serializer); + var allow = allowModel.OldValue.ToObject(discord.ApiClient.Serializer); + + var permissions = new OverwritePermissions(allow, deny); + + var id = entry.Options.OverwriteTargetId.Value; + var type = entry.Options.OverwriteType; + + return new OverwriteDeleteAuditLogData(entry.TargetId.Value, new Overwrite(id, type, permissions)); + } + + /// + /// Gets the ID of the channel that the overwrite was deleted from. + /// + /// + /// A representing the snowflake identifier for the channel that the overwrite was + /// deleted from. + /// + public ulong ChannelId { get; } + /// + /// Gets the permission overwrite object that was deleted. + /// + /// + /// An object representing the overwrite that was deleted. + /// + public Overwrite Overwrite { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OverwriteUpdateAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OverwriteUpdateAuditLogData.cs index 9aee0813..a73b5283 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OverwriteUpdateAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OverwriteUpdateAuditLogData.cs @@ -1,80 +1,80 @@ using System.Linq; + using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to the update of a permission overwrite. +/// +public class OverwriteUpdateAuditLogData : IAuditLogData { - /// - /// Contains a piece of audit log data related to the update of a permission overwrite. - /// - public class OverwriteUpdateAuditLogData : IAuditLogData + private OverwriteUpdateAuditLogData(ulong channelId, OverwritePermissions before, OverwritePermissions after, ulong targetId, PermissionTarget targetType) { - private OverwriteUpdateAuditLogData(ulong channelId, OverwritePermissions before, OverwritePermissions after, ulong targetId, PermissionTarget targetType) - { - ChannelId = channelId; - OldPermissions = before; - NewPermissions = after; - OverwriteTargetId = targetId; - OverwriteType = targetType; - } - - internal static OverwriteUpdateAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - var changes = entry.Changes; - - var denyModel = changes.FirstOrDefault(x => x.ChangedProperty == "deny"); - var allowModel = changes.FirstOrDefault(x => x.ChangedProperty == "allow"); - - var beforeAllow = allowModel?.OldValue?.ToObject(discord.ApiClient.Serializer); - var afterAllow = allowModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - var beforeDeny = denyModel?.OldValue?.ToObject(discord.ApiClient.Serializer); - var afterDeny = denyModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - - var beforePermissions = new OverwritePermissions(beforeAllow ?? 0, beforeDeny ?? 0); - var afterPermissions = new OverwritePermissions(afterAllow ?? 0, afterDeny ?? 0); - - var type = entry.Options.OverwriteType; - - return new OverwriteUpdateAuditLogData(entry.TargetId.Value, beforePermissions, afterPermissions, entry.Options.OverwriteTargetId.Value, type); - } - - /// - /// Gets the ID of the channel that the overwrite was updated from. - /// - /// - /// A representing the snowflake identifier for the channel that the overwrite was - /// updated from. - /// - public ulong ChannelId { get; } - /// - /// Gets the overwrite permissions before the changes. - /// - /// - /// An overwrite permissions object representing the overwrite permissions that the overwrite had before - /// the changes were made. - /// - public OverwritePermissions OldPermissions { get; } - /// - /// Gets the overwrite permissions after the changes. - /// - /// - /// An overwrite permissions object representing the overwrite permissions that the overwrite had after the - /// changes. - /// - public OverwritePermissions NewPermissions { get; } - /// - /// Gets the ID of the overwrite that was updated. - /// - /// - /// A representing the snowflake identifier of the overwrite that was updated. - /// - public ulong OverwriteTargetId { get; } - /// - /// Gets the target of the updated permission overwrite. - /// - /// - /// The target of the updated permission overwrite. - /// - public PermissionTarget OverwriteType { get; } + ChannelId = channelId; + OldPermissions = before; + NewPermissions = after; + OverwriteTargetId = targetId; + OverwriteType = targetType; } + + internal static OverwriteUpdateAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log = null) + { + var changes = entry.Changes; + + var denyModel = changes.FirstOrDefault(x => x.ChangedProperty == "deny"); + var allowModel = changes.FirstOrDefault(x => x.ChangedProperty == "allow"); + + var beforeAllow = allowModel?.OldValue?.ToObject(discord.ApiClient.Serializer); + var afterAllow = allowModel?.NewValue?.ToObject(discord.ApiClient.Serializer); + var beforeDeny = denyModel?.OldValue?.ToObject(discord.ApiClient.Serializer); + var afterDeny = denyModel?.NewValue?.ToObject(discord.ApiClient.Serializer); + + var beforePermissions = new OverwritePermissions(beforeAllow ?? 0, beforeDeny ?? 0); + var afterPermissions = new OverwritePermissions(afterAllow ?? 0, afterDeny ?? 0); + + var type = entry.Options.OverwriteType; + + return new OverwriteUpdateAuditLogData(entry.TargetId.Value, beforePermissions, afterPermissions, entry.Options.OverwriteTargetId.Value, type); + } + + /// + /// Gets the ID of the channel that the overwrite was updated from. + /// + /// + /// A representing the snowflake identifier for the channel that the overwrite was + /// updated from. + /// + public ulong ChannelId { get; } + /// + /// Gets the overwrite permissions before the changes. + /// + /// + /// An overwrite permissions object representing the overwrite permissions that the overwrite had before + /// the changes were made. + /// + public OverwritePermissions OldPermissions { get; } + /// + /// Gets the overwrite permissions after the changes. + /// + /// + /// An overwrite permissions object representing the overwrite permissions that the overwrite had after the + /// changes. + /// + public OverwritePermissions NewPermissions { get; } + /// + /// Gets the ID of the overwrite that was updated. + /// + /// + /// A representing the snowflake identifier of the overwrite that was updated. + /// + public ulong OverwriteTargetId { get; } + /// + /// Gets the target of the updated permission overwrite. + /// + /// + /// The target of the updated permission overwrite. + /// + public PermissionTarget OverwriteType { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/PruneAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/PruneAuditLogData.cs index 1f08eab5..25476392 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/PruneAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/PruneAuditLogData.cs @@ -1,40 +1,40 @@ using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to a guild prune. +/// +public class PruneAuditLogData : IAuditLogData { - /// - /// Contains a piece of audit log data related to a guild prune. - /// - public class PruneAuditLogData : IAuditLogData + private PruneAuditLogData(int pruneDays, int membersRemoved) { - private PruneAuditLogData(int pruneDays, int membersRemoved) - { - PruneDays = pruneDays; - MembersRemoved = membersRemoved; - } - - internal static PruneAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - return new PruneAuditLogData(entry.Options.PruneDeleteMemberDays.Value, entry.Options.PruneMembersRemoved.Value); - } - - /// - /// Gets the threshold for a guild member to not be kicked. - /// - /// - /// An representing the amount of days that a member must have been seen in the server, - /// to avoid being kicked. (i.e. If a user has not been seen for more than , they will be - /// kicked from the server) - /// - public int PruneDays { get; } - /// - /// Gets the number of members that were kicked during the purge. - /// - /// - /// An representing the number of members that were removed from this guild for having - /// not been seen within . - /// - public int MembersRemoved { get; } + PruneDays = pruneDays; + MembersRemoved = membersRemoved; } + + internal static PruneAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log = null) + { + return new PruneAuditLogData(entry.Options.PruneDeleteMemberDays.Value, entry.Options.PruneMembersRemoved.Value); + } + + /// + /// Gets the threshold for a guild member to not be kicked. + /// + /// + /// An representing the amount of days that a member must have been seen in the server, + /// to avoid being kicked. (i.e. If a user has not been seen for more than , they will be + /// kicked from the server) + /// + public int PruneDays { get; } + + /// + /// Gets the number of members that were kicked during the purge. + /// + /// + /// An representing the number of members that were removed from this guild for having + /// not been seen within . + /// + public int MembersRemoved { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/RoleCreateAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/RoleCreateAuditLogData.cs index be635ecb..c5bc2e6d 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/RoleCreateAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/RoleCreateAuditLogData.cs @@ -1,61 +1,46 @@ +using Discord.API.AuditLogs; + using System.Linq; + using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to a role creation. +/// +public class RoleCreateAuditLogData : IAuditLogData { - /// - /// Contains a piece of audit log data related to a role creation. - /// - public class RoleCreateAuditLogData : IAuditLogData + private RoleCreateAuditLogData(ulong id, RoleEditInfo props) { - private RoleCreateAuditLogData(ulong id, RoleEditInfo props) - { - RoleId = id; - Properties = props; - } - - internal static RoleCreateAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - var changes = entry.Changes; - - var colorModel = changes.FirstOrDefault(x => x.ChangedProperty == "color"); - var mentionableModel = changes.FirstOrDefault(x => x.ChangedProperty == "mentionable"); - var hoistModel = changes.FirstOrDefault(x => x.ChangedProperty == "hoist"); - var nameModel = changes.FirstOrDefault(x => x.ChangedProperty == "name"); - var permissionsModel = changes.FirstOrDefault(x => x.ChangedProperty == "permissions"); - - uint? colorRaw = colorModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - bool? mentionable = mentionableModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - bool? hoist = hoistModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - string name = nameModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - ulong? permissionsRaw = permissionsModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - - Color? color = null; - GuildPermissions? permissions = null; - - if (colorRaw.HasValue) - color = new Color(colorRaw.Value); - if (permissionsRaw.HasValue) - permissions = new GuildPermissions(permissionsRaw.Value); - - return new RoleCreateAuditLogData(entry.TargetId.Value, - new RoleEditInfo(color, mentionable, hoist, name, permissions)); - } - - /// - /// Gets the ID of the role that was created. - /// - /// - /// A representing the snowflake identifier to the role that was created. - /// - public ulong RoleId { get; } - /// - /// Gets the role information that was created. - /// - /// - /// An information object representing the properties of the role that was created. - /// - public RoleEditInfo Properties { get; } + RoleId = id; + Properties = props; } + + internal static RoleCreateAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log) + { + var changes = entry.Changes; + + var (_, data) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new RoleCreateAuditLogData(entry.TargetId!.Value, + new RoleEditInfo(data)); + } + + /// + /// Gets the ID of the role that was created. + /// + /// + /// A representing the snowflake identifier to the role that was created. + /// + public ulong RoleId { get; } + + /// + /// Gets the role information that was created. + /// + /// + /// An information object representing the properties of the role that was created. + /// + public RoleEditInfo Properties { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/RoleDeleteAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/RoleDeleteAuditLogData.cs index feb8064b..8ba448dc 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/RoleDeleteAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/RoleDeleteAuditLogData.cs @@ -1,61 +1,43 @@ -using System.Linq; +using Discord.API.AuditLogs; + using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data relating to a role deletion. +/// +public class RoleDeleteAuditLogData : IAuditLogData { - /// - /// Contains a piece of audit log data relating to a role deletion. - /// - public class RoleDeleteAuditLogData : IAuditLogData + private RoleDeleteAuditLogData(ulong id, RoleEditInfo props) { - private RoleDeleteAuditLogData(ulong id, RoleEditInfo props) - { - RoleId = id; - Properties = props; - } - - internal static RoleDeleteAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - var changes = entry.Changes; - - var colorModel = changes.FirstOrDefault(x => x.ChangedProperty == "color"); - var mentionableModel = changes.FirstOrDefault(x => x.ChangedProperty == "mentionable"); - var hoistModel = changes.FirstOrDefault(x => x.ChangedProperty == "hoist"); - var nameModel = changes.FirstOrDefault(x => x.ChangedProperty == "name"); - var permissionsModel = changes.FirstOrDefault(x => x.ChangedProperty == "permissions"); - - uint? colorRaw = colorModel?.OldValue?.ToObject(discord.ApiClient.Serializer); - bool? mentionable = mentionableModel?.OldValue?.ToObject(discord.ApiClient.Serializer); - bool? hoist = hoistModel?.OldValue?.ToObject(discord.ApiClient.Serializer); - string name = nameModel?.OldValue?.ToObject(discord.ApiClient.Serializer); - ulong? permissionsRaw = permissionsModel?.OldValue?.ToObject(discord.ApiClient.Serializer); - - Color? color = null; - GuildPermissions? permissions = null; - - if (colorRaw.HasValue) - color = new Color(colorRaw.Value); - if (permissionsRaw.HasValue) - permissions = new GuildPermissions(permissionsRaw.Value); - - return new RoleDeleteAuditLogData(entry.TargetId.Value, - new RoleEditInfo(color, mentionable, hoist, name, permissions)); - } - - /// - /// Gets the ID of the role that was deleted. - /// - /// - /// A representing the snowflake identifier to the role that was deleted. - /// - public ulong RoleId { get; } - /// - /// Gets the role information that was deleted. - /// - /// - /// An information object representing the properties of the role that was deleted. - /// - public RoleEditInfo Properties { get; } + RoleId = id; + Properties = props; } + + internal static RoleDeleteAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log) + { + var changes = entry.Changes; + + var (data, _) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new RoleDeleteAuditLogData(entry.TargetId!.Value, new RoleEditInfo(data)); + } + + /// + /// Gets the ID of the role that was deleted. + /// + /// + /// A representing the snowflake identifier to the role that was deleted. + /// + public ulong RoleId { get; } + + /// + /// Gets the role information that was deleted. + /// + /// + /// An information object representing the properties of the role that was deleted. + /// + public RoleEditInfo Properties { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/RoleEditInfo.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/RoleEditInfo.cs index 6f3d8d38..7d4ad3c1 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/RoleEditInfo.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/RoleEditInfo.cs @@ -1,59 +1,79 @@ -namespace Discord.Rest -{ - /// - /// Represents information for a role edit. - /// - public struct RoleEditInfo - { - internal RoleEditInfo(Color? color, bool? mentionable, bool? hoist, string name, - GuildPermissions? permissions) - { - Color = color; - Mentionable = mentionable; - Hoist = hoist; - Name = name; - Permissions = permissions; - } +using Model = Discord.API.AuditLogs.RoleInfoAuditLogModel; - /// - /// Gets the color of this role. - /// - /// - /// A color object representing the color assigned to this role; null if this role does not have a - /// color. - /// - public Color? Color { get; } - /// - /// Gets a value that indicates whether this role is mentionable. - /// - /// - /// true if other members can mention this role in a text channel; otherwise false; - /// null if this is not mentioned in this entry. - /// - public bool? Mentionable { get; } - /// - /// Gets a value that indicates whether this role is hoisted (i.e. its members will appear in a separate - /// section on the user list). - /// - /// - /// true if this role's members will appear in a separate section in the user list; otherwise - /// false; null if this is not mentioned in this entry. - /// - public bool? Hoist { get; } - /// - /// Gets the name of this role. - /// - /// - /// A string containing the name of this role. - /// - public string Name { get; } - /// - /// Gets the permissions assigned to this role. - /// - /// - /// A guild permissions object representing the permissions that have been assigned to this role; null - /// if no permissions have been assigned. - /// - public GuildPermissions? Permissions { get; } +namespace Discord.Rest; + +/// +/// Represents information for a role edit. +/// +public struct RoleEditInfo +{ + internal RoleEditInfo(Model model) + { + if (model.Color is not null) + Color = new Color(model.Color.Value); + else + Color = null; + + Mentionable = model.IsMentionable; + Hoist = model.Hoist; + Name = model.Name; + + if (model.Permissions is not null) + Permissions = new GuildPermissions(model.Permissions.Value); + else + Permissions = null; + + IconId = model.IconHash; } + + /// + /// Gets the color of this role. + /// + /// + /// A color object representing the color assigned to this role; null if this role does not have a + /// color. + /// + public Color? Color { get; } + + /// + /// Gets a value that indicates whether this role is mentionable. + /// + /// + /// true if other members can mention this role in a text channel; otherwise false; + /// null if this is not mentioned in this entry. + /// + public bool? Mentionable { get; } + + /// + /// Gets a value that indicates whether this role is hoisted (i.e. its members will appear in a separate + /// section on the user list). + /// + /// + /// true if this role's members will appear in a separate section in the user list; otherwise + /// false; null if this is not mentioned in this entry. + /// + public bool? Hoist { get; } + + /// + /// Gets the name of this role. + /// + /// + /// A string containing the name of this role. + /// + public string Name { get; } + + /// + /// Gets the permissions assigned to this role. + /// + /// + /// A guild permissions object representing the permissions that have been assigned to this role; null + /// if no permissions have been assigned. + /// + public GuildPermissions? Permissions { get; } + + /// + /// + /// if the value was not updated in this entry. + /// + public string IconId { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/RoleUpdateAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/RoleUpdateAuditLogData.cs index 89b2db3e..3b31931d 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/RoleUpdateAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/RoleUpdateAuditLogData.cs @@ -1,82 +1,52 @@ -using System.Linq; +using Discord.API.AuditLogs; + using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to a role update. +/// +public class RoleUpdateAuditLogData : IAuditLogData { - /// - /// Contains a piece of audit log data related to a role update. - /// - public class RoleUpdateAuditLogData : IAuditLogData + private RoleUpdateAuditLogData(ulong id, RoleEditInfo oldProps, RoleEditInfo newProps) { - private RoleUpdateAuditLogData(ulong id, RoleEditInfo oldProps, RoleEditInfo newProps) - { - RoleId = id; - Before = oldProps; - After = newProps; - } - - internal static RoleUpdateAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - var changes = entry.Changes; - - var colorModel = changes.FirstOrDefault(x => x.ChangedProperty == "color"); - var mentionableModel = changes.FirstOrDefault(x => x.ChangedProperty == "mentionable"); - var hoistModel = changes.FirstOrDefault(x => x.ChangedProperty == "hoist"); - var nameModel = changes.FirstOrDefault(x => x.ChangedProperty == "name"); - var permissionsModel = changes.FirstOrDefault(x => x.ChangedProperty == "permissions"); - - uint? oldColorRaw = colorModel?.OldValue?.ToObject(discord.ApiClient.Serializer), - newColorRaw = colorModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - bool? oldMentionable = mentionableModel?.OldValue?.ToObject(discord.ApiClient.Serializer), - newMentionable = mentionableModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - bool? oldHoist = hoistModel?.OldValue?.ToObject(discord.ApiClient.Serializer), - newHoist = hoistModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - string oldName = nameModel?.OldValue?.ToObject(discord.ApiClient.Serializer), - newName = nameModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - ulong? oldPermissionsRaw = permissionsModel?.OldValue?.ToObject(discord.ApiClient.Serializer), - newPermissionsRaw = permissionsModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - - Color? oldColor = null, - newColor = null; - GuildPermissions? oldPermissions = null, - newPermissions = null; - - if (oldColorRaw.HasValue) - oldColor = new Color(oldColorRaw.Value); - if (newColorRaw.HasValue) - newColor = new Color(newColorRaw.Value); - if (oldPermissionsRaw.HasValue) - oldPermissions = new GuildPermissions(oldPermissionsRaw.Value); - if (newPermissionsRaw.HasValue) - newPermissions = new GuildPermissions(newPermissionsRaw.Value); - - var oldProps = new RoleEditInfo(oldColor, oldMentionable, oldHoist, oldName, oldPermissions); - var newProps = new RoleEditInfo(newColor, newMentionable, newHoist, newName, newPermissions); - - return new RoleUpdateAuditLogData(entry.TargetId.Value, oldProps, newProps); - } - - /// - /// Gets the ID of the role that was changed. - /// - /// - /// A representing the snowflake identifier of the role that was changed. - /// - public ulong RoleId { get; } - /// - /// Gets the role information before the changes. - /// - /// - /// A role information object containing the role information before the changes were made. - /// - public RoleEditInfo Before { get; } - /// - /// Gets the role information after the changes. - /// - /// - /// A role information object containing the role information after the changes were made. - /// - public RoleEditInfo After { get; } + RoleId = id; + Before = oldProps; + After = newProps; } + + internal static RoleUpdateAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log) + { + var changes = entry.Changes; + + var (before, after) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new RoleUpdateAuditLogData(entry.TargetId!.Value, new(before), new(after)); + } + + /// + /// Gets the ID of the role that was changed. + /// + /// + /// A representing the snowflake identifier of the role that was changed. + /// + public ulong RoleId { get; } + + /// + /// Gets the role information before the changes. + /// + /// + /// A role information object containing the role information before the changes were made. + /// + public RoleEditInfo Before { get; } + + /// + /// Gets the role information after the changes. + /// + /// + /// A role information object containing the role information after the changes were made. + /// + public RoleEditInfo After { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ScheduledEventCreateAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ScheduledEventCreateAuditLogData.cs index 823c60a7..b4e4d07d 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ScheduledEventCreateAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ScheduledEventCreateAuditLogData.cs @@ -1,148 +1,97 @@ -using Discord.API; +using Discord.API.AuditLogs; using System; using System.Linq; using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to a scheduled event creation. +/// +public class ScheduledEventCreateAuditLogData : IAuditLogData { - /// - /// Contains a piece of audit log data related to a scheduled event creation. - /// - public class ScheduledEventCreateAuditLogData : IAuditLogData + private ScheduledEventCreateAuditLogData(ulong id, ScheduledEventInfoAuditLogModel model, IGuildScheduledEvent scheduledEvent) { - private ScheduledEventCreateAuditLogData(ulong id, ulong guildId, ulong? channelId, ulong? creatorId, string name, string description, DateTimeOffset scheduledStartTime, DateTimeOffset? scheduledEndTime, GuildScheduledEventPrivacyLevel privacyLevel, GuildScheduledEventStatus status, GuildScheduledEventType entityType, ulong? entityId, string location, RestUser creator, int userCount, string image) - { - Id = id; - GuildId = guildId; - ChannelId = channelId; - CreatorId = creatorId; - Name = name; - Description = description; - ScheduledStartTime = scheduledStartTime; - ScheduledEndTime = scheduledEndTime; - PrivacyLevel = privacyLevel; - Status = status; - EntityType = entityType; - EntityId = entityId; - Location = location; - Creator = creator; - UserCount = userCount; - Image = image; - } - - internal static ScheduledEventCreateAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - var changes = entry.Changes; - - var id = entry.TargetId.Value; - - var guildId = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "guild_id") - .NewValue.ToObject(discord.ApiClient.Serializer); - var channelId = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "channel_id") - .NewValue.ToObject(discord.ApiClient.Serializer); - var creatorId = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "channel_id") - .NewValue.ToObject>(discord.ApiClient.Serializer) - .GetValueOrDefault(); - var name = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "name") - .NewValue.ToObject(discord.ApiClient.Serializer); - var description = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "description") - .NewValue.ToObject>(discord.ApiClient.Serializer) - .GetValueOrDefault(); - var scheduledStartTime = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "scheduled_start_time") - .NewValue.ToObject(discord.ApiClient.Serializer); - var scheduledEndTime = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "scheduled_end_time") - .NewValue.ToObject(discord.ApiClient.Serializer); - var privacyLevel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "privacy_level") - .NewValue.ToObject(discord.ApiClient.Serializer); - var status = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "status") - .NewValue.ToObject(discord.ApiClient.Serializer); - var entityType = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "entity_type") - .NewValue.ToObject(discord.ApiClient.Serializer); - var entityId = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "entity_id") - .NewValue.ToObject(discord.ApiClient.Serializer); - var entityMetadata = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "entity_metadata") - .NewValue.ToObject(discord.ApiClient.Serializer); - var creator = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "creator") - .NewValue.ToObject>(discord.ApiClient.Serializer) - .GetValueOrDefault(); - var userCount = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "user_count") - .NewValue.ToObject>(discord.ApiClient.Serializer) - .GetValueOrDefault(); - var image = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "image") - .NewValue.ToObject>(discord.ApiClient.Serializer) - .GetValueOrDefault(); - - var creatorUser = creator == null ? null : RestUser.Create(discord, creator); - - return new ScheduledEventCreateAuditLogData(id, guildId, channelId, creatorId, name, description, scheduledStartTime, scheduledEndTime, privacyLevel, status, entityType, entityId, entityMetadata.Location.GetValueOrDefault(), creatorUser, userCount, image); - } - - // Doc Note: Corresponds to the *current* data - - /// - /// Gets the snowflake id of the event. - /// - public ulong Id { get; } - /// - /// Gets the snowflake id of the guild the event is associated with. - /// - public ulong GuildId { get; } - /// - /// Gets the snowflake id of the channel the event is associated with. - /// - public ulong? ChannelId { get; } - /// - /// Gets the snowflake id of the original creator of the event. - /// - public ulong? CreatorId { get; } - /// - /// Gets name of the event. - /// - public string Name { get; } - /// - /// Gets the description of the event. null if none is set. - /// - public string Description { get; } - /// - /// Gets the time the event was scheduled for. - /// - public DateTimeOffset ScheduledStartTime { get; } - /// - /// Gets the time the event was scheduled to end. - /// - public DateTimeOffset? ScheduledEndTime { get; } - /// - /// Gets the privacy level of the event. - /// - public GuildScheduledEventPrivacyLevel PrivacyLevel { get; } - /// - /// Gets the status of the event. - /// - public GuildScheduledEventStatus Status { get; } - /// - /// Gets the type of the entity associated with the event (stage / void / external). - /// - public GuildScheduledEventType EntityType { get; } - /// - /// Gets the snowflake id of the entity associated with the event (stage / void / external). - /// - public ulong? EntityId { get; } - /// - /// Gets the metadata for the entity associated with the event. - /// - public string Location { get; } - /// - /// Gets the user that originally created the event. - /// - public RestUser Creator { get; } - /// - /// Gets the count of users interested in this event. - /// - public int UserCount { get; } - /// - /// Gets the image hash of the image that was attached to the event. Null if not set. - /// - public string Image { get; } + Id = id; + ChannelId = model.ChannelId; + Name = model.Name; + Description = model.Description; + ScheduledStartTime = model.StartTime; + ScheduledEndTime = model.EndTime; + PrivacyLevel = model.PrivacyLevel!.Value; + Status = model.EventStatus!.Value; + EntityType = model.EventType!.Value; + EntityId = model.EntityId; + Location = model.Location; + Image = model.Image; + ScheduledEvent = scheduledEvent; } + + internal static ScheduledEventCreateAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log) + { + var changes = entry.Changes; + + var (_, data) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + var scheduledEvent = log.GuildScheduledEvents.FirstOrDefault(x => x.Id == entry.TargetId); + + return new ScheduledEventCreateAuditLogData(entry.TargetId!.Value, data, RestGuildEvent.Create(discord, null, scheduledEvent)); + } + + /// + /// Gets the scheduled event this log corresponds to. + /// + public IGuildScheduledEvent ScheduledEvent { get; } + + // Doc Note: Corresponds to the *current* data + + /// + /// Gets the snowflake id of the event. + /// + public ulong Id { get; } + /// + /// Gets the snowflake id of the channel the event is associated with. + /// + public ulong? ChannelId { get; } + /// + /// Gets name of the event. + /// + public string Name { get; } + /// + /// Gets the description of the event. null if none is set. + /// + public string Description { get; } + /// + /// Gets the time the event was scheduled for. + /// + public DateTimeOffset? ScheduledStartTime { get; } + /// + /// Gets the time the event was scheduled to end. + /// + public DateTimeOffset? ScheduledEndTime { get; } + /// + /// Gets the privacy level of the event. + /// + public GuildScheduledEventPrivacyLevel PrivacyLevel { get; } + /// + /// Gets the status of the event. + /// + public GuildScheduledEventStatus Status { get; } + /// + /// Gets the type of the entity associated with the event (stage / void / external). + /// + public GuildScheduledEventType EntityType { get; } + /// + /// Gets the snowflake id of the entity associated with the event (stage / void / external). + /// + public ulong? EntityId { get; } + /// + /// Gets the metadata for the entity associated with the event. + /// + public string Location { get; } + /// + /// Gets the image hash of the image that was attached to the event. Null if not set. + /// + public string Image { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ScheduledEventDeleteAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ScheduledEventDeleteAuditLogData.cs index 87502604..4fa3fa51 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ScheduledEventDeleteAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ScheduledEventDeleteAuditLogData.cs @@ -1,33 +1,97 @@ -using Discord.API; +using Discord.API.AuditLogs; using System; -using System.Linq; using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to a scheduled event deletion. +/// +public class ScheduledEventDeleteAuditLogData : IAuditLogData { - /// - /// Contains a piece of audit log data related to a scheduled event deletion. - /// - public class ScheduledEventDeleteAuditLogData : IAuditLogData + private ScheduledEventDeleteAuditLogData(ulong id, ScheduledEventInfoAuditLogModel model) { - private ScheduledEventDeleteAuditLogData(ulong id) - { - Id = id; - } - - internal static ScheduledEventDeleteAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - var id = entry.TargetId.Value; - - return new ScheduledEventDeleteAuditLogData(id); - } - - // Doc Note: Corresponds to the *current* data - - /// - /// Gets the snowflake id of the event. - /// - public ulong Id { get; } + Id = id; + ChannelId = model.ChannelId; + Name = model.Name; + Description = model.Description; + ScheduledStartTime = model.StartTime; + ScheduledEndTime = model.EndTime; + PrivacyLevel = model.PrivacyLevel; + Status = model.EventStatus; + EntityType = model.EventType; + EntityId = model.EntityId; + Location = model.Location; + Image = model.Image; } + + internal static ScheduledEventDeleteAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log) + { + var changes = entry.Changes; + + var (data, _) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new ScheduledEventDeleteAuditLogData(entry.TargetId!.Value, data); + } + + /// + /// Gets the snowflake id of the event. + /// + public ulong Id { get; } + + /// + /// Gets the snowflake id of the channel the event is associated with. + /// + public ulong? ChannelId { get; } + + /// + /// Gets name of the event. + /// + public string Name { get; } + + /// + /// Gets the description of the event. null if none is set. + /// + public string Description { get; } + + /// + /// Gets the time the event was scheduled for. + /// + public DateTimeOffset? ScheduledStartTime { get; } + + /// + /// Gets the time the event was scheduled to end. + /// + public DateTimeOffset? ScheduledEndTime { get; } + + /// + /// Gets the privacy level of the event. + /// + public GuildScheduledEventPrivacyLevel? PrivacyLevel { get; } + + /// + /// Gets the status of the event. + /// + public GuildScheduledEventStatus? Status { get; } + + /// + /// Gets the type of the entity associated with the event (stage / void / external). + /// + public GuildScheduledEventType? EntityType { get; } + + /// + /// Gets the snowflake id of the entity associated with the event (stage / void / external). + /// + public ulong? EntityId { get; } + + /// + /// Gets the metadata for the entity associated with the event. + /// + public string Location { get; } + + /// + /// Gets the image hash of the image that was attached to the event. Null if not set. + /// + public string Image { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ScheduledEventInfo.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ScheduledEventInfo.cs index 868c8e9d..c334a1d9 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ScheduledEventInfo.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ScheduledEventInfo.cs @@ -1,80 +1,81 @@ +using Discord.API.AuditLogs; + using System; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Represents information for a scheduled event. +/// +public class ScheduledEventInfo { /// - /// Represents information for a scheduled event. + /// Gets the snowflake id of the channel the event is associated with. /// - public class ScheduledEventInfo - { - /// - /// Gets the snowflake id of the guild the event is associated with. - /// - public ulong? GuildId { get; } - /// - /// Gets the snowflake id of the channel the event is associated with. 0 for events with external location. - /// - public ulong? ChannelId { get; } - /// - /// Gets name of the event. - /// - public string Name { get; } - /// - /// Gets the description of the event. null if none is set. - /// - public string Description { get; } - /// - /// Gets the time the event was scheduled for. - /// - public DateTimeOffset? ScheduledStartTime { get; } - /// - /// Gets the time the event was scheduled to end. - /// - public DateTimeOffset? ScheduledEndTime { get; } - /// - /// Gets the privacy level of the event. - /// - public GuildScheduledEventPrivacyLevel? PrivacyLevel { get; } - /// - /// Gets the status of the event. - /// - public GuildScheduledEventStatus? Status { get; } - /// - /// Gets the type of the entity associated with the event (stage / void / external). - /// - public GuildScheduledEventType? EntityType { get; } - /// - /// Gets the snowflake id of the entity associated with the event (stage / void / external). - /// - public ulong? EntityId { get; } - /// - /// Gets the metadata for the entity associated with the event. if there was no change. - /// - public Optional Location { get; } - /// - /// Gets the count of users interested in this event. - /// - public int? UserCount { get; } - /// - /// Gets the image hash of the image that was attached to the event. Null if not set. - /// - public string Image { get; } + public ulong? ChannelId { get; } - internal ScheduledEventInfo(ulong? guildId, ulong? channelId, string name, string description, DateTimeOffset? scheduledStartTime, DateTimeOffset? scheduledEndTime, GuildScheduledEventPrivacyLevel? privacyLevel, GuildScheduledEventStatus? status, GuildScheduledEventType? entityType, ulong? entityId, Optional location, int? userCount, string image) - { - GuildId = guildId; - ChannelId = channelId; - Name = name; - Description = description; - ScheduledStartTime = scheduledStartTime; - ScheduledEndTime = scheduledEndTime; - PrivacyLevel = privacyLevel; - Status = status; - EntityType = entityType; - EntityId = entityId; - Location = location; - UserCount = userCount; - Image = image; - } + /// + /// Gets name of the event. + /// + public string Name { get; } + + /// + /// Gets the description of the event. null if none is set. + /// + public string Description { get; } + + /// + /// Gets the time the event was scheduled for. + /// + public DateTimeOffset? ScheduledStartTime { get; } + + /// + /// Gets the time the event was scheduled to end. + /// + public DateTimeOffset? ScheduledEndTime { get; } + + /// + /// Gets the privacy level of the event. + /// + public GuildScheduledEventPrivacyLevel? PrivacyLevel { get; } + + /// + /// Gets the status of the event. + /// + public GuildScheduledEventStatus? Status { get; } + + /// + /// Gets the type of the entity associated with the event (stage / void / external). + /// + public GuildScheduledEventType? EntityType { get; } + + /// + /// Gets the snowflake id of the entity associated with the event (stage / void / external). + /// + public ulong? EntityId { get; } + + /// + /// Gets the metadata for the entity associated with the event. + /// + public string Location { get; } + + /// + /// Gets the image hash of the image that was attached to the event. Null if not set. + /// + public string Image { get; } + + internal ScheduledEventInfo(ScheduledEventInfoAuditLogModel model) + { + ChannelId = model.ChannelId; + Name = model.Name; + Description = model.Description; + ScheduledStartTime = model.StartTime; + ScheduledEndTime = model.EndTime; + PrivacyLevel = model.PrivacyLevel; + Status = model.EventStatus; + EntityType = model.EventType; + EntityId = model.EntityId; + Location = model.Location; + Image = model.Image; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ScheduledEventUpdateAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ScheduledEventUpdateAuditLogData.cs index e39759a4..d93e72c5 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ScheduledEventUpdateAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ScheduledEventUpdateAuditLogData.cs @@ -1,95 +1,54 @@ -using System; +using Discord.API.AuditLogs; using System.Linq; using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to a scheduled event updates. +/// +public class ScheduledEventUpdateAuditLogData : IAuditLogData { - /// - /// Contains a piece of audit log data related to a scheduled event updates. - /// - public class ScheduledEventUpdateAuditLogData : IAuditLogData + private ScheduledEventUpdateAuditLogData(ulong id, ScheduledEventInfo before, ScheduledEventInfo after, IGuildScheduledEvent scheduledEvent) { - private ScheduledEventUpdateAuditLogData(ulong id, ScheduledEventInfo before, ScheduledEventInfo after) - { - Id = id; - Before = before; - After = after; - } + Id = id; + Before = before; + After = after; + ScheduledEvent = scheduledEvent; - internal static ScheduledEventUpdateAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - var changes = entry.Changes; - - var id = entry.TargetId.Value; - - var guildId = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "guild_id"); - var channelId = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "channel_id"); - var name = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "name"); - var description = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "description"); - var scheduledStartTime = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "scheduled_start_time"); - var scheduledEndTime = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "scheduled_end_time"); - var privacyLevel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "privacy_level"); - var status = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "status"); - var entityType = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "entity_type"); - var entityId = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "entity_id"); - var location = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "location"); - var userCount = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "user_count"); - var image = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "image"); - - var before = new ScheduledEventInfo( - guildId?.OldValue.ToObject(discord.ApiClient.Serializer), - channelId == null ? null : channelId.OldValue?.ToObject(discord.ApiClient.Serializer) ?? 0, - name?.OldValue.ToObject(discord.ApiClient.Serializer), - description?.OldValue.ToObject>(discord.ApiClient.Serializer) - .GetValueOrDefault(), - scheduledStartTime?.OldValue.ToObject(discord.ApiClient.Serializer), - scheduledEndTime?.OldValue.ToObject(discord.ApiClient.Serializer), - privacyLevel?.OldValue.ToObject(discord.ApiClient.Serializer), - status?.OldValue.ToObject(discord.ApiClient.Serializer), - entityType?.OldValue.ToObject(discord.ApiClient.Serializer), - entityId?.OldValue.ToObject(discord.ApiClient.Serializer), - location == null ? Optional.Unspecified : new Optional(location.OldValue?.ToObject(discord.ApiClient.Serializer)), - userCount?.OldValue.ToObject>(discord.ApiClient.Serializer) - .GetValueOrDefault(), - image?.OldValue.ToObject>(discord.ApiClient.Serializer) - .GetValueOrDefault() - ); - var after = new ScheduledEventInfo( - guildId?.NewValue.ToObject(discord.ApiClient.Serializer), - channelId == null ? null : channelId.NewValue?.ToObject(discord.ApiClient.Serializer) ?? 0, - name?.NewValue.ToObject(discord.ApiClient.Serializer), - description?.NewValue.ToObject>(discord.ApiClient.Serializer) - .GetValueOrDefault(), - scheduledStartTime?.NewValue.ToObject(discord.ApiClient.Serializer), - scheduledEndTime?.NewValue.ToObject(discord.ApiClient.Serializer), - privacyLevel?.NewValue.ToObject(discord.ApiClient.Serializer), - status?.NewValue.ToObject(discord.ApiClient.Serializer), - entityType?.NewValue.ToObject(discord.ApiClient.Serializer), - entityId?.NewValue.ToObject(discord.ApiClient.Serializer), - location == null ? Optional.Unspecified : new Optional(location.NewValue?.ToObject(discord.ApiClient.Serializer)), - userCount?.NewValue.ToObject>(discord.ApiClient.Serializer) - .GetValueOrDefault(), - image?.NewValue.ToObject>(discord.ApiClient.Serializer) - .GetValueOrDefault() - ); - - return new ScheduledEventUpdateAuditLogData(id, before, after); - } - - // Doc Note: Corresponds to the *current* data - - /// - /// Gets the snowflake id of the event. - /// - public ulong Id { get; } - /// - /// Gets the state before the change. - /// - public ScheduledEventInfo Before { get; } - /// - /// Gets the state after the change. - /// - public ScheduledEventInfo After { get; } } + + internal static ScheduledEventUpdateAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log) + { + var changes = entry.Changes; + + var (before, after) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + var scheduledEvent = log.GuildScheduledEvents.FirstOrDefault(x => x.Id == entry.TargetId); + + return new ScheduledEventUpdateAuditLogData(entry.TargetId!.Value, new(before), new(after), RestGuildEvent.Create(discord, null, scheduledEvent)); + } + + /// + /// Gets the scheduled event this log corresponds to. + /// + public IGuildScheduledEvent ScheduledEvent { get; } + + // Doc Note: Corresponds to the *current* data + + /// + /// Gets the snowflake id of the event. + /// + public ulong Id { get; } + + /// + /// Gets the state before the change. + /// + public ScheduledEventInfo Before { get; } + + /// + /// Gets the state after the change. + /// + public ScheduledEventInfo After { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/StageInstanceCreateAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/StageInstanceCreateAuditLogData.cs index 778ecb1e..f73f71df 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/StageInstanceCreateAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/StageInstanceCreateAuditLogData.cs @@ -2,49 +2,48 @@ using System.Linq; using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to a stage going live. +/// +public class StageInstanceCreateAuditLogData : IAuditLogData { /// - /// Contains a piece of audit log data related to a stage going live. + /// Gets the topic of the stage channel. /// - public class StageInstanceCreateAuditLogData : IAuditLogData + public string Topic { get; } + + /// + /// Gets the privacy level of the stage channel. + /// + public StagePrivacyLevel PrivacyLevel { get; } + + /// + /// Gets the user who started the stage channel. + /// + public IUser User { get; } + + /// + /// Gets the Id of the stage channel. + /// + public ulong StageChannelId { get; } + + internal StageInstanceCreateAuditLogData(string topic, StagePrivacyLevel privacyLevel, IUser user, ulong channelId) { - /// - /// Gets the topic of the stage channel. - /// - public string Topic { get; } + Topic = topic; + PrivacyLevel = privacyLevel; + User = user; + StageChannelId = channelId; + } - /// - /// Gets the privacy level of the stage channel. - /// - public StagePrivacyLevel PrivacyLevel { get; } + internal static StageInstanceCreateAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log) + { + var topic = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "topic").NewValue.ToObject(discord.ApiClient.Serializer); + var privacyLevel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "privacy_level").NewValue.ToObject(discord.ApiClient.Serializer); + var user = log.Users.FirstOrDefault(x => x.Id == entry.UserId); + var channelId = entry.Options.ChannelId; - /// - /// Gets the user who started the stage channel. - /// - public IUser User { get; } - - /// - /// Gets the Id of the stage channel. - /// - public ulong StageChannelId { get; } - - internal StageInstanceCreateAuditLogData(string topic, StagePrivacyLevel privacyLevel, IUser user, ulong channelId) - { - Topic = topic; - PrivacyLevel = privacyLevel; - User = user; - StageChannelId = channelId; - } - - internal static StageInstanceCreateAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - var topic = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "topic").NewValue.ToObject(discord.ApiClient.Serializer); - var privacyLevel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "privacy_level").NewValue.ToObject(discord.ApiClient.Serializer); - var user = log.Users.FirstOrDefault(x => x.Id == entry.UserId); - var channelId = entry.Options.ChannelId; - - return new StageInstanceCreateAuditLogData(topic, privacyLevel, RestUser.Create(discord, user), channelId ?? 0); - } + return new StageInstanceCreateAuditLogData(topic, privacyLevel, RestUser.Create(discord, user), channelId ?? 0); } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/StageInstanceDeleteAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/StageInstanceDeleteAuditLogData.cs index becf0aa4..d5136a85 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/StageInstanceDeleteAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/StageInstanceDeleteAuditLogData.cs @@ -2,49 +2,48 @@ using System.Linq; using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to a stage instance deleted. +/// +public class StageInstanceDeleteAuditLogData : IAuditLogData { /// - /// Contains a piece of audit log data related to a stage instance deleted. + /// Gets the topic of the stage channel. /// - public class StageInstanceDeleteAuditLogData + public string Topic { get; } + + /// + /// Gets the privacy level of the stage channel. + /// + public StagePrivacyLevel PrivacyLevel { get; } + + /// + /// Gets the user who started the stage channel. + /// + public IUser User { get; } + + /// + /// Gets the Id of the stage channel. + /// + public ulong StageChannelId { get; } + + internal StageInstanceDeleteAuditLogData(string topic, StagePrivacyLevel privacyLevel, IUser user, ulong channelId) { - /// - /// Gets the topic of the stage channel. - /// - public string Topic { get; } + Topic = topic; + PrivacyLevel = privacyLevel; + User = user; + StageChannelId = channelId; + } - /// - /// Gets the privacy level of the stage channel. - /// - public StagePrivacyLevel PrivacyLevel { get; } + internal static StageInstanceDeleteAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log) + { + var topic = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "topic").OldValue.ToObject(discord.ApiClient.Serializer); + var privacyLevel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "privacy_level").OldValue.ToObject(discord.ApiClient.Serializer); + var user = log.Users.FirstOrDefault(x => x.Id == entry.UserId); + var channelId = entry.Options.ChannelId; - /// - /// Gets the user who started the stage channel. - /// - public IUser User { get; } - - /// - /// Gets the Id of the stage channel. - /// - public ulong StageChannelId { get; } - - internal StageInstanceDeleteAuditLogData(string topic, StagePrivacyLevel privacyLevel, IUser user, ulong channelId) - { - Topic = topic; - PrivacyLevel = privacyLevel; - User = user; - StageChannelId = channelId; - } - - internal static StageInstanceDeleteAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - var topic = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "topic").OldValue.ToObject(discord.ApiClient.Serializer); - var privacyLevel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "privacy_level").OldValue.ToObject(discord.ApiClient.Serializer); - var user = log.Users.FirstOrDefault(x => x.Id == entry.UserId); - var channelId = entry.Options.ChannelId; - - return new StageInstanceDeleteAuditLogData(topic, privacyLevel, RestUser.Create(discord, user), channelId ?? 0); - } + return new StageInstanceDeleteAuditLogData(topic, privacyLevel, RestUser.Create(discord, user), channelId ?? 0); } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/StageInstanceUpdatedAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/StageInstanceUpdatedAuditLogData.cs index dfcf1386..d661a486 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/StageInstanceUpdatedAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/StageInstanceUpdatedAuditLogData.cs @@ -2,50 +2,49 @@ using System.Linq; using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to a stage instance update. +/// +public class StageInstanceUpdatedAuditLogData : IAuditLogData { /// - /// Contains a piece of audit log data related to a stage instance update. + /// Gets the Id of the stage channel. /// - public class StageInstanceUpdatedAuditLogData + public ulong StageChannelId { get; } + + /// + /// Gets the stage information before the changes. + /// + public StageInfo Before { get; } + + /// + /// Gets the stage information after the changes. + /// + public StageInfo After { get; } + + internal StageInstanceUpdatedAuditLogData(ulong channelId, StageInfo before, StageInfo after) { - /// - /// Gets the Id of the stage channel. - /// - public ulong StageChannelId { get; } + StageChannelId = channelId; + Before = before; + After = after; + } - /// - /// Gets the stage information before the changes. - /// - public StageInfo Before { get; } + internal static StageInstanceUpdatedAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log) + { + var channelId = entry.Options.ChannelId.Value; - /// - /// Gets the stage information after the changes. - /// - public StageInfo After { get; } + var topic = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "topic"); + var privacy = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "privacy"); - internal StageInstanceUpdatedAuditLogData(ulong channelId, StageInfo before, StageInfo after) - { - StageChannelId = channelId; - Before = before; - After = after; - } + var user = RestUser.Create(discord, log.Users.FirstOrDefault(x => x.Id == entry.UserId)); - internal static StageInstanceUpdatedAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - var channelId = entry.Options.ChannelId.Value; + var oldTopic = topic?.OldValue.ToObject(); + var newTopic = topic?.NewValue.ToObject(); + var oldPrivacy = privacy?.OldValue.ToObject(); + var newPrivacy = privacy?.NewValue.ToObject(); - var topic = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "topic"); - var privacy = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "privacy"); - - var user = RestUser.Create(discord, log.Users.FirstOrDefault(x => x.Id == entry.UserId)); - - var oldTopic = topic?.OldValue.ToObject(); - var newTopic = topic?.NewValue.ToObject(); - var oldPrivacy = privacy?.OldValue.ToObject(); - var newPrivacy = privacy?.NewValue.ToObject(); - - return new StageInstanceUpdatedAuditLogData(channelId, new StageInfo(user, oldPrivacy, oldTopic), new StageInfo(user, newPrivacy, newTopic)); - } + return new StageInstanceUpdatedAuditLogData(channelId, new StageInfo(user, oldPrivacy, oldTopic), new StageInfo(user, newPrivacy, newTopic)); } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/StickerCreatedAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/StickerCreatedAuditLogData.cs new file mode 100644 index 00000000..c7462859 --- /dev/null +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/StickerCreatedAuditLogData.cs @@ -0,0 +1,29 @@ +using Discord.API.AuditLogs; +using EntryModel = Discord.API.AuditLogEntry; +using Model = Discord.API.AuditLog; + +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to a sticker creation. +/// +public class StickerCreatedAuditLogData : IAuditLogData +{ + internal StickerCreatedAuditLogData(StickerInfo data) + { + Data = data; + } + + internal static StickerCreatedAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log = null) + { + var changes = entry.Changes; + var (_, data) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new StickerCreatedAuditLogData(new(data)); + } + + /// + /// Gets the sticker information after the changes. + /// + public StickerInfo Data { get; } +} diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/StickerDeletedAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/StickerDeletedAuditLogData.cs new file mode 100644 index 00000000..8616dcf6 --- /dev/null +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/StickerDeletedAuditLogData.cs @@ -0,0 +1,29 @@ +using Discord.API.AuditLogs; +using EntryModel = Discord.API.AuditLogEntry; +using Model = Discord.API.AuditLog; + +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to a sticker removal. +/// +public class StickerDeletedAuditLogData : IAuditLogData +{ + internal StickerDeletedAuditLogData(StickerInfo data) + { + Data = data; + } + + internal static StickerDeletedAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log = null) + { + var changes = entry.Changes; + var (data, _) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new StickerDeletedAuditLogData(new(data)); + } + + /// + /// Gets the sticker information before the changes. + /// + public StickerInfo Data { get; } +} diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/StickerInfo.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/StickerInfo.cs new file mode 100644 index 00000000..acba67e4 --- /dev/null +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/StickerInfo.cs @@ -0,0 +1,31 @@ +using Discord.API.AuditLogs; + +namespace Discord.Rest; + +/// +/// Represents information for a guild. +/// +public class StickerInfo +{ + internal StickerInfo(StickerInfoAuditLogModel model) + { + Name = model.Name; + Tags = model.Tags; + Description = model.Description; + } + + /// + /// Gets the name of the sticker. if the value was not updated in this entry. + /// + public string Name { get; set; } + + /// + /// Gets tags of the sticker. if the value was not updated in this entry. + /// + public string Tags { get; set; } + + /// + /// Gets the description of the sticker. if the value was not updated in this entry. + /// + public string Description { get; set; } +} diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/StickerUpdatedAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/StickerUpdatedAuditLogData.cs new file mode 100644 index 00000000..9e71850e --- /dev/null +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/StickerUpdatedAuditLogData.cs @@ -0,0 +1,35 @@ +using Discord.API.AuditLogs; +using EntryModel = Discord.API.AuditLogEntry; +using Model = Discord.API.AuditLog; + +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to a sticker update. +/// +public class StickerUpdatedAuditLogData : IAuditLogData +{ + internal StickerUpdatedAuditLogData(StickerInfo before, StickerInfo after) + { + Before = before; + After = after; + } + + internal static StickerUpdatedAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log = null) + { + var changes = entry.Changes; + var (before, after) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new StickerUpdatedAuditLogData(new(before), new (after)); + } + + /// + /// Gets the sticker information before the changes. + /// + public StickerInfo Before { get; } + + /// + /// Gets the sticker information after the changes. + /// + public StickerInfo After { get; } +} diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ThreadCreateAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ThreadCreateAuditLogData.cs index d93529a2..5969b457 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ThreadCreateAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ThreadCreateAuditLogData.cs @@ -1,114 +1,123 @@ +using Discord.API.AuditLogs; + +using System.Collections.Generic; using System.Linq; using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to a thread creation. +/// +public class ThreadCreateAuditLogData : IAuditLogData { - /// - /// Contains a piece of audit log data related to a thread creation. - /// - public class ThreadCreateAuditLogData : IAuditLogData + private ThreadCreateAuditLogData(IThreadChannel thread, ulong id, ThreadInfoAuditLogModel model) { - private ThreadCreateAuditLogData(IThreadChannel thread, ulong id, string name, ThreadType type, bool archived, - ThreadArchiveDuration autoArchiveDuration, bool locked, int? rateLimit) - { - Thread = thread; - ThreadId = id; - ThreadName = name; - ThreadType = type; - IsArchived = archived; - AutoArchiveDuration = autoArchiveDuration; - IsLocked = locked; - SlowModeInterval = rateLimit; - } + Thread = thread; + ThreadId = id; - internal static ThreadCreateAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - var changes = entry.Changes; - - var id = entry.TargetId.Value; - - var nameModel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "name"); - var typeModel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "type"); - - var archivedModel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "archived"); - var autoArchiveDurationModel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "auto_archive_duration"); - var lockedModel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "locked"); - var rateLimitPerUserModel = changes.FirstOrDefault(x => x.ChangedProperty == "rate_limit_per_user"); - - var name = nameModel.NewValue.ToObject(discord.ApiClient.Serializer); - var type = typeModel.NewValue.ToObject(discord.ApiClient.Serializer); - - var archived = archivedModel.NewValue.ToObject(discord.ApiClient.Serializer); - var autoArchiveDuration = autoArchiveDurationModel.NewValue.ToObject(discord.ApiClient.Serializer); - var locked = lockedModel.NewValue.ToObject(discord.ApiClient.Serializer); - var rateLimit = rateLimitPerUserModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - - var threadInfo = log.Threads.FirstOrDefault(x => x.Id == id); - var threadChannel = threadInfo == null ? null : RestThreadChannel.Create(discord, (IGuild)null, threadInfo); - - return new ThreadCreateAuditLogData(threadChannel, id, name, type, archived, autoArchiveDuration, locked, rateLimit); - } - - // Doc Note: Corresponds to the *current* data - - /// - /// Gets the thread that was created if it still exists. - /// - /// - /// A thread object representing the thread that was created if it still exists, otherwise returns null. - /// - public IThreadChannel Thread { get; } - /// - /// Gets the snowflake ID of the thread. - /// - /// - /// A representing the snowflake identifier for the thread. - /// - public ulong ThreadId { get; } - /// - /// Gets the name of the thread. - /// - /// - /// A string containing the name of the thread. - /// - public string ThreadName { get; } - /// - /// Gets the type of the thread. - /// - /// - /// The type of thread. - /// - public ThreadType ThreadType { get; } - /// - /// Gets the value that indicates whether the thread is archived. - /// - /// - /// true if this thread has the Archived flag enabled; otherwise false. - /// - public bool IsArchived { get; } - /// - /// Gets the auto archive duration of the thread. - /// - /// - /// The thread auto archive duration of the thread. - /// - public ThreadArchiveDuration AutoArchiveDuration { get; } - /// - /// Gets the value that indicates whether the thread is locked. - /// - /// - /// true if this thread has the Locked flag enabled; otherwise false. - /// - public bool IsLocked { get; } - /// - /// Gets the slow-mode delay of the thread. - /// - /// - /// An representing the time in seconds required before the user can send another - /// message; 0 if disabled. - /// null if this is not mentioned in this entry. - /// - public int? SlowModeInterval { get; } + ThreadName = model.Name; + IsArchived = model.IsArchived!.Value; + AutoArchiveDuration = model.ArchiveDuration!.Value; + IsLocked = model.IsLocked!.Value; + SlowModeInterval = model.SlowModeInterval; + AppliedTags = model.AppliedTags; + Flags = model.ChannelFlags; + ThreadType = model.Type; } + + internal static ThreadCreateAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log) + { + var changes = entry.Changes; + + var (_, data) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + var threadInfo = log.Threads.FirstOrDefault(x => x.Id == entry.TargetId!.Value); + var threadChannel = threadInfo == null ? null : RestThreadChannel.Create(discord, (IGuild)null, threadInfo); + + return new ThreadCreateAuditLogData(threadChannel, entry.TargetId!.Value, data); + } + + /// + /// Gets the thread that was created if it still exists. + /// + /// + /// A thread object representing the thread that was created if it still exists, otherwise returns null. + /// + public IThreadChannel Thread { get; } + + /// + /// Gets the snowflake ID of the thread. + /// + /// + /// A representing the snowflake identifier for the thread. + /// + public ulong ThreadId { get; } + + /// + /// Gets the name of the thread. + /// + /// + /// A string containing the name of the thread. + /// + public string ThreadName { get; } + + /// + /// Gets the type of the thread. + /// + /// + /// The type of thread. + /// + public ThreadType ThreadType { get; } + + /// + /// Gets the value that indicates whether the thread is archived. + /// + /// + /// true if this thread has the Archived flag enabled; otherwise false. + /// + public bool IsArchived { get; } + + /// + /// Gets the auto archive duration of the thread. + /// + /// + /// The thread auto archive duration of the thread. + /// + public ThreadArchiveDuration AutoArchiveDuration { get; } + + /// + /// Gets the value that indicates whether the thread is locked. + /// + /// + /// true if this thread has the Locked flag enabled; otherwise false. + /// + public bool IsLocked { get; } + + /// + /// Gets the slow-mode delay of the thread. + /// + /// + /// An representing the time in seconds required before the user can send another + /// message; 0 if disabled. + /// null if this is not mentioned in this entry. + /// + public int? SlowModeInterval { get; } + + /// + /// Gets the applied tags of this thread. + /// + /// + /// if the property was not updated. + /// + public IReadOnlyCollection AppliedTags { get; } + + /// + /// Gets the flags of the thread channel. + /// + /// + /// if the property was not updated. + /// + public ChannelFlags? Flags { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ThreadDeleteAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ThreadDeleteAuditLogData.cs index 31e6420c..abf1fea1 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ThreadDeleteAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ThreadDeleteAuditLogData.cs @@ -1,102 +1,111 @@ -using System.Linq; +using Discord.API.AuditLogs; +using System.Collections.Generic; using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to a thread deletion. +/// +public class ThreadDeleteAuditLogData : IAuditLogData { - /// - /// Contains a piece of audit log data related to a thread deletion. - /// - public class ThreadDeleteAuditLogData : IAuditLogData + private ThreadDeleteAuditLogData(ulong id, ThreadInfoAuditLogModel model) { - private ThreadDeleteAuditLogData(ulong id, string name, ThreadType type, bool archived, - ThreadArchiveDuration autoArchiveDuration, bool locked, int? rateLimit) - { - ThreadId = id; - ThreadName = name; - ThreadType = type; - IsArchived = archived; - AutoArchiveDuration = autoArchiveDuration; - IsLocked = locked; - SlowModeInterval = rateLimit; - } + ThreadId = id; - internal static ThreadDeleteAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - var changes = entry.Changes; - - var id = entry.TargetId.Value; - var thread = log.Threads.FirstOrDefault(x => x.Id == id); - - var nameModel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "name"); - var typeModel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "type"); - - var archivedModel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "archived"); - var autoArchiveDurationModel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "auto_archive_duration"); - var lockedModel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "locked"); - var rateLimitPerUserModel = changes.FirstOrDefault(x => x.ChangedProperty == "rate_limit_per_user"); - - var name = nameModel.OldValue.ToObject(discord.ApiClient.Serializer); - var type = typeModel.OldValue.ToObject(discord.ApiClient.Serializer); - - var archived = archivedModel.OldValue.ToObject(discord.ApiClient.Serializer); - var autoArchiveDuration = autoArchiveDurationModel.OldValue.ToObject(discord.ApiClient.Serializer); - var locked = lockedModel.OldValue.ToObject(discord.ApiClient.Serializer); - var rateLimit = rateLimitPerUserModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - - return new ThreadDeleteAuditLogData(id, name, type, archived, autoArchiveDuration, locked, rateLimit); - } - - /// - /// Gets the snowflake ID of the deleted thread. - /// - /// - /// A representing the snowflake identifier for the deleted thread. - /// - public ulong ThreadId { get; } - /// - /// Gets the name of the deleted thread. - /// - /// - /// A string containing the name of the deleted thread. - /// - public string ThreadName { get; } - /// - /// Gets the type of the deleted thread. - /// - /// - /// The type of thread that was deleted. - /// - public ThreadType ThreadType { get; } - /// - /// Gets the value that indicates whether the deleted thread was archived. - /// - /// - /// true if this thread had the Archived flag enabled; otherwise false. - /// - public bool IsArchived { get; } - /// - /// Gets the thread auto archive duration of the deleted thread. - /// - /// - /// The thread auto archive duration of the thread that was deleted. - /// - public ThreadArchiveDuration AutoArchiveDuration { get; } - /// - /// Gets the value that indicates whether the deleted thread was locked. - /// - /// - /// true if this thread had the Locked flag enabled; otherwise false. - /// - public bool IsLocked { get; } - /// - /// Gets the slow-mode delay of the deleted thread. - /// - /// - /// An representing the time in seconds required before the user can send another - /// message; 0 if disabled. - /// null if this is not mentioned in this entry. - /// - public int? SlowModeInterval { get; } + ThreadName = model.Name; + IsArchived = model.IsArchived!.Value; + AutoArchiveDuration = model.ArchiveDuration!.Value; + IsLocked = model.IsLocked!.Value; + SlowModeInterval = model.SlowModeInterval; + AppliedTags = model.AppliedTags; + Flags = model.ChannelFlags; + ThreadType = model.Type; } + + internal static ThreadDeleteAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log) + { + var changes = entry.Changes; + + var (data, _) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new ThreadDeleteAuditLogData(entry.TargetId!.Value, data); + } + + /// + /// Gets the snowflake ID of the deleted thread. + /// + /// + /// A representing the snowflake identifier for the deleted thread. + /// + /// + public ulong ThreadId { get; } + + /// + /// Gets the name of the deleted thread. + /// + /// + /// A string containing the name of the deleted thread. + /// + /// + public string ThreadName { get; } + + /// + /// Gets the type of the deleted thread. + /// + /// + /// The type of thread that was deleted. + /// + public ThreadType ThreadType { get; } + + /// + /// Gets the value that indicates whether the deleted thread was archived. + /// + /// + /// true if this thread had the Archived flag enabled; otherwise false. + /// + public bool IsArchived { get; } + + /// + /// Gets the thread auto archive duration of the deleted thread. + /// + /// + /// The thread auto archive duration of the thread that was deleted. + /// + public ThreadArchiveDuration AutoArchiveDuration { get; } + + /// + /// Gets the value that indicates whether the deleted thread was locked. + /// + /// + /// true if this thread had the Locked flag enabled; otherwise false. + /// + public bool IsLocked { get; } + + /// + /// Gets the slow-mode delay of the deleted thread. + /// + /// + /// An representing the time in seconds required before the user can send another + /// message; 0 if disabled. + /// null if this is not mentioned in this entry. + /// + public int? SlowModeInterval { get; } + + /// + /// Gets the applied tags of this thread. + /// + /// + /// if this is not mentioned in this entry. + /// + public IReadOnlyCollection AppliedTags { get; } + + /// + /// Gets the flags of the thread channel. + /// + /// + /// if this is not mentioned in this entry. + /// + public ChannelFlags? Flags { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ThreadInfo.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ThreadInfo.cs index 0e01ba8a..ba53bd11 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ThreadInfo.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ThreadInfo.cs @@ -1,39 +1,84 @@ -namespace Discord.Rest +using Discord.API.AuditLogs; +using System; +using System.Collections.Generic; + +namespace Discord.Rest; + +/// +/// Represents information for a thread. +/// +public class ThreadInfo { /// - /// Represents information for a thread. + /// Gets the name of the thread. /// - public class ThreadInfo + public string Name { get; } + + /// + /// Gets the value that indicates whether the thread is archived. + /// + /// + /// if the property was not updated. + /// + public bool? IsArchived { get; } + + /// + /// Gets the auto archive duration of thread. + /// + /// + /// if the property was not updated. + /// + public ThreadArchiveDuration? AutoArchiveDuration { get; } + + /// + /// Gets the value that indicates whether the thread is locked. + /// + /// + /// if the property was not updated. + /// + public bool? IsLocked { get; } + + /// + /// Gets the slow-mode delay of the thread. + /// + /// + /// if the property was not updated. + /// + public int? SlowModeInterval { get; } + + /// + /// Gets the applied tags of this thread. + /// + /// + /// if the property was not updated. + /// + public IReadOnlyCollection AppliedTags { get; } + + /// + /// Gets the flags of the thread channel. + /// + /// + /// if the property was not updated. + /// + public ChannelFlags? Flags { get; } + + /// + /// Gets the type of the thread. + /// + /// + /// if the property was not updated. + /// + public ThreadType Type { get; } + + internal ThreadInfo(ThreadInfoAuditLogModel model) { - /// - /// Gets the name of the thread. - /// - public string Name { get; } - /// - /// Gets the value that indicates whether the thread is archived. - /// - public bool IsArchived { get; } - /// - /// Gets the auto archive duration of thread. - /// - public ThreadArchiveDuration AutoArchiveDuration { get; } - /// - /// Gets the value that indicates whether the thread is locked. - /// - public bool IsLocked { get; } - - /// - /// Gets the slow-mode delay of the ´thread. - /// - public int? SlowModeInterval { get; } - - internal ThreadInfo(string name, bool archived, ThreadArchiveDuration autoArchiveDuration, bool locked, int? rateLimit) - { - Name = name; - IsArchived = archived; - AutoArchiveDuration = autoArchiveDuration; - IsLocked = locked; - SlowModeInterval = rateLimit; - } + Name = model.Name; + IsArchived = model.IsArchived; + AutoArchiveDuration = model.ArchiveDuration; + IsLocked = model.IsLocked; + SlowModeInterval = model.SlowModeInterval; + AppliedTags = model.AppliedTags; + Flags = model.ChannelFlags; + Type = model.Type; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ThreadUpdateAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ThreadUpdateAuditLogData.cs index 9eb6b56d..b7343aad 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ThreadUpdateAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ThreadUpdateAuditLogData.cs @@ -1,87 +1,67 @@ +using Discord.API.AuditLogs; + using System.Linq; using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to a thread update. +/// +public class ThreadUpdateAuditLogData : IAuditLogData { - /// - /// Contains a piece of audit log data related to a thread update. - /// - public class ThreadUpdateAuditLogData : IAuditLogData + private ThreadUpdateAuditLogData(IThreadChannel thread, ThreadType type, ThreadInfo before, ThreadInfo after) { - private ThreadUpdateAuditLogData(IThreadChannel thread, ThreadType type, ThreadInfo before, ThreadInfo after) - { - Thread = thread; - ThreadType = type; - Before = before; - After = after; - } - - internal static ThreadUpdateAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - var changes = entry.Changes; - - var id = entry.TargetId.Value; - - var nameModel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "name"); - var typeModel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "type"); - - var archivedModel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "archived"); - var autoArchiveDurationModel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "auto_archive_duration"); - var lockedModel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "locked"); - var rateLimitPerUserModel = changes.FirstOrDefault(x => x.ChangedProperty == "rate_limit_per_user"); - - var type = typeModel.OldValue.ToObject(discord.ApiClient.Serializer); - - var oldName = nameModel.OldValue.ToObject(discord.ApiClient.Serializer); - var oldArchived = archivedModel.OldValue.ToObject(discord.ApiClient.Serializer); - var oldAutoArchiveDuration = autoArchiveDurationModel.OldValue.ToObject(discord.ApiClient.Serializer); - var oldLocked = lockedModel.OldValue.ToObject(discord.ApiClient.Serializer); - var oldRateLimit = rateLimitPerUserModel?.OldValue?.ToObject(discord.ApiClient.Serializer); - var before = new ThreadInfo(oldName, oldArchived, oldAutoArchiveDuration, oldLocked, oldRateLimit); - - var newName = nameModel.NewValue.ToObject(discord.ApiClient.Serializer); - var newArchived = archivedModel.NewValue.ToObject(discord.ApiClient.Serializer); - var newAutoArchiveDuration = autoArchiveDurationModel.NewValue.ToObject(discord.ApiClient.Serializer); - var newLocked = lockedModel.NewValue.ToObject(discord.ApiClient.Serializer); - var newRateLimit = rateLimitPerUserModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - var after = new ThreadInfo(newName, newArchived, newAutoArchiveDuration, newLocked, newRateLimit); - - var threadInfo = log.Threads.FirstOrDefault(x => x.Id == id); - var threadChannel = threadInfo == null ? null : RestThreadChannel.Create(discord, (IGuild)null, threadInfo); - - return new ThreadUpdateAuditLogData(threadChannel, type, before, after); - } - - // Doc Note: Corresponds to the *current* data - - /// - /// Gets the thread that was created if it still exists. - /// - /// - /// A thread object representing the thread that was created if it still exists, otherwise returns null. - /// - public IThreadChannel Thread { get; } - /// - /// Gets the type of the thread. - /// - /// - /// The type of thread. - /// - public ThreadType ThreadType { get; } - /// - /// Gets the thread information before the changes. - /// - /// - /// A thread information object representing the thread before the changes were made. - /// - public ThreadInfo Before { get; } - /// - /// Gets the thread information after the changes. - /// - /// - /// A thread information object representing the thread after the changes were made. - /// - public ThreadInfo After { get; } + Thread = thread; + ThreadType = type; + Before = before; + After = after; } + + internal static ThreadUpdateAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log) + { + var changes = entry.Changes; + + var (before, after) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + var threadInfo = log.Threads.FirstOrDefault(x => x.Id == entry.TargetId!.Value); + var threadChannel = threadInfo == null ? null : RestThreadChannel.Create(discord, (IGuild)null, threadInfo); + + return new ThreadUpdateAuditLogData(threadChannel, before.Type, new(before), new (after)); + } + + // Doc Note: Corresponds to the *current* data + + /// + /// Gets the thread that was created if it still exists. + /// + /// + /// A thread object representing the thread that was created if it still exists, otherwise returns null. + /// + public IThreadChannel Thread { get; } + + /// + /// Gets the type of the thread. + /// + /// + /// The type of thread. + /// + public ThreadType ThreadType { get; } + + /// + /// Gets the thread information before the changes. + /// + /// + /// A thread information object representing the thread before the changes were made. + /// + public ThreadInfo Before { get; } + + /// + /// Gets the thread information after the changes. + /// + /// + /// A thread information object representing the thread after the changes were made. + /// + public ThreadInfo After { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/UnbanAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/UnbanAuditLogData.cs index df8da5ff..39f97b1f 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/UnbanAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/UnbanAuditLogData.cs @@ -2,30 +2,29 @@ using System.Linq; using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to an unban. +/// +public class UnbanAuditLogData : IAuditLogData { - /// - /// Contains a piece of audit log data related to an unban. - /// - public class UnbanAuditLogData : IAuditLogData + private UnbanAuditLogData(IUser user) { - private UnbanAuditLogData(IUser user) - { - Target = user; - } - - internal static UnbanAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - var userInfo = log.Users.FirstOrDefault(x => x.Id == entry.TargetId); - return new UnbanAuditLogData((userInfo != null) ? RestUser.Create(discord, userInfo) : null); - } - - /// - /// Gets the user that was unbanned. - /// - /// - /// A user object representing the user that was unbanned. - /// - public IUser Target { get; } + Target = user; } + + internal static UnbanAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log = null) + { + var userInfo = log.Users.FirstOrDefault(x => x.Id == entry.TargetId); + return new UnbanAuditLogData((userInfo != null) ? RestUser.Create(discord, userInfo) : null); + } + + /// + /// Gets the user that was unbanned. + /// + /// + /// A user object representing the user that was unbanned. + /// + public IUser Target { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/WebhookCreateAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/WebhookCreateAuditLogData.cs index ff6bc944..6b91f243 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/WebhookCreateAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/WebhookCreateAuditLogData.cs @@ -1,83 +1,87 @@ +using Discord.API.AuditLogs; using System.Linq; + using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to a webhook creation. +/// +public class WebhookCreateAuditLogData : IAuditLogData { - /// - /// Contains a piece of audit log data related to a webhook creation. - /// - public class WebhookCreateAuditLogData : IAuditLogData + private WebhookCreateAuditLogData(IWebhook webhook, ulong webhookId, WebhookInfoAuditLogModel model) { - private WebhookCreateAuditLogData(IWebhook webhook, ulong webhookId, WebhookType type, string name, ulong channelId) - { - Webhook = webhook; - WebhookId = webhookId; - Name = name; - Type = type; - ChannelId = channelId; - } - - internal static WebhookCreateAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - var changes = entry.Changes; - - var channelIdModel = changes.FirstOrDefault(x => x.ChangedProperty == "channel_id"); - var typeModel = changes.FirstOrDefault(x => x.ChangedProperty == "type"); - var nameModel = changes.FirstOrDefault(x => x.ChangedProperty == "name"); - - var channelId = channelIdModel.NewValue.ToObject(discord.ApiClient.Serializer); - var type = typeModel.NewValue.ToObject(discord.ApiClient.Serializer); - var name = nameModel.NewValue.ToObject(discord.ApiClient.Serializer); - - var webhookInfo = log.Webhooks?.FirstOrDefault(x => x.Id == entry.TargetId); - var webhook = webhookInfo == null ? null : RestWebhook.Create(discord, (IGuild)null, webhookInfo); - - return new WebhookCreateAuditLogData(webhook, entry.TargetId.Value, type, name, channelId); - } - - // Doc Note: Corresponds to the *current* data - - /// - /// Gets the webhook that was created if it still exists. - /// - /// - /// A webhook object representing the webhook that was created if it still exists, otherwise returns null. - /// - public IWebhook Webhook { get; } - - // Doc Note: Corresponds to the *audit log* data - - /// - /// Gets the webhook id. - /// - /// - /// The webhook identifier. - /// - public ulong WebhookId { get; } - - /// - /// Gets the type of webhook that was created. - /// - /// - /// The type of webhook that was created. - /// - public WebhookType Type { get; } - - /// - /// Gets the name of the webhook. - /// - /// - /// A string containing the name of the webhook. - /// - public string Name { get; } - /// - /// Gets the ID of the channel that the webhook could send to. - /// - /// - /// A representing the snowflake identifier of the channel that the webhook could send - /// to. - /// - public ulong ChannelId { get; } + Webhook = webhook; + WebhookId = webhookId; + Name = model.Name; + Type = model.Type!.Value; + ChannelId = model.ChannelId!.Value; + Avatar = model.AvatarHash; } + + internal static WebhookCreateAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log) + { + var changes = entry.Changes; + + var (_, data) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + var webhookInfo = log.Webhooks?.FirstOrDefault(x => x.Id == entry.TargetId); + var webhook = webhookInfo == null ? null : RestWebhook.Create(discord, (IGuild)null, webhookInfo); + + return new WebhookCreateAuditLogData(webhook, entry.TargetId!.Value, data); + } + + // Doc Note: Corresponds to the *current* data + + /// + /// Gets the webhook that was created if it still exists. + /// + /// + /// A webhook object representing the webhook that was created if it still exists, otherwise returns null. + /// + public IWebhook Webhook { get; } + + // Doc Note: Corresponds to the *audit log* data + + /// + /// Gets the webhook id. + /// + /// + /// The webhook identifier. + /// + public ulong WebhookId { get; } + + /// + /// Gets the type of webhook that was created. + /// + /// + /// The type of webhook that was created. + /// + public WebhookType Type { get; } + + /// + /// Gets the name of the webhook. + /// + /// + /// A string containing the name of the webhook. + /// + public string Name { get; } + /// + /// Gets the ID of the channel that the webhook could send to. + /// + /// + /// A representing the snowflake identifier of the channel that the webhook could send + /// to. + /// + public ulong ChannelId { get; } + + /// + /// Gets the hash value of the webhook's avatar. + /// + /// + /// A string containing the hash of the webhook's avatar. + /// + public string Avatar { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/WebhookDeleteAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/WebhookDeleteAuditLogData.cs index 4ab5ac99..f4bb9360 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/WebhookDeleteAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/WebhookDeleteAuditLogData.cs @@ -1,75 +1,71 @@ -using System.Linq; +using Discord.API.AuditLogs; + using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to a webhook deletion. +/// +public class WebhookDeleteAuditLogData : IAuditLogData { - /// - /// Contains a piece of audit log data related to a webhook deletion. - /// - public class WebhookDeleteAuditLogData : IAuditLogData + private WebhookDeleteAuditLogData(ulong id, WebhookInfoAuditLogModel model) { - private WebhookDeleteAuditLogData(ulong id, ulong channel, WebhookType type, string name, string avatar) - { - WebhookId = id; - ChannelId = channel; - Name = name; - Type = type; - Avatar = avatar; - } - - internal static WebhookDeleteAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - var changes = entry.Changes; - - var channelIdModel = changes.FirstOrDefault(x => x.ChangedProperty == "channel_id"); - var typeModel = changes.FirstOrDefault(x => x.ChangedProperty == "type"); - var nameModel = changes.FirstOrDefault(x => x.ChangedProperty == "name"); - var avatarHashModel = changes.FirstOrDefault(x => x.ChangedProperty == "avatar_hash"); - - var channelId = channelIdModel.OldValue.ToObject(discord.ApiClient.Serializer); - var type = typeModel.OldValue.ToObject(discord.ApiClient.Serializer); - var name = nameModel.OldValue.ToObject(discord.ApiClient.Serializer); - var avatarHash = avatarHashModel?.OldValue?.ToObject(discord.ApiClient.Serializer); - - return new WebhookDeleteAuditLogData(entry.TargetId.Value, channelId, type, name, avatarHash); - } - - /// - /// Gets the ID of the webhook that was deleted. - /// - /// - /// A representing the snowflake identifier of the webhook that was deleted. - /// - public ulong WebhookId { get; } - /// - /// Gets the ID of the channel that the webhook could send to. - /// - /// - /// A representing the snowflake identifier of the channel that the webhook could send - /// to. - /// - public ulong ChannelId { get; } - /// - /// Gets the type of the webhook that was deleted. - /// - /// - /// The type of webhook that was deleted. - /// - public WebhookType Type { get; } - /// - /// Gets the name of the webhook that was deleted. - /// - /// - /// A string containing the name of the webhook that was deleted. - /// - public string Name { get; } - /// - /// Gets the hash value of the webhook's avatar. - /// - /// - /// A string containing the hash of the webhook's avatar. - /// - public string Avatar { get; } + WebhookId = id; + ChannelId = model.ChannelId!.Value; + Name = model.Name; + Type = model.Type!.Value; + Avatar = model.AvatarHash; } + + internal static WebhookDeleteAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log) + { + var changes = entry.Changes; + + var (data, _) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new WebhookDeleteAuditLogData(entry.TargetId!.Value, data); + } + + /// + /// Gets the ID of the webhook that was deleted. + /// + /// + /// A representing the snowflake identifier of the webhook that was deleted. + /// + public ulong WebhookId { get; } + + /// + /// Gets the ID of the channel that the webhook could send to. + /// + /// + /// A representing the snowflake identifier of the channel that the webhook could send + /// to. + /// + public ulong ChannelId { get; } + + /// + /// Gets the type of the webhook that was deleted. + /// + /// + /// The type of webhook that was deleted. + /// + public WebhookType Type { get; } + + /// + /// Gets the name of the webhook that was deleted. + /// + /// + /// A string containing the name of the webhook that was deleted. + /// + public string Name { get; } + + /// + /// Gets the hash value of the webhook's avatar. + /// + /// + /// A string containing the hash of the webhook's avatar. + /// + public string Avatar { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/WebhookInfo.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/WebhookInfo.cs index e60157b1..93ed9fae 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/WebhookInfo.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/WebhookInfo.cs @@ -1,38 +1,41 @@ -namespace Discord.Rest -{ - /// - /// Represents information for a webhook. - /// - public struct WebhookInfo - { - internal WebhookInfo(string name, ulong? channelId, string avatar) - { - Name = name; - ChannelId = channelId; - Avatar = avatar; - } +using Model = Discord.API.AuditLogs.WebhookInfoAuditLogModel; - /// - /// Gets the name of this webhook. - /// - /// - /// A string containing the name of this webhook. - /// - public string Name { get; } - /// - /// Gets the ID of the channel that this webhook sends to. - /// - /// - /// A representing the snowflake identifier of the channel that this webhook can send - /// to. - /// - public ulong? ChannelId { get; } - /// - /// Gets the hash value of this webhook's avatar. - /// - /// - /// A string containing the hash of this webhook's avatar. - /// - public string Avatar { get; } +namespace Discord.Rest; + +/// +/// Represents information for a webhook. +/// +public struct WebhookInfo +{ + internal WebhookInfo(Model model) + { + Name = model.Name; + ChannelId = model.ChannelId; + Avatar = model.AvatarHash; } + + /// + /// Gets the name of this webhook. + /// + /// + /// A string containing the name of this webhook. + /// + public string Name { get; } + + /// + /// Gets the ID of the channel that this webhook sends to. + /// + /// + /// A representing the snowflake identifier of the channel that this webhook can send + /// to. + /// + public ulong? ChannelId { get; } + + /// + /// Gets the hash value of this webhook's avatar. + /// + /// + /// A string containing the hash of this webhook's avatar. + /// + public string Avatar { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/WebhookUpdateAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/WebhookUpdateAuditLogData.cs index c1540b0d..f54b78c1 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/WebhookUpdateAuditLogData.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/WebhookUpdateAuditLogData.cs @@ -1,67 +1,55 @@ +using Discord.API.AuditLogs; using System.Linq; using EntryModel = Discord.API.AuditLogEntry; using Model = Discord.API.AuditLog; -namespace Discord.Rest +namespace Discord.Rest; + +/// +/// Contains a piece of audit log data related to a webhook update. +/// +public class WebhookUpdateAuditLogData : IAuditLogData { - /// - /// Contains a piece of audit log data related to a webhook update. - /// - public class WebhookUpdateAuditLogData : IAuditLogData + private WebhookUpdateAuditLogData(IWebhook webhook, WebhookInfo before, WebhookInfo after) { - private WebhookUpdateAuditLogData(IWebhook webhook, WebhookInfo before, WebhookInfo after) - { - Webhook = webhook; - Before = before; - After = after; - } - - internal static WebhookUpdateAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry) - { - var changes = entry.Changes; - - var nameModel = changes.FirstOrDefault(x => x.ChangedProperty == "name"); - var channelIdModel = changes.FirstOrDefault(x => x.ChangedProperty == "channel_id"); - var avatarHashModel = changes.FirstOrDefault(x => x.ChangedProperty == "avatar_hash"); - - var oldName = nameModel?.OldValue?.ToObject(discord.ApiClient.Serializer); - var oldChannelId = channelIdModel?.OldValue?.ToObject(discord.ApiClient.Serializer); - var oldAvatar = avatarHashModel?.OldValue?.ToObject(discord.ApiClient.Serializer); - var before = new WebhookInfo(oldName, oldChannelId, oldAvatar); - - var newName = nameModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - var newChannelId = channelIdModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - var newAvatar = avatarHashModel?.NewValue?.ToObject(discord.ApiClient.Serializer); - var after = new WebhookInfo(newName, newChannelId, newAvatar); - - var webhookInfo = log.Webhooks?.FirstOrDefault(x => x.Id == entry.TargetId); - var webhook = webhookInfo != null ? RestWebhook.Create(discord, (IGuild)null, webhookInfo) : null; - - return new WebhookUpdateAuditLogData(webhook, before, after); - } - - /// - /// Gets the webhook that was updated. - /// - /// - /// A webhook object representing the webhook that was updated. - /// - public IWebhook Webhook { get; } - - /// - /// Gets the webhook information before the changes. - /// - /// - /// A webhook information object representing the webhook before the changes were made. - /// - public WebhookInfo Before { get; } - - /// - /// Gets the webhook information after the changes. - /// - /// - /// A webhook information object representing the webhook after the changes were made. - /// - public WebhookInfo After { get; } + Webhook = webhook; + Before = before; + After = after; } + + internal static WebhookUpdateAuditLogData Create(BaseDiscordClient discord, EntryModel entry, Model log) + { + var changes = entry.Changes; + + var (before, after) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + var webhookInfo = log.Webhooks?.FirstOrDefault(x => x.Id == entry.TargetId); + var webhook = webhookInfo != null ? RestWebhook.Create(discord, (IGuild)null, webhookInfo) : null; + + return new WebhookUpdateAuditLogData(webhook, new(before), new(after)); + } + + /// + /// Gets the webhook that was updated. + /// + /// + /// A webhook object representing the webhook that was updated. + /// + public IWebhook Webhook { get; } + + /// + /// Gets the webhook information before the changes. + /// + /// + /// A webhook information object representing the webhook before the changes were made. + /// + public WebhookInfo Before { get; } + + /// + /// Gets the webhook information after the changes. + /// + /// + /// A webhook information object representing the webhook after the changes were made. + /// + public WebhookInfo After { get; } } diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/JsonFieldAttribute.cs b/src/Discord.Net.Rest/Entities/AuditLogs/JsonFieldAttribute.cs new file mode 100644 index 00000000..0f838141 --- /dev/null +++ b/src/Discord.Net.Rest/Entities/AuditLogs/JsonFieldAttribute.cs @@ -0,0 +1,14 @@ +using System; + +namespace Discord.Rest; + +[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] +internal class JsonFieldAttribute : Attribute +{ + public string FieldName { get; } + + public JsonFieldAttribute(string fieldName) + { + FieldName = fieldName; + } +} diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/RestAuditLogEntry.cs b/src/Discord.Net.Rest/Entities/AuditLogs/RestAuditLogEntry.cs index 26b1cfe0..88ab517e 100644 --- a/src/Discord.Net.Rest/Entities/AuditLogs/RestAuditLogEntry.cs +++ b/src/Discord.Net.Rest/Entities/AuditLogs/RestAuditLogEntry.cs @@ -14,7 +14,7 @@ namespace Discord.Rest : base(discord, model.Id) { Action = model.Action; - Data = AuditLogHelper.CreateData(discord, fullLog, model); + Data = AuditLogHelper.CreateData(discord, model, fullLog); User = user; Reason = model.Reason; } diff --git a/src/Discord.Net.Rest/Entities/Channels/RestForumChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestForumChannel.cs index 59d6741d..0b2c2562 100644 --- a/src/Discord.Net.Rest/Entities/Channels/RestForumChannel.cs +++ b/src/Discord.Net.Rest/Entities/Channels/RestForumChannel.cs @@ -75,7 +75,7 @@ namespace Discord.Rest DefaultSortOrder = model.DefaultSortOrder.GetValueOrDefault(); - Tags = model.ForumTags.GetValueOrDefault(Array.Empty()).Select( + Tags = model.ForumTags.GetValueOrDefault(Array.Empty()).Select( x => new ForumTag(x.Id, x.Name, x.EmojiId.GetValueOrDefault(null), x.EmojiName.GetValueOrDefault(), x.Moderated) ).ToImmutableArray(); diff --git a/src/Discord.Net.Rest/Net/Converters/DiscordContractResolver.cs b/src/Discord.Net.Rest/Net/Converters/DiscordContractResolver.cs index 91ba2246..ae16f19c 100644 --- a/src/Discord.Net.Rest/Net/Converters/DiscordContractResolver.cs +++ b/src/Discord.Net.Rest/Net/Converters/DiscordContractResolver.cs @@ -37,7 +37,7 @@ namespace Discord.Net.Converters { if (type.IsArray) return MakeGenericConverter(property, propInfo, typeof(ArrayConverter<>), type.GetElementType(), depth); - if (type.IsConstructedGenericType) + if (type.IsConstructedGenericType) { Type genericType = type.GetGenericTypeDefinition(); if (depth == 0 && genericType == typeof(Optional<>)) diff --git a/src/Discord.Net.WebSocket/API/Gateway/ApplicationCommandCreatedUpdatedEvent.cs b/src/Discord.Net.WebSocket/API/Gateway/ApplicationCommandCreatedUpdatedEvent.cs index 91dcbde1..96bdc9c1 100644 --- a/src/Discord.Net.WebSocket/API/Gateway/ApplicationCommandCreatedUpdatedEvent.cs +++ b/src/Discord.Net.WebSocket/API/Gateway/ApplicationCommandCreatedUpdatedEvent.cs @@ -4,7 +4,5 @@ namespace Discord.API.Gateway { internal class ApplicationCommandCreatedUpdatedEvent : ApplicationCommand { - [JsonProperty("guild_id")] - public Optional GuildId { get; set; } } } diff --git a/src/Discord.Net.WebSocket/API/Gateway/AuditLogCreatedEvent.cs b/src/Discord.Net.WebSocket/API/Gateway/AuditLogCreatedEvent.cs new file mode 100644 index 00000000..4c208c7a --- /dev/null +++ b/src/Discord.Net.WebSocket/API/Gateway/AuditLogCreatedEvent.cs @@ -0,0 +1,9 @@ +using Newtonsoft.Json; + +namespace Discord.API.Gateway; + +internal class AuditLogCreatedEvent : AuditLogEntry +{ + [JsonProperty("guild_id")] + public ulong GuildId { get; set; } +} diff --git a/src/Discord.Net.WebSocket/BaseSocketClient.Events.cs b/src/Discord.Net.WebSocket/BaseSocketClient.Events.cs index bc97139e..7ae8d6af 100644 --- a/src/Discord.Net.WebSocket/BaseSocketClient.Events.cs +++ b/src/Discord.Net.WebSocket/BaseSocketClient.Events.cs @@ -893,6 +893,21 @@ namespace Discord.WebSocket #endregion + #region Audit Logs + + /// + /// Fired when a guild audit log entry is created. + /// + public event Func AuditLogCreated + { + add { _auditLogCreated.Add(value); } + remove { _auditLogCreated.Remove(value); } + } + + internal readonly AsyncEvent> _auditLogCreated = new(); + + #endregion + #region AutoModeration /// diff --git a/src/Discord.Net.WebSocket/DiscordShardedClient.cs b/src/Discord.Net.WebSocket/DiscordShardedClient.cs index 45958c0a..c3809ba6 100644 --- a/src/Discord.Net.WebSocket/DiscordShardedClient.cs +++ b/src/Discord.Net.WebSocket/DiscordShardedClient.cs @@ -509,6 +509,7 @@ namespace Discord.WebSocket client.GuildScheduledEventUserRemove += (arg1, arg2) => _guildScheduledEventUserRemove.InvokeAsync(arg1, arg2); client.WebhooksUpdated += (arg1, arg2) => _webhooksUpdated.InvokeAsync(arg1, arg2); + client.AuditLogCreated += (arg1, arg2) => _auditLogCreated.InvokeAsync(arg1, arg2); } #endregion diff --git a/src/Discord.Net.WebSocket/DiscordSocketClient.cs b/src/Discord.Net.WebSocket/DiscordSocketClient.cs index 219e4548..924f5f64 100644 --- a/src/Discord.Net.WebSocket/DiscordSocketClient.cs +++ b/src/Discord.Net.WebSocket/DiscordSocketClient.cs @@ -83,6 +83,8 @@ namespace Discord.WebSocket internal bool AlwaysResolveStickers { get; private set; } internal bool LogGatewayIntentWarnings { get; private set; } internal bool SuppressUnknownDispatchWarnings { get; private set; } + internal int AuditLogCacheSize { get; private set; } + internal new DiscordSocketApiClient ApiClient => base.ApiClient; /// public override IReadOnlyCollection Guilds => State.Guilds; @@ -200,6 +202,7 @@ namespace Discord.WebSocket }; _largeGuilds = new ConcurrentQueue(); + AuditLogCacheSize = config.AuditLogCacheSize; } private static API.DiscordSocketApiClient CreateApiClient(DiscordSocketConfig config) => new DiscordSocketApiClient(config.RestClientProvider, config.WebSocketProvider, DiscordRestConfig.UserAgent, config.GatewayHost, @@ -2885,6 +2888,23 @@ namespace Discord.WebSocket #endregion + #region Audit Logs + + case "GUILD_AUDIT_LOG_ENTRY_CREATE": + { + var data = (payload as JToken).ToObject(_serializer); + type = "GUILD_AUDIT_LOG_ENTRY_CREATE"; + await _gatewayLogger.DebugAsync("Received Dispatch (GUILD_AUDIT_LOG_ENTRY_CREATE)").ConfigureAwait(false); + + var guild = State.GetGuild(data.GuildId); + var auditLog = SocketAuditLogEntry.Create(this, data); + guild.AddAuditLog(auditLog); + + await TimedInvokeAsync(_auditLogCreated, nameof(AuditLogCreated), auditLog, guild); + } + break; + #endregion + #region Auto Moderation case "AUTO_MODERATION_RULE_CREATE": diff --git a/src/Discord.Net.WebSocket/DiscordSocketConfig.cs b/src/Discord.Net.WebSocket/DiscordSocketConfig.cs index 4a0d809a..5917fc97 100644 --- a/src/Discord.Net.WebSocket/DiscordSocketConfig.cs +++ b/src/Discord.Net.WebSocket/DiscordSocketConfig.cs @@ -80,6 +80,12 @@ namespace Discord.WebSocket /// public int MessageCacheSize { get; set; } = 0; + /// + /// Gets or sets the number of audit logs per guild that should be kept in cache. Setting this to zero + /// disables the audit log cache entirely. + /// + public int AuditLogCacheSize { get; set; } = 0; + /// /// Gets or sets the max number of users a guild may have for offline users to be included in the READY /// packet. The maximum value allowed is 250. diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/AuditLogCache.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/AuditLogCache.cs new file mode 100644 index 00000000..3fd6eee9 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/AuditLogCache.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; + +namespace Discord.WebSocket; + +internal class AuditLogCache +{ + private readonly ConcurrentDictionary _entries; + private readonly ConcurrentQueue _orderedEntries; + + private readonly int _size; + + public IReadOnlyCollection AuditLogs => _entries.ToReadOnlyCollection(); + + public AuditLogCache(DiscordSocketClient client) + { + _size = client.AuditLogCacheSize; + + _entries = new ConcurrentDictionary(ConcurrentHashSet.DefaultConcurrencyLevel, (int)(_size * 1.05)); + _orderedEntries = new ConcurrentQueue(); + } + + public void Add(SocketAuditLogEntry entry) + { + if (_entries.TryAdd(entry.Id, entry)) + { + _orderedEntries.Enqueue(entry.Id); + + while (_orderedEntries.Count > _size && _orderedEntries.TryDequeue(out var entryId)) + _entries.TryRemove(entryId, out _); + } + } + + public SocketAuditLogEntry Remove(ulong id) + { + _entries.TryRemove(id, out var entry); + return entry; + } + + public SocketAuditLogEntry Get(ulong id) + => _entries.TryGetValue(id, out var result) ? result : null; + + /// is less than 0. + public IReadOnlyCollection GetMany(ulong? fromEntryId, Direction dir, int limit = DiscordConfig.MaxAuditLogEntriesPerBatch, ActionType ? action = null) + { + if (limit < 0) + throw new ArgumentOutOfRangeException(nameof(limit)); + if (limit == 0) + return ImmutableArray.Empty; + + IEnumerable cachedEntriesIds; + if (fromEntryId == null) + cachedEntriesIds = _orderedEntries; + else if (dir == Direction.Before) + cachedEntriesIds = _orderedEntries.Where(x => x < fromEntryId.Value); + else if (dir == Direction.After) + cachedEntriesIds = _orderedEntries.Where(x => x > fromEntryId.Value); + else //Direction.Around + { + if (!_entries.TryGetValue(fromEntryId.Value, out var entry)) + return ImmutableArray.Empty; + var around = limit / 2; + var before = GetMany(fromEntryId, Direction.Before, around, action); + var after = GetMany(fromEntryId, Direction.After, around, action).Reverse(); + + return after.Concat(new [] { entry }).Concat(before).ToImmutableArray(); + } + + if (dir == Direction.Before) + cachedEntriesIds = cachedEntriesIds.Reverse(); + if (dir == Direction.Around) + limit = limit / 2 + 1; + + return cachedEntriesIds + .Select(x => _entries.TryGetValue(x, out var entry) ? entry : null) + .Where(x => x != null && (action is null || x.Action == action)) + .Take(limit) + .ToImmutableArray(); + } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketAutoModBlockedMessageAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketAutoModBlockedMessageAuditLogData.cs new file mode 100644 index 00000000..35b7a82a --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketAutoModBlockedMessageAuditLogData.cs @@ -0,0 +1,37 @@ +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to message getting blocked by automod. +/// +public class SocketAutoModBlockedMessageAuditLogData : ISocketAuditLogData +{ + internal SocketAutoModBlockedMessageAuditLogData(ulong channelId, string autoModRuleName, AutoModTriggerType autoModRuleTriggerType) + { + ChannelId = channelId; + AutoModRuleName = autoModRuleName; + AutoModRuleTriggerType = autoModRuleTriggerType; + } + + internal static SocketAutoModBlockedMessageAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + return new(entry.Options.ChannelId!.Value, entry.Options.AutoModRuleName, + entry.Options.AutoModRuleTriggerType!.Value); + } + + /// + /// Gets the channel the message was sent in. + /// + public ulong ChannelId { get; set; } + + /// + /// Gets the name of the auto moderation rule that got triggered. + /// + public string AutoModRuleName { get; set; } + + /// + /// Gets the trigger type of the auto moderation rule that got triggered. + /// + public AutoModTriggerType AutoModRuleTriggerType { get; set; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketAutoModFlaggedMessageAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketAutoModFlaggedMessageAuditLogData.cs new file mode 100644 index 00000000..e53f20d1 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketAutoModFlaggedMessageAuditLogData.cs @@ -0,0 +1,37 @@ +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to message getting flagged by automod. +/// +public class SocketAutoModFlaggedMessageAuditLogData : ISocketAuditLogData +{ + internal SocketAutoModFlaggedMessageAuditLogData(ulong channelId, string autoModRuleName, AutoModTriggerType autoModRuleTriggerType) + { + ChannelId = channelId; + AutoModRuleName = autoModRuleName; + AutoModRuleTriggerType = autoModRuleTriggerType; + } + + internal static SocketAutoModFlaggedMessageAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + return new(entry.Options.ChannelId!.Value, entry.Options.AutoModRuleName, + entry.Options.AutoModRuleTriggerType!.Value); + } + + /// + /// Gets the channel the message was sent in. + /// + public ulong ChannelId { get; set; } + + /// + /// Gets the name of the auto moderation rule that got triggered. + /// + public string AutoModRuleName { get; set; } + + /// + /// Gets the trigger type of the auto moderation rule that got triggered. + /// + public AutoModTriggerType AutoModRuleTriggerType { get; set; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketAutoModRuleCreatedAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketAutoModRuleCreatedAuditLogData.cs new file mode 100644 index 00000000..df556f49 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketAutoModRuleCreatedAuditLogData.cs @@ -0,0 +1,30 @@ +using Discord.API.AuditLogs; +using Discord.Rest; +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to an auto moderation rule creation. +/// +public class SocketAutoModRuleCreatedAuditLogData : ISocketAuditLogData +{ + private SocketAutoModRuleCreatedAuditLogData(SocketAutoModRuleInfo data) + { + Data = data; + } + + internal static SocketAutoModRuleCreatedAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var changes = entry.Changes; + + var (_, data) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new SocketAutoModRuleCreatedAuditLogData(new (data)); + } + + /// + /// Gets the auto moderation rule information after the changes. + /// + public SocketAutoModRuleInfo Data { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketAutoModRuleDeletedAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketAutoModRuleDeletedAuditLogData.cs new file mode 100644 index 00000000..40b6b7ac --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketAutoModRuleDeletedAuditLogData.cs @@ -0,0 +1,30 @@ +using Discord.API.AuditLogs; +using Discord.Rest; +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to an auto moderation rule removal. +/// +public class SocketAutoModRuleDeletedAuditLogData : ISocketAuditLogData +{ + private SocketAutoModRuleDeletedAuditLogData(SocketAutoModRuleInfo data) + { + Data = data; + } + + internal static SocketAutoModRuleDeletedAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var changes = entry.Changes; + + var (data, _) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new SocketAutoModRuleDeletedAuditLogData(new (data)); + } + + /// + /// Gets the auto moderation rule information before the changes. + /// + public SocketAutoModRuleInfo Data { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketAutoModRuleInfo.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketAutoModRuleInfo.cs new file mode 100644 index 00000000..6f7b7c8d --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketAutoModRuleInfo.cs @@ -0,0 +1,113 @@ +using Discord.API.AuditLogs; + +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; + +namespace Discord.WebSocket; + +/// +/// Represents information for an auto moderation rule. +/// +public class SocketAutoModRuleInfo +{ + internal SocketAutoModRuleInfo(AutoModRuleInfoAuditLogModel model) + { + Actions = model.Actions?.Select(x => new AutoModRuleAction( + x.Type, + x.Metadata.GetValueOrDefault()?.ChannelId.ToNullable(), + x.Metadata.GetValueOrDefault()?.DurationSeconds.ToNullable(), + x.Metadata.IsSpecified + ? x.Metadata.Value.CustomMessage.IsSpecified + ? x.Metadata.Value.CustomMessage.Value + : null + : null + )).ToImmutableArray(); + KeywordFilter = model.TriggerMetadata?.KeywordFilter.GetValueOrDefault(Array.Empty())?.ToImmutableArray(); + Presets = model.TriggerMetadata?.Presets.GetValueOrDefault(Array.Empty())?.ToImmutableArray(); + RegexPatterns = model.TriggerMetadata?.RegexPatterns.GetValueOrDefault(Array.Empty())?.ToImmutableArray(); + AllowList = model.TriggerMetadata?.AllowList.GetValueOrDefault(Array.Empty())?.ToImmutableArray(); + MentionTotalLimit = model.TriggerMetadata?.MentionLimit.IsSpecified ?? false + ? model.TriggerMetadata?.MentionLimit.Value + : null; + Name = model.Name; + Enabled = model.Enabled; + ExemptRoles = model.ExemptRoles?.ToImmutableArray(); + ExemptChannels = model.ExemptChannels?.ToImmutableArray(); + TriggerType = model.TriggerType; + EventType = model.EventType; + } + + /// + /// + /// if this property is not mentioned in this entry. + /// + public string Name { get; set; } + + /// + /// + /// if this property is not mentioned in this entry. + /// + public AutoModEventType? EventType { get; set; } + + /// + /// + /// if this property is not mentioned in this entry. + /// + public AutoModTriggerType? TriggerType { get; set; } + + /// + /// + /// if this property is not mentioned in this entry. + /// + public bool? Enabled { get; set; } + + /// + /// + /// if this property is not mentioned in this entry. + /// + public IReadOnlyCollection ExemptRoles { get; set; } + + /// + /// + /// if this property is not mentioned in this entry. + /// + public IReadOnlyCollection ExemptChannels { get; set; } + + /// + /// + /// if this property is not mentioned in this entry. + /// + public IReadOnlyCollection KeywordFilter { get; } + + /// + /// + /// if this property is not mentioned in this entry. + /// + public IReadOnlyCollection RegexPatterns { get; } + + /// + /// + /// if this property is not mentioned in this entry. + /// + public IReadOnlyCollection AllowList { get; } + + /// + /// + /// if this property is not mentioned in this entry. + /// + public IReadOnlyCollection Presets { get; } + + /// + /// + /// if this property is not mentioned in this entry. + /// + public int? MentionTotalLimit { get; } + + /// + /// + /// if this property is not mentioned in this entry. + /// + public IReadOnlyCollection Actions { get; private set; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketAutoModRuleUpdatedAuditLogData .cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketAutoModRuleUpdatedAuditLogData .cs new file mode 100644 index 00000000..ca724d7d --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketAutoModRuleUpdatedAuditLogData .cs @@ -0,0 +1,36 @@ +using Discord.API.AuditLogs; +using Discord.Rest; +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to an auto moderation rule update. +/// +public class AutoModRuleUpdatedAuditLogData : ISocketAuditLogData +{ + private AutoModRuleUpdatedAuditLogData(SocketAutoModRuleInfo before, SocketAutoModRuleInfo after) + { + Before = before; + After = after; + } + + internal static AutoModRuleUpdatedAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var changes = entry.Changes; + + var (before, after) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new AutoModRuleUpdatedAuditLogData(new(before), new(after)); + } + + /// + /// Gets the auto moderation rule information before the changes. + /// + public SocketAutoModRuleInfo Before { get; } + + /// + /// Gets the auto moderation rule information after the changes. + /// + public SocketAutoModRuleInfo After { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketAutoModTimeoutUserAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketAutoModTimeoutUserAuditLogData.cs new file mode 100644 index 00000000..22050002 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketAutoModTimeoutUserAuditLogData.cs @@ -0,0 +1,37 @@ +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to user getting in timeout by automod. +/// +public class SocketAutoModTimeoutUserAuditLogData : ISocketAuditLogData +{ + internal SocketAutoModTimeoutUserAuditLogData(ulong channelId, string autoModRuleName, AutoModTriggerType autoModRuleTriggerType) + { + ChannelId = channelId; + AutoModRuleName = autoModRuleName; + AutoModRuleTriggerType = autoModRuleTriggerType; + } + + internal static SocketAutoModTimeoutUserAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + return new(entry.Options.ChannelId!.Value, entry.Options.AutoModRuleName, + entry.Options.AutoModRuleTriggerType!.Value); + } + + /// + /// Gets the channel the message was sent in. + /// + public ulong ChannelId { get; set; } + + /// + /// Gets the name of the auto moderation rule that got triggered. + /// + public string AutoModRuleName { get; set; } + + /// + /// Gets the trigger type of the auto moderation rule that got triggered. + /// + public AutoModTriggerType AutoModRuleTriggerType { get; set; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketBanAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketBanAuditLogData.cs new file mode 100644 index 00000000..699cca58 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketBanAuditLogData.cs @@ -0,0 +1,43 @@ +using Discord.Rest; +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to a ban. +/// +public class SocketBanAuditLogData : ISocketAuditLogData +{ + private SocketBanAuditLogData(Cacheable user) + { + Target = user; + } + + internal static SocketBanAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var cachedUser = discord.GetUser(entry.TargetId!.Value); + var cacheableUser = new Cacheable( + cachedUser, + entry.TargetId.Value, + cachedUser is not null, + async () => + { + var user = await discord.ApiClient.GetUserAsync(entry.TargetId.Value); + return user is not null ? RestUser.Create(discord, user) : null; + }); + + return new SocketBanAuditLogData(cacheableUser); + } + + /// + /// Gets the user that was banned. + /// + /// + /// Download method may return if the user is a 'Deleted User#....' + /// because Discord does send user data for deleted users. + /// + /// + /// A cacheable user object representing the banned user. + /// + public Cacheable Target { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketBotAddAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketBotAddAuditLogData.cs new file mode 100644 index 00000000..35f14f0a --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketBotAddAuditLogData.cs @@ -0,0 +1,42 @@ +using Discord.Rest; +using System.Linq; +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to a adding a bot to a guild. +/// +public class SocketBotAddAuditLogData : ISocketAuditLogData +{ + private SocketBotAddAuditLogData(Cacheable bot) + { + Target = bot; + } + + internal static SocketBotAddAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var cachedUser = discord.GetUser(entry.TargetId!.Value); + var cacheableUser = new Cacheable( + cachedUser, + entry.TargetId.Value, + cachedUser is not null, + async () => + { + var user = await discord.ApiClient.GetUserAsync(entry.TargetId.Value); + return user is not null ? RestUser.Create(discord, user) : null; + }); + return new SocketBotAddAuditLogData(cacheableUser); + } + + /// + /// Gets the bot that was added. + /// + /// + /// Will be if the bot is a 'Deleted User#....' because Discord does send user data for deleted users. + /// + /// + /// A cacheable user object representing the bot. + /// + public Cacheable Target { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketChannelCreateAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketChannelCreateAuditLogData.cs new file mode 100644 index 00000000..801ce617 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketChannelCreateAuditLogData.cs @@ -0,0 +1,165 @@ +using Discord.Rest; +using Discord.API.AuditLogs; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; + +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to a channel creation. +/// +public class SocketChannelCreateAuditLogData : ISocketAuditLogData +{ + private SocketChannelCreateAuditLogData(ChannelInfoAuditLogModel model, EntryModel entry) + { + ChannelId = entry.TargetId!.Value; + ChannelName = model.Name; + ChannelType = model.Type!.Value; + SlowModeInterval = model.RateLimitPerUser; + IsNsfw = model.IsNsfw; + Bitrate = model.Bitrate; + Topic = model.Topic; + AutoArchiveDuration = model.AutoArchiveDuration; + DefaultSlowModeInterval = model.DefaultThreadRateLimitPerUser; + DefaultAutoArchiveDuration = model.DefaultArchiveDuration; + + AvailableTags = model.AvailableTags?.Select(x => new ForumTag(x.Id, + x.Name, + x.EmojiId.GetValueOrDefault(null), + x.EmojiName.GetValueOrDefault(null), + x.Moderated)).ToImmutableArray(); + + + if (model.DefaultEmoji is not null) + { + if (model.DefaultEmoji.EmojiId.HasValue && model.DefaultEmoji.EmojiId.Value != 0) + DefaultReactionEmoji = new Emote(model.DefaultEmoji.EmojiId.GetValueOrDefault(), null, false); + else if (model.DefaultEmoji.EmojiName.IsSpecified) + DefaultReactionEmoji = new Emoji(model.DefaultEmoji.EmojiName.Value); + else + DefaultReactionEmoji = null; + } + else + DefaultReactionEmoji = null; + + VideoQualityMode = model.VideoQualityMode; + RtcRegion = model.Region; + Flags = model.Flags; + UserLimit = model.UserLimit; + } + + internal static SocketChannelCreateAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var changes = entry.Changes; + + var (_, data) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new SocketChannelCreateAuditLogData(data, entry); + } + + /// + /// Gets the snowflake ID of the created channel. + /// + /// + /// A representing the snowflake identifier for the created channel. + /// + public ulong ChannelId { get; } + + /// + /// Gets the name of the created channel. + /// + /// + /// A string containing the name of the created channel. + /// + public string ChannelName { get; } + + /// + /// Gets the type of the created channel. + /// + /// + /// The type of channel that was created. + /// + public ChannelType ChannelType { get; } + + /// + /// Gets the current slow-mode delay of the created channel. + /// + /// + /// An representing the time in seconds required before the user can send another + /// message; 0 if disabled. + /// null if this is not mentioned in this entry. + /// + public int? SlowModeInterval { get; } + + /// + /// Gets the value that indicates whether the created channel is NSFW. + /// + /// + /// true if the created channel has the NSFW flag enabled; otherwise false. + /// null if this is not mentioned in this entry. + /// + public bool? IsNsfw { get; } + + /// + /// Gets the bit-rate that the clients in the created voice channel are requested to use. + /// + /// + /// An representing the bit-rate (bps) that the created voice channel defines and requests the + /// client(s) to use. + /// null if this is not mentioned in this entry. + /// + public int? Bitrate { get; } + + /// + /// Gets the thread archive duration that was set in the created channel. + /// + public ThreadArchiveDuration? AutoArchiveDuration { get; } + + /// + /// Gets the default thread archive duration that was set in the created channel. + /// + public ThreadArchiveDuration? DefaultAutoArchiveDuration { get; } + + /// + /// Gets the default slow mode interval that will be set in child threads in the channel. + /// + public int? DefaultSlowModeInterval { get; } + + /// + /// Gets the topic that was set in the created channel. + /// + public string Topic { get; } + + /// + /// Gets tags available in the created forum channel. + /// + public IReadOnlyCollection AvailableTags { get; } + + /// + /// Gets the default reaction added to posts in the created forum channel. + /// + public IEmote DefaultReactionEmoji { get; } + + /// + /// Gets the user limit configured in the created voice channel. + /// + public int? UserLimit { get; } + + /// + /// Gets the video quality mode configured in the created voice channel. + /// + public VideoQualityMode? VideoQualityMode { get; } + + /// + /// Gets the region configured in the created voice channel. + /// + public string RtcRegion { get; } + + /// + /// Gets channel flags configured for the created channel. + /// + public ChannelFlags? Flags { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketChannelDeleteAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketChannelDeleteAuditLogData.cs new file mode 100644 index 00000000..8f9fb80a --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketChannelDeleteAuditLogData.cs @@ -0,0 +1,182 @@ +using Discord.Rest; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; + +using Model = Discord.API.AuditLogs.ChannelInfoAuditLogModel; +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to a channel deletion. +/// +public class SocketChannelDeleteAuditLogData : ISocketAuditLogData +{ + private SocketChannelDeleteAuditLogData(Model model, EntryModel entry) + { + ChannelId = entry.TargetId!.Value; + ChannelType = model.Type; + ChannelName = model.Name; + + Topic = model.Topic; + IsNsfw = model.IsNsfw; + Bitrate = model.Bitrate; + DefaultArchiveDuration = model.DefaultArchiveDuration; + SlowModeInterval = model.RateLimitPerUser; + + ForumTags = model.AvailableTags?.Select( + x => new ForumTag(x.Id, + x.Name, + x.EmojiId.GetValueOrDefault(null), + x.EmojiName.GetValueOrDefault(null), + x.Moderated)).ToImmutableArray(); + + if (model.DefaultEmoji is not null) + { + if (model.DefaultEmoji.EmojiId.HasValue && model.DefaultEmoji.EmojiId.Value != 0) + DefaultReactionEmoji = new Emote(model.DefaultEmoji.EmojiId.GetValueOrDefault(), null, false); + else if (model.DefaultEmoji.EmojiName.IsSpecified) + DefaultReactionEmoji = new Emoji(model.DefaultEmoji.EmojiName.Value); + else + DefaultReactionEmoji = null; + } + else + DefaultReactionEmoji = null; + AutoArchiveDuration = model.AutoArchiveDuration; + DefaultSlowModeInterval = model.DefaultThreadRateLimitPerUser; + + VideoQualityMode = model.VideoQualityMode; + RtcRegion = model.Region; + Flags = model.Flags; + UserLimit = model.UserLimit; + + Overwrites = model.Overwrites?.Select(x + => new Overwrite(x.TargetId, + x.TargetType, + new OverwritePermissions(x.Allow, x.Deny))).ToImmutableArray(); + } + + internal static SocketChannelDeleteAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var changes = entry.Changes; + + var (data, _) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new SocketChannelDeleteAuditLogData(data, entry); + } + + /// + /// Gets the snowflake ID of the deleted channel. + /// + /// + /// A representing the snowflake identifier for the deleted channel. + /// + public ulong ChannelId { get; } + + /// + /// Gets the name of the deleted channel. + /// + /// + /// A string containing the name of the deleted channel. + /// + public string ChannelName { get; } + + /// + /// Gets the type of the deleted channel. + /// + /// + /// The type of channel that was deleted. + /// + public ChannelType? ChannelType { get; } + + /// + /// Gets the slow-mode delay of the deleted channel. + /// + /// + /// An representing the time in seconds required before the user can send another + /// message; 0 if disabled. + /// null if this is not mentioned in this entry. + /// + public int? SlowModeInterval { get; } + + /// + /// Gets the value that indicates whether the deleted channel was NSFW. + /// + /// + /// true if this channel had the NSFW flag enabled; otherwise false. + /// null if this is not mentioned in this entry. + /// + public bool? IsNsfw { get; } + + /// + /// Gets the bit-rate of this channel if applicable. + /// + /// + /// An representing the bit-rate set of the voice channel. + /// null if this is not mentioned in this entry. + /// + public int? Bitrate { get; } + + /// + /// Gets a collection of permission overwrites that was assigned to the deleted channel. + /// + /// + /// A collection of permission . + /// + public IReadOnlyCollection Overwrites { get; } + + /// + /// Gets the user limit configured in the created voice channel. + /// + public int? UserLimit { get; } + + /// + /// Gets the video quality mode configured in the created voice channel. + /// + public VideoQualityMode? VideoQualityMode { get; } + + /// + /// Gets the region configured in the created voice channel. + /// + public string RtcRegion { get; } + + /// + /// Gets channel flags configured for the created channel. + /// + public ChannelFlags? Flags { get; } + + /// + /// Gets the thread archive duration that was configured for the created channel. + /// + public ThreadArchiveDuration? AutoArchiveDuration { get; } + + /// + /// Gets the default slow mode interval that was configured for the channel. + /// + public int? DefaultSlowModeInterval { get; } + + /// + /// + /// if the value was not specified in this entry.. + /// + public ThreadArchiveDuration? DefaultArchiveDuration { get; } + + /// + /// + /// if the value was not specified in this entry.. + /// + public IReadOnlyCollection ForumTags { get; } + + /// + /// + /// if the value was not specified in this entry.. + /// + public string Topic { get; } + + /// + /// + /// if the value was not specified in this entry.. + /// + public IEmote DefaultReactionEmoji { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketChannelInfo.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketChannelInfo.cs new file mode 100644 index 00000000..aa620c0d --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketChannelInfo.cs @@ -0,0 +1,142 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using Model = Discord.API.AuditLogs.ChannelInfoAuditLogModel; + +namespace Discord.WebSocket; + +/// +/// Represents information for a channel. +/// +public struct SocketChannelInfo +{ + internal SocketChannelInfo(Model model) + { + Name = model.Name; + Topic = model.Topic; + IsNsfw = model.IsNsfw; + Bitrate = model.Bitrate; + DefaultArchiveDuration = model.DefaultArchiveDuration; + ChannelType = model.Type; + SlowModeInterval = model.RateLimitPerUser; + + ForumTags = model.AvailableTags?.Select( + x => new ForumTag(x.Id, + x.Name, + x.EmojiId.GetValueOrDefault(null), + x.EmojiName.GetValueOrDefault(null), + x.Moderated)).ToImmutableArray(); + + if (model.DefaultEmoji is not null) + { + if (model.DefaultEmoji.EmojiId.HasValue && model.DefaultEmoji.EmojiId.Value != 0) + DefaultReactionEmoji = new Emote(model.DefaultEmoji.EmojiId.GetValueOrDefault(), null, false); + else if (model.DefaultEmoji.EmojiName.IsSpecified) + DefaultReactionEmoji = new Emoji(model.DefaultEmoji.EmojiName.Value); + else + DefaultReactionEmoji = null; + } + else + DefaultReactionEmoji = null; + AutoArchiveDuration = model.AutoArchiveDuration; + DefaultSlowModeInterval = model.DefaultThreadRateLimitPerUser; + + VideoQualityMode = model.VideoQualityMode; + RTCRegion = model.Region; + Flags = model.Flags; + UserLimit = model.UserLimit; + } + + /// + /// + /// if the value was not updated in this entry. + /// + public string Name { get; } + + /// + /// + /// if the value was not updated in this entry. + /// + public string Topic { get; } + + /// + /// + /// if the value was not updated in this entry. + /// + public int? SlowModeInterval { get; } + + /// + /// + /// if the value was not updated in this entry. + /// + public bool? IsNsfw { get; } + + /// + /// + /// if the value was not updated in this entry. + /// + public int? Bitrate { get; } + + /// + /// Gets the type of this channel. + /// + /// + /// The channel type of this channel; null if not applicable. + /// + public ChannelType? ChannelType { get; } + + /// + /// + /// if the value was not updated in this entry. + /// + public ThreadArchiveDuration? DefaultArchiveDuration { get; } + + /// + /// + /// if the value was not updated in this entry. + /// + public IReadOnlyCollection ForumTags { get; } + + /// + /// + /// if the value was not updated in this entry. + /// + public IEmote DefaultReactionEmoji { get; } + + /// + /// + /// if the value was not updated in this entry. + /// + public int? UserLimit { get; } + + /// + /// + /// if the value was not updated in this entry. + /// + public VideoQualityMode? VideoQualityMode { get; } + + /// + /// + /// if the value was not updated in this entry. + /// + public string RTCRegion { get; } + + /// + /// + /// if the value was not updated in this entry. + /// + public ChannelFlags? Flags { get; } + + /// + /// + /// if the value was not updated in this entry. + /// + public ThreadArchiveDuration? AutoArchiveDuration { get; } + + /// + /// + /// if the value was not updated in this entry. + /// + public int? DefaultSlowModeInterval { get; } + +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketChannelUpdateAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketChannelUpdateAuditLogData.cs new file mode 100644 index 00000000..4494e0aa --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketChannelUpdateAuditLogData.cs @@ -0,0 +1,53 @@ +using Discord.Rest; +using Discord.API.AuditLogs; + +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket +{ + /// + /// Contains a piece of audit log data related to a channel update. + /// + public class SocketChannelUpdateAuditLogData : ISocketAuditLogData + { + private SocketChannelUpdateAuditLogData(ulong id, SocketChannelInfo before, SocketChannelInfo after) + { + ChannelId = id; + Before = before; + After = after; + } + + internal static SocketChannelUpdateAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var changes = entry.Changes; + + var (before, after) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new SocketChannelUpdateAuditLogData(entry.TargetId!.Value, new(before), new(after)); + } + + /// + /// Gets the snowflake ID of the updated channel. + /// + /// + /// A representing the snowflake identifier for the updated channel. + /// + public ulong ChannelId { get; } + + /// + /// Gets the channel information before the changes. + /// + /// + /// An information object containing the original channel information before the changes were made. + /// + public SocketChannelInfo Before { get; } + + /// + /// Gets the channel information after the changes. + /// + /// + /// An information object containing the channel information after the changes were made. + /// + public SocketChannelInfo After { get; } + } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketCommandPermissionUpdateAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketCommandPermissionUpdateAuditLogData.cs new file mode 100644 index 00000000..ec220c1e --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketCommandPermissionUpdateAuditLogData.cs @@ -0,0 +1,63 @@ +using System.Collections.Generic; +using System.Collections.Immutable; + +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to an application command permission update. +/// +public class SocketCommandPermissionUpdateAuditLogData : ISocketAuditLogData +{ + internal SocketCommandPermissionUpdateAuditLogData(IReadOnlyCollection before, IReadOnlyCollection after, + ulong commandId, ulong appId) + { + Before = before; + After = after; + ApplicationId = appId; + CommandId = commandId; + } + + internal static SocketCommandPermissionUpdateAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var changes = entry.Changes; + + var before = new List(); + var after = new List(); + + foreach (var change in changes) + { + var oldValue = change.OldValue?.ToObject(); + var newValue = change.NewValue?.ToObject(); + + if (oldValue is not null) + before.Add(new ApplicationCommandPermission(oldValue.Id, oldValue.Type, oldValue.Permission)); + + if (newValue is not null) + after.Add(new ApplicationCommandPermission(newValue.Id, newValue.Type, newValue.Permission)); + } + + return new(before.ToImmutableArray(), after.ToImmutableArray(), entry.TargetId!.Value, entry.Options.ApplicationId!.Value); + } + + /// + /// Gets the ID of the app whose permissions were targeted. + /// + public ulong ApplicationId { get; set; } + + /// + /// Gets the id of the application command which permissions were updated. + /// + public ulong CommandId { get; } + + /// + /// Gets values of the permissions before the change if available. + /// + public IReadOnlyCollection Before { get; } + + /// + /// Gets values of the permissions after the change if available. + /// + public IReadOnlyCollection After { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketEmoteCreateAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketEmoteCreateAuditLogData.cs new file mode 100644 index 00000000..51d48ef9 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketEmoteCreateAuditLogData.cs @@ -0,0 +1,41 @@ +using System.Linq; + +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to an emoji creation. +/// +public class SocketEmoteCreateAuditLogData : ISocketAuditLogData +{ + private SocketEmoteCreateAuditLogData(ulong id, string name) + { + EmoteId = id; + Name = name; + } + + internal static SocketEmoteCreateAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var change = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "name"); + + var emoteName = change.NewValue?.ToObject(discord.ApiClient.Serializer); + return new SocketEmoteCreateAuditLogData(entry.TargetId!.Value, emoteName); + } + + /// + /// Gets the snowflake ID of the created emoji. + /// + /// + /// A representing the snowflake identifier for the created emoji. + /// + public ulong EmoteId { get; } + + /// + /// Gets the name of the created emoji. + /// + /// + /// A string containing the name of the created emoji. + /// + public string Name { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketEmoteDeleteAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketEmoteDeleteAuditLogData.cs new file mode 100644 index 00000000..6354251a --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketEmoteDeleteAuditLogData.cs @@ -0,0 +1,41 @@ +using System.Linq; +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to an emoji deletion. +/// +public class SocketEmoteDeleteAuditLogData : ISocketAuditLogData +{ + private SocketEmoteDeleteAuditLogData(ulong id, string name) + { + EmoteId = id; + Name = name; + } + + internal static SocketEmoteDeleteAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var change = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "name"); + + var emoteName = change.OldValue?.ToObject(discord.ApiClient.Serializer); + + return new SocketEmoteDeleteAuditLogData(entry.TargetId!.Value, emoteName); + } + + /// + /// Gets the snowflake ID of the deleted emoji. + /// + /// + /// A representing the snowflake identifier for the deleted emoji. + /// + public ulong EmoteId { get; } + + /// + /// Gets the name of the deleted emoji. + /// + /// + /// A string containing the name of the deleted emoji. + /// + public string Name { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketEmoteUpdateAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketEmoteUpdateAuditLogData.cs new file mode 100644 index 00000000..384d4a15 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketEmoteUpdateAuditLogData.cs @@ -0,0 +1,52 @@ +using System.Linq; + +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to an emoji update. +/// +public class SocketEmoteUpdateAuditLogData : ISocketAuditLogData +{ + private SocketEmoteUpdateAuditLogData(ulong id, string oldName, string newName) + { + EmoteId = id; + OldName = oldName; + NewName = newName; + } + + internal static SocketEmoteUpdateAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var change = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "name"); + + var newName = change.NewValue?.ToObject(discord.ApiClient.Serializer); + var oldName = change.OldValue?.ToObject(discord.ApiClient.Serializer); + + return new SocketEmoteUpdateAuditLogData(entry.TargetId!.Value, oldName, newName); + } + + /// + /// Gets the snowflake ID of the updated emoji. + /// + /// + /// A representing the snowflake identifier of the updated emoji. + /// + public ulong EmoteId { get; } + + /// + /// Gets the new name of the updated emoji. + /// + /// + /// A string containing the new name of the updated emoji. + /// + public string NewName { get; } + + /// + /// Gets the old name of the updated emoji. + /// + /// + /// A string containing the old name of the updated emoji. + /// + public string OldName { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketGuildInfo.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketGuildInfo.cs new file mode 100644 index 00000000..ed5d1c47 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketGuildInfo.cs @@ -0,0 +1,191 @@ +using Model = Discord.API.AuditLogs.GuildInfoAuditLogModel; + +namespace Discord.WebSocket; + +/// +/// Represents information for a guild. +/// +public class SocketGuildInfo +{ + internal static SocketGuildInfo Create(Model model) + { + return new() + { + Name = model.Name, + AfkTimeout = model.AfkTimeout.GetValueOrDefault(), + IsEmbeddable = model.IsEmbeddable, + DefaultMessageNotifications = model.DefaultMessageNotifications, + MfaLevel = model.MfaLevel, + Description = model.Description, + PreferredLocale = model.PreferredLocale, + IconHash = model.IconHash, + OwnerId = model.OwnerId, + AfkChannelId = model.AfkChannelId, + ApplicationId = model.ApplicationId, + BannerId = model.Banner, + DiscoverySplashId = model.DiscoverySplash, + EmbedChannelId = model.EmbeddedChannelId, + ExplicitContentFilter = model.ExplicitContentFilterLevel, + IsBoostProgressBarEnabled = model.ProgressBarEnabled, + NsfwLevel = model.NsfwLevel, + PublicUpdatesChannelId = model.PublicUpdatesChannelId, + RegionId = model.RegionId, + RulesChannelId = model.RulesChannelId, + SplashId = model.Splash, + SystemChannelFlags = model.SystemChannelFlags, + SystemChannelId = model.SystemChannelId, + VanityURLCode = model.VanityUrl, + VerificationLevel = model.VerificationLevel + }; + } + + /// + /// + /// if the value was not updated in this entry. + /// + public string Name { get; private set; } + + /// + /// + /// if the value was not updated in this entry. + /// + public int? AfkTimeout { get; private set; } + + /// + /// + /// if the value was not updated in this entry. + /// + public bool? IsEmbeddable { get; private set; } + + /// + /// + /// if the value was not updated in this entry. + /// + public DefaultMessageNotifications? DefaultMessageNotifications { get; private set; } + + /// + /// + /// if the value was not updated in this entry. + /// + public MfaLevel? MfaLevel { get; private set; } + + /// + /// + /// if the value was not updated in this entry. + /// + public VerificationLevel? VerificationLevel { get; private set; } + + /// + /// + /// if the value was not updated in this entry. + /// + public ExplicitContentFilterLevel? ExplicitContentFilter { get; private set; } + + /// + /// + /// if the value was not updated in this entry. + /// + public string IconHash { get; private set; } + + /// + /// + /// if the value was not updated in this entry. + /// + public string SplashId { get; private set; } + + /// + /// + /// if the value was not updated in this entry. + /// + public string DiscoverySplashId { get; private set; } + + /// + /// + /// if the value was not updated in this entry. + /// + public ulong? AfkChannelId { get; private set; } + + /// + /// + /// if the value was not updated in this entry. + /// + public ulong? EmbedChannelId { get; private set; } + + /// + /// + /// if the value was not updated in this entry. + /// + public ulong? SystemChannelId { get; private set; } + + /// + /// + /// if the value was not updated in this entry. + /// + public ulong? RulesChannelId { get; private set; } + + /// + /// + /// if the value was not updated in this entry. + /// + public ulong? PublicUpdatesChannelId { get; private set; } + + /// + /// + /// if the value was not updated in this entry. + /// + public ulong? OwnerId { get; private set; } + + /// + /// + /// if the value was not updated in this entry. + /// + public ulong? ApplicationId { get; private set; } + + /// + /// + /// if the value was not updated in this entry. + /// + public string RegionId { get; private set; } + + /// + /// + /// if the value was not updated in this entry. + /// + public string BannerId { get; private set; } + + /// + /// + /// if the value was not updated in this entry. + /// + public string VanityURLCode { get; private set; } + + /// + /// + /// if the value was not updated in this entry. + /// + public SystemChannelMessageDeny? SystemChannelFlags { get; private set; } + + /// + /// + /// if the value was not updated in this entry. + /// + public string Description { get; private set; } + + /// + /// + /// if the value was not updated in this entry. + /// + public string PreferredLocale { get; private set; } + + /// + /// + /// if the value was not updated in this entry. + /// + public NsfwLevel? NsfwLevel { get; private set; } + + /// + /// + /// if the value was not updated in this entry. + /// + public bool? IsBoostProgressBarEnabled { get; private set; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketGuildUpdateAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketGuildUpdateAuditLogData.cs new file mode 100644 index 00000000..c912b67e --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketGuildUpdateAuditLogData.cs @@ -0,0 +1,42 @@ +using System.Linq; + +using EntryModel = Discord.API.AuditLogEntry; +using InfoModel = Discord.API.AuditLogs.GuildInfoAuditLogModel; + +namespace Discord.WebSocket +{ + /// + /// Contains a piece of audit log data related to a guild update. + /// + public class SocketGuildUpdateAuditLogData : ISocketAuditLogData + { + private SocketGuildUpdateAuditLogData(SocketGuildInfo before, SocketGuildInfo after) + { + Before = before; + After = after; + } + + internal static SocketGuildUpdateAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var info = Rest.AuditLogHelper.CreateAuditLogEntityInfo(entry.Changes, discord); + + var data = new SocketGuildUpdateAuditLogData(SocketGuildInfo.Create(info.Item1), SocketGuildInfo.Create(info.Item2)); + return data; + } + + /// + /// Gets the guild information before the changes. + /// + /// + /// An information object containing the original guild information before the changes were made. + /// + public SocketGuildInfo Before { get; } + /// + /// Gets the guild information after the changes. + /// + /// + /// An information object containing the guild information after the changes were made. + /// + public SocketGuildInfo After { get; } + } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketIntegrationCreatedAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketIntegrationCreatedAuditLogData.cs new file mode 100644 index 00000000..1afb5750 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketIntegrationCreatedAuditLogData.cs @@ -0,0 +1,30 @@ +using Discord.API.AuditLogs; +using Discord.Rest; +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to an integration authorization. +/// +public class SocketIntegrationCreatedAuditLogData : ISocketAuditLogData +{ + internal SocketIntegrationCreatedAuditLogData(SocketIntegrationInfo info) + { + Data = info; + } + + internal static SocketIntegrationCreatedAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var changes = entry.Changes; + + var (_, data) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new(new SocketIntegrationInfo(data)); + } + + /// + /// Gets the integration information after the changes. + /// + public SocketIntegrationInfo Data { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketIntegrationDeletedAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketIntegrationDeletedAuditLogData.cs new file mode 100644 index 00000000..eb78b8fa --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketIntegrationDeletedAuditLogData.cs @@ -0,0 +1,30 @@ +using Discord.API.AuditLogs; +using Discord.Rest; +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to an integration removal. +/// +public class SocketIntegrationDeletedAuditLogData : ISocketAuditLogData +{ + internal SocketIntegrationDeletedAuditLogData(SocketIntegrationInfo info) + { + Data = info; + } + + internal static SocketIntegrationDeletedAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var changes = entry.Changes; + + var (data, _) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new(new SocketIntegrationInfo(data)); + } + + /// + /// Gets the integration information before the changes. + /// + public SocketIntegrationInfo Data { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketIntegrationInfo.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketIntegrationInfo.cs new file mode 100644 index 00000000..9f095d5a --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketIntegrationInfo.cs @@ -0,0 +1,69 @@ +using Discord.API.AuditLogs; +using System.Collections.Generic; +using System.Collections.Immutable; + +namespace Discord.WebSocket; + +/// +/// Represents information for an integration. +/// +public class SocketIntegrationInfo +{ + internal SocketIntegrationInfo(IntegrationInfoAuditLogModel model) + { + Name = model.Name; + Type = model.Type; + EnableEmojis = model.EnableEmojis; + Enabled = model.Enabled; + Scopes = model.Scopes?.ToImmutableArray(); + ExpireBehavior = model.ExpireBehavior; + ExpireGracePeriod = model.ExpireGracePeriod; + Syncing = model.Syncing; + RoleId = model.RoleId; + } + + /// + /// Gets the name of the integration. if the property was not mentioned in this audit log. + /// + public string Name { get; set; } + + /// + /// Gets the type of the integration. if the property was not mentioned in this audit log. + /// + public string Type { get; set; } + + /// + /// Gets if the integration is enabled. if the property was not mentioned in this audit log. + /// + public bool? Enabled { get; set; } + + /// + /// Gets if syncing is enabled for this integration. if the property was not mentioned in this audit log. + /// + public bool? Syncing { get; set; } + + /// + /// Gets the id of the role that this integration uses for subscribers. if the property was not mentioned in this audit log. + /// + public ulong? RoleId { get; set; } + + /// + /// Gets whether emoticons should be synced for this integration. if the property was not mentioned in this audit log. + /// + public bool? EnableEmojis { get; set; } + + /// + /// Gets the behavior of expiring subscribers. if the property was not mentioned in this audit log. + /// + public IntegrationExpireBehavior? ExpireBehavior { get; set; } + + /// + /// Gets the grace period (in days) before expiring subscribers. if the property was not mentioned in this audit log. + /// + public int? ExpireGracePeriod { get; set; } + + /// + /// Gets the scopes the application has been authorized for. if the property was not mentioned in this audit log. + /// + public IReadOnlyCollection Scopes { get; set; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketIntegrationUpdatedAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketIntegrationUpdatedAuditLogData.cs new file mode 100644 index 00000000..e6cbac52 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketIntegrationUpdatedAuditLogData.cs @@ -0,0 +1,36 @@ +using Discord.API.AuditLogs; +using Discord.Rest; +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to an integration update. +/// +public class SocketIntegrationUpdatedAuditLogData : ISocketAuditLogData +{ + internal SocketIntegrationUpdatedAuditLogData(SocketIntegrationInfo before, SocketIntegrationInfo after) + { + Before = before; + After = after; + } + + internal static SocketIntegrationUpdatedAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var changes = entry.Changes; + + var (before, after) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new(new SocketIntegrationInfo(before), new SocketIntegrationInfo(after)); + } + + /// + /// Gets the integration information before the changes. + /// + public SocketIntegrationInfo Before { get; } + + /// + /// Gets the integration information after the changes. + /// + public SocketIntegrationInfo After { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketInviteCreateAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketInviteCreateAuditLogData.cs new file mode 100644 index 00000000..7c648222 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketInviteCreateAuditLogData.cs @@ -0,0 +1,110 @@ +using Discord.API.AuditLogs; +using Discord.Rest; + +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to an invite creation. +/// +public class SocketInviteCreateAuditLogData : ISocketAuditLogData +{ + private SocketInviteCreateAuditLogData(InviteInfoAuditLogModel model, Cacheable? inviter) + { + MaxAge = model.MaxAge!.Value; + Code = model.Code; + Temporary = model.Temporary!.Value; + ChannelId = model.ChannelId!.Value; + Uses = model.Uses!.Value; + MaxUses = model.MaxUses!.Value; + + Creator = inviter; + } + + internal static SocketInviteCreateAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var changes = entry.Changes; + + var (_, data) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + Cacheable? cacheableUser = null; + + if (data.InviterId is not null) + { + var cachedUser = discord.GetUser(data.InviterId.Value); + cacheableUser = new Cacheable( + cachedUser, + data.InviterId.Value, + cachedUser is not null, + async () => + { + var user = await discord.ApiClient.GetUserAsync(data.InviterId.Value); + return user is not null ? RestUser.Create(discord, user) : null; + }); + } + + return new SocketInviteCreateAuditLogData(data, cacheableUser); + } + + /// + /// Gets the time (in seconds) until the invite expires. + /// + /// + /// An representing the time in seconds until this invite expires. + /// + public int MaxAge { get; } + + /// + /// Gets the unique identifier for this invite. + /// + /// + /// A string containing the invite code (e.g. FTqNnyS). + /// + public string Code { get; } + + /// + /// Gets a value that determines whether the invite is a temporary one. + /// + /// + /// true if users accepting this invite will be removed from the guild when they log off; otherwise + /// false. + /// + public bool Temporary { get; } + + /// + /// Gets the user that created this invite if available. + /// + /// + /// Will be if the user is a 'Deleted User#....' because Discord does send user data for deleted users. + /// + /// + /// A user that created this invite or . + /// + public Cacheable? Creator { get; } + + /// + /// Gets the ID of the channel this invite is linked to. + /// + /// + /// A representing the channel snowflake identifier that the invite points to. + /// + public ulong ChannelId { get; } + + /// + /// Gets the number of times this invite has been used. + /// + /// + /// An representing the number of times this invite was used. + /// + public int Uses { get; } + + /// + /// Gets the max number of uses this invite may have. + /// + /// + /// An representing the number of uses this invite may be accepted until it is removed + /// from the guild; null if none is set. + /// + public int MaxUses { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketInviteDeleteAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketInviteDeleteAuditLogData.cs new file mode 100644 index 00000000..15df061c --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketInviteDeleteAuditLogData.cs @@ -0,0 +1,109 @@ +using Discord.API.AuditLogs; +using Discord.Rest; + +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to an invite removal. +/// +public class SocketInviteDeleteAuditLogData : ISocketAuditLogData +{ + private SocketInviteDeleteAuditLogData(InviteInfoAuditLogModel model, Cacheable? inviter) + { + MaxAge = model.MaxAge!.Value; + Code = model.Code; + Temporary = model.Temporary!.Value; + Creator = inviter; + ChannelId = model.ChannelId!.Value; + Uses = model.Uses!.Value; + MaxUses = model.MaxUses!.Value; + } + + internal static SocketInviteDeleteAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var changes = entry.Changes; + + var (data, _) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + Cacheable? cacheableUser = null; + + if (data.InviterId != null) + { + var cachedUser = discord.GetUser(data.InviterId.Value); + cacheableUser = new Cacheable( + cachedUser, + data.InviterId.Value, + cachedUser is not null, + async () => + { + var user = await discord.ApiClient.GetUserAsync(data.InviterId.Value); + return user is not null ? RestUser.Create(discord, user) : null; + }); + } + + return new SocketInviteDeleteAuditLogData(data, cacheableUser); + } + + /// + /// Gets the time (in seconds) until the invite expires. + /// + /// + /// An representing the time in seconds until this invite expires. + /// + public int MaxAge { get; } + + /// + /// Gets the unique identifier for this invite. + /// + /// + /// A string containing the invite code (e.g. FTqNnyS). + /// + public string Code { get; } + + /// + /// Gets a value that indicates whether the invite is a temporary one. + /// + /// + /// true if users accepting this invite will be removed from the guild when they log off; otherwise + /// false. + /// + public bool Temporary { get; } + + /// + /// Gets the user that created this invite if available. + /// + /// + /// Will be if the user is a 'Deleted User#....' because Discord does send user data for deleted users. + /// + /// + /// A user that created this invite or . + /// + public Cacheable? Creator { get; } + + /// + /// Gets the ID of the channel this invite is linked to. + /// + /// + /// A representing the channel snowflake identifier that the invite points to. + /// + public ulong ChannelId { get; } + + /// + /// Gets the number of times this invite has been used. + /// + /// + /// An representing the number of times this invite has been used. + /// + public int Uses { get; } + + /// + /// Gets the max number of uses this invite may have. + /// + /// + /// An representing the number of uses this invite may be accepted until it is removed + /// from the guild; null if none is set. + /// + public int MaxUses { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketInviteInfo.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketInviteInfo.cs new file mode 100644 index 00000000..bfb51912 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketInviteInfo.cs @@ -0,0 +1,68 @@ +using Model = Discord.API.AuditLogs.InviteInfoAuditLogModel; + +namespace Discord.WebSocket; + +/// +/// Represents information for an invite. +/// +public struct SocketInviteInfo +{ + internal SocketInviteInfo(Model model) + { + MaxAge = model.MaxAge; + Code = model.Code; + Temporary = model.Temporary; + ChannelId = model.ChannelId; + MaxUses = model.MaxUses; + CreatorId = model.InviterId; + } + + /// + /// Gets the time (in seconds) until the invite expires. + /// + /// + /// An representing the time in seconds until this invite expires; null if this + /// invite never expires or not specified. + /// + public int? MaxAge { get; } + + /// + /// Gets the unique identifier for this invite. + /// + /// + /// A string containing the invite code (e.g. FTqNnyS). + /// + public string Code { get; } + + /// + /// Gets a value that indicates whether the invite is a temporary one. + /// + /// + /// true if users accepting this invite will be removed from the guild when they log off, + /// false if not; null if not specified. + /// + public bool? Temporary { get; } + + /// + /// Gets the ID of the channel this invite is linked to. + /// + /// + /// A representing the channel snowflake identifier that the invite points to; + /// null if not specified. + /// + public ulong? ChannelId { get; } + + /// + /// Gets the max number of uses this invite may have. + /// + /// + /// An representing the number of uses this invite may be accepted until it is removed + /// from the guild; null if none is specified. + /// + public int? MaxUses { get; } + + /// + /// Gets the id of the user created this invite. + /// + public ulong? CreatorId { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketInviteUpdateAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketInviteUpdateAuditLogData.cs new file mode 100644 index 00000000..a4134079 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketInviteUpdateAuditLogData.cs @@ -0,0 +1,42 @@ +using Discord.API.AuditLogs; +using Discord.Rest; +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data relating to an invite update. +/// +public class SocketInviteUpdateAuditLogData : ISocketAuditLogData +{ + private SocketInviteUpdateAuditLogData(SocketInviteInfo before, SocketInviteInfo after) + { + Before = before; + After = after; + } + + internal static SocketInviteUpdateAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var changes = entry.Changes; + + var (before, after) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new SocketInviteUpdateAuditLogData(new(before), new(after)); + } + + /// + /// Gets the invite information before the changes. + /// + /// + /// An information object containing the original invite information before the changes were made. + /// + public SocketInviteInfo Before { get; } + + /// + /// Gets the invite information after the changes. + /// + /// + /// An information object containing the invite information after the changes were made. + /// + public SocketInviteInfo After { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketKickAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketKickAuditLogData.cs new file mode 100644 index 00000000..169d7668 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketKickAuditLogData.cs @@ -0,0 +1,43 @@ +using Discord.Rest; +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to a kick. +/// +public class SocketKickAuditLogData : ISocketAuditLogData +{ + private SocketKickAuditLogData(Cacheable user) + { + Target = user; + } + + internal static SocketKickAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var cachedUser = discord.GetUser(entry.Id); + var cacheableUser = new Cacheable( + cachedUser, + entry.Id, + cachedUser is not null, + async () => + { + var user = await discord.ApiClient.GetUserAsync(entry.TargetId!.Value); + return user is not null ? RestUser.Create(discord, user) : null; + }); + + return new SocketKickAuditLogData(cacheableUser); + } + + /// + /// Gets the user that was kicked. + /// + /// + /// Download method may return if the user is a 'Deleted User#....' + /// because Discord does send user data for deleted users. + /// + /// + /// A cacheable user object representing the kicked user. + /// + public Cacheable Target { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketMemberDisconnectAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketMemberDisconnectAuditLogData.cs new file mode 100644 index 00000000..42f1df41 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketMemberDisconnectAuditLogData.cs @@ -0,0 +1,27 @@ +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to disconnecting members from voice channels. +/// +public class SocketMemberDisconnectAuditLogData : ISocketAuditLogData +{ + private SocketMemberDisconnectAuditLogData(int count) + { + MemberCount = count; + } + + internal static SocketMemberDisconnectAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + return new SocketMemberDisconnectAuditLogData(entry.Options.Count!.Value); + } + + /// + /// Gets the number of members that were disconnected. + /// + /// + /// An representing the number of members that were disconnected from a voice channel. + /// + public int MemberCount { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketMemberMoveAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketMemberMoveAuditLogData.cs new file mode 100644 index 00000000..f158b0fa --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketMemberMoveAuditLogData.cs @@ -0,0 +1,36 @@ +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to moving members between voice channels. +/// +public class SocketMemberMoveAuditLogData : ISocketAuditLogData +{ + private SocketMemberMoveAuditLogData(ulong channelId, int count) + { + ChannelId = channelId; + MemberCount = count; + } + + internal static SocketMemberMoveAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + return new SocketMemberMoveAuditLogData(entry.Options.ChannelId!.Value, entry.Options.Count!.Value); + } + + /// + /// Gets the ID of the channel that the members were moved to. + /// + /// + /// A representing the snowflake identifier for the channel that the members were moved to. + /// + public ulong ChannelId { get; } + + /// + /// Gets the number of members that were moved. + /// + /// + /// An representing the number of members that were moved to another voice channel. + /// + public int MemberCount { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketMemberRoleAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketMemberRoleAuditLogData.cs new file mode 100644 index 00000000..9264f6d1 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketMemberRoleAuditLogData.cs @@ -0,0 +1,58 @@ +using Discord.Rest; +using System.Collections.Generic; +using System.Linq; +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to a change in a guild member's roles. +/// +public class SocketMemberRoleAuditLogData : ISocketAuditLogData +{ + private SocketMemberRoleAuditLogData(IReadOnlyCollection roles, Cacheable target) + { + Roles = roles; + Target = target; + } + + internal static SocketMemberRoleAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var changes = entry.Changes; + + var roleInfos = changes.SelectMany(x => x.NewValue.ToObject(discord.ApiClient.Serializer), + (model, role) => new { model.ChangedProperty, Role = role }) + .Select(x => new SocketMemberRoleEditInfo(x.Role.Name, x.Role.Id, x.ChangedProperty == "$add")) + .ToList(); + + var cachedUser = discord.GetUser(entry.TargetId!.Value); + var cacheableUser = new Cacheable( + cachedUser, + entry.TargetId.Value, + cachedUser is not null, + async () => + { + var user = await discord.ApiClient.GetUserAsync(entry.TargetId.Value); + return user is not null ? RestUser.Create(discord, user) : null; + }); + + return new SocketMemberRoleAuditLogData(roleInfos.ToReadOnlyCollection(), cacheableUser); + } + + /// + /// Gets a collection of role changes that were performed on the member. + /// + /// + /// A read-only collection of , containing the roles that were changed on + /// the member. + /// + public IReadOnlyCollection Roles { get; } + + /// + /// Gets the user that the roles changes were performed on. + /// + /// + /// A cacheable user object representing the user that the role changes were performed on. + /// + public Cacheable Target { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketMemberRoleEditInfo.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketMemberRoleEditInfo.cs new file mode 100644 index 00000000..66ff970c --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketMemberRoleEditInfo.cs @@ -0,0 +1,36 @@ +namespace Discord.WebSocket; + +/// +/// An information object representing a change in one of a guild member's roles. +/// +public struct SocketMemberRoleEditInfo +{ + internal SocketMemberRoleEditInfo(string name, ulong roleId, bool added) + { + Name = name; + RoleId = roleId; + Added = added; + } + + /// + /// Gets the name of the role that was changed. + /// + /// + /// A string containing the name of the role that was changed. + /// + public string Name { get; } + /// + /// Gets the ID of the role that was changed. + /// + /// + /// A representing the snowflake identifier of the role that was changed. + /// + public ulong RoleId { get; } + /// + /// Gets a value that indicates whether the role was added to the user. + /// + /// + /// true if the role was added to the user; otherwise false. + /// + public bool Added { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketMemberUpdateAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketMemberUpdateAuditLogData.cs new file mode 100644 index 00000000..93c0263e --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketMemberUpdateAuditLogData.cs @@ -0,0 +1,65 @@ +using Discord.API.AuditLogs; +using Discord.Rest; +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to a change in a guild member. +/// +public class SocketMemberUpdateAuditLogData : ISocketAuditLogData +{ + private SocketMemberUpdateAuditLogData(Cacheable target, MemberInfo before, MemberInfo after) + { + Target = target; + Before = before; + After = after; + } + + internal static SocketMemberUpdateAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var changes = entry.Changes; + + var (before, after) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + var cachedUser = discord.GetUser(entry.TargetId!.Value); + var cacheableUser = new Cacheable( + cachedUser, + entry.TargetId.Value, + cachedUser is not null, + async () => + { + var user = await discord.ApiClient.GetUserAsync(entry.TargetId.Value); + return user is not null ? RestUser.Create(discord, user) : null; + }); + + return new SocketMemberUpdateAuditLogData(cacheableUser, new MemberInfo(before), new MemberInfo(after)); + } + + /// + /// Gets the user that the changes were performed on. + /// + /// + /// Will be if the user is a 'Deleted User#....' because Discord does send user data for deleted users. + /// + /// + /// A user object representing the user who the changes were performed on. + /// + public Cacheable Target { get; } + + /// + /// Gets the member information before the changes. + /// + /// + /// An information object containing the original member information before the changes were made. + /// + public MemberInfo Before { get; } + + /// + /// Gets the member information after the changes. + /// + /// + /// An information object containing the member information after the changes were made. + /// + public MemberInfo After { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketMessageBulkDeleteAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketMessageBulkDeleteAuditLogData.cs new file mode 100644 index 00000000..be292c22 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketMessageBulkDeleteAuditLogData.cs @@ -0,0 +1,37 @@ +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to message deletion(s). +/// +public class SocketMessageBulkDeleteAuditLogData : ISocketAuditLogData +{ + private SocketMessageBulkDeleteAuditLogData(ulong channelId, int count) + { + ChannelId = channelId; + MessageCount = count; + } + + internal static SocketMessageBulkDeleteAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + return new SocketMessageBulkDeleteAuditLogData(entry.TargetId!.Value, entry.Options.Count!.Value); + } + + /// + /// Gets the ID of the channel that the messages were deleted from. + /// + /// + /// A representing the snowflake identifier for the channel that the messages were + /// deleted from. + /// + public ulong ChannelId { get; } + + /// + /// Gets the number of messages that were deleted. + /// + /// + /// An representing the number of messages that were deleted from the channel. + /// + public int MessageCount { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketMessageDeleteAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketMessageDeleteAuditLogData.cs new file mode 100644 index 00000000..706e2405 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketMessageDeleteAuditLogData.cs @@ -0,0 +1,62 @@ +using Discord.Rest; +using System; +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to message deletion(s). +/// +public class SocketMessageDeleteAuditLogData : ISocketAuditLogData +{ + private SocketMessageDeleteAuditLogData(ulong channelId, int count, Cacheable user) + { + ChannelId = channelId; + MessageCount = count; + Target = user; + } + + internal static SocketMessageDeleteAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var cachedUser = discord.GetUser(entry.TargetId!.Value); + var cacheableUser = new Cacheable( + cachedUser, + entry.TargetId.Value, + cachedUser is not null, + async () => + { + var user = await discord.ApiClient.GetUserAsync(entry.TargetId.Value); + return user is not null ? RestUser.Create(discord, user) : null; + }); + + return new SocketMessageDeleteAuditLogData(entry.Options.ChannelId!.Value, entry.Options.Count!.Value, cacheableUser); + } + + /// + /// Gets the number of messages that were deleted. + /// + /// + /// An representing the number of messages that were deleted from the channel. + /// + public int MessageCount { get; } + + /// + /// Gets the ID of the channel that the messages were deleted from. + /// + /// + /// A representing the snowflake identifier for the channel that the messages were + /// deleted from. + /// + public ulong ChannelId { get; } + + /// + /// Gets the user of the messages that were deleted. + /// + /// + /// Will be if the user is a 'Deleted User#....' because Discord does send user data for deleted users. + /// + /// + /// A user object representing the user that created the deleted messages. + /// + public Cacheable Target { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketMessagePinAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketMessagePinAuditLogData.cs new file mode 100644 index 00000000..723fb8e0 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketMessagePinAuditLogData.cs @@ -0,0 +1,65 @@ +using Discord.Rest; +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to a pinned message. +/// +public class SocketMessagePinAuditLogData : ISocketAuditLogData +{ + private SocketMessagePinAuditLogData(ulong messageId, ulong channelId, Cacheable? user) + { + MessageId = messageId; + ChannelId = channelId; + Target = user; + } + + internal static SocketMessagePinAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + Cacheable? cacheableUser = null; + + if (entry.TargetId.HasValue) + { + var cachedUser = discord.GetUser(entry.TargetId.Value); + cacheableUser = new Cacheable( + cachedUser, + entry.TargetId.Value, + cachedUser is not null, + async () => + { + var user = await discord.ApiClient.GetUserAsync(entry.TargetId.Value); + return user is not null ? RestUser.Create(discord, user) : null; + }); + } + + return new SocketMessagePinAuditLogData(entry.Options.MessageId!.Value, entry.Options.ChannelId!.Value, cacheableUser); + } + + /// + /// Gets the ID of the messages that was pinned. + /// + /// + /// A representing the snowflake identifier for the messages that was pinned. + /// + public ulong MessageId { get; } + + /// + /// Gets the ID of the channel that the message was pinned from. + /// + /// + /// A representing the snowflake identifier for the channel that the message was pinned from. + /// + public ulong ChannelId { get; } + + /// + /// Gets the user of the message that was pinned if available. + /// + /// + /// Will be if the user is a 'Deleted User#....' because Discord does send user data for deleted users. + /// + /// + /// A user object representing the user that created the pinned message or . + /// + public Cacheable? Target { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketMessageUnpinAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketMessageUnpinAuditLogData.cs new file mode 100644 index 00000000..088152a6 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketMessageUnpinAuditLogData.cs @@ -0,0 +1,64 @@ +using Discord.Rest; +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to an unpinned message. +/// +public class SocketMessageUnpinAuditLogData : ISocketAuditLogData +{ + private SocketMessageUnpinAuditLogData(ulong messageId, ulong channelId, Cacheable? user) + { + MessageId = messageId; + ChannelId = channelId; + Target = user; + } + + internal static SocketMessageUnpinAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + Cacheable? cacheableUser = null; + if (entry.TargetId.HasValue) + { + var cachedUser = discord.GetUser(entry.TargetId.Value); + cacheableUser = new Cacheable( + cachedUser, + entry.TargetId.Value, + cachedUser is not null, + async () => + { + var user = await discord.ApiClient.GetUserAsync(entry.TargetId.Value); + return user is not null ? RestUser.Create(discord, user) : null; + }); + } + + return new SocketMessageUnpinAuditLogData(entry.Options.MessageId!.Value, entry.Options.ChannelId!.Value, cacheableUser); + } + + /// + /// Gets the ID of the messages that was unpinned. + /// + /// + /// A representing the snowflake identifier for the messages that was unpinned. + /// + public ulong MessageId { get; } + + /// + /// Gets the ID of the channel that the message was unpinned from. + /// + /// + /// A representing the snowflake identifier for the channel that the message was unpinned from. + /// + public ulong ChannelId { get; } + + /// + /// Gets the user of the message that was unpinned if available. + /// + /// + /// Will be if the user is a 'Deleted User#....' because Discord does send user data for deleted users. + /// + /// + /// A user object representing the user that created the unpinned message or . + /// + public Cacheable? Target { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketOnboardingInfo.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketOnboardingInfo.cs new file mode 100644 index 00000000..6ecd2221 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketOnboardingInfo.cs @@ -0,0 +1,35 @@ +using Discord.API.AuditLogs; +using Discord.Rest; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; + +namespace Discord.WebSocket; + +public class SocketOnboardingInfo +{ + internal SocketOnboardingInfo(OnboardingAuditLogModel model, DiscordSocketClient discord) + { + Prompts = model.Prompts?.Select(x => new RestGuildOnboardingPrompt(discord, x.Id, x)).ToImmutableArray(); + DefaultChannelIds = model.DefaultChannelIds; + IsEnabled = model.Enabled; + } + + /// + /// + /// if this property is not mentioned in this entry. + /// + IReadOnlyCollection Prompts { get; } + + /// + /// + /// if this property is not mentioned in this entry. + /// + IReadOnlyCollection DefaultChannelIds { get; } + + /// + /// + /// if this property is not mentioned in this entry. + /// + bool? IsEnabled { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketOnboardingPromptCreatedAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketOnboardingPromptCreatedAuditLogData.cs new file mode 100644 index 00000000..7cf75172 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketOnboardingPromptCreatedAuditLogData.cs @@ -0,0 +1,30 @@ +using Discord.API.AuditLogs; +using Discord.Rest; +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to an onboarding prompt creation. +/// +public class SocketOnboardingPromptCreatedAuditLogData : ISocketAuditLogData +{ + internal SocketOnboardingPromptCreatedAuditLogData(SocketOnboardingPromptInfo data) + { + Data = data; + } + + internal static SocketOnboardingPromptCreatedAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var changes = entry.Changes; + + var (_, data) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new SocketOnboardingPromptCreatedAuditLogData(new(data, discord)); + } + + /// + /// Gets the onboarding prompt information after the changes. + /// + SocketOnboardingPromptInfo Data { get; set; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketOnboardingPromptInfo.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketOnboardingPromptInfo.cs new file mode 100644 index 00000000..b5e24781 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketOnboardingPromptInfo.cs @@ -0,0 +1,56 @@ +using Discord.API.AuditLogs; +using Discord.Rest; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; + +namespace Discord.WebSocket; + +public class SocketOnboardingPromptInfo +{ + internal SocketOnboardingPromptInfo(OnboardingPromptAuditLogModel model, DiscordSocketClient discord) + { + Title = model.Title; + IsSingleSelect = model.IsSingleSelect; + IsRequired = model.IsRequired; + IsInOnboarding = model.IsInOnboarding; + Type = model.Type; + Options = model.Options?.Select(x => new RestGuildOnboardingPromptOption(discord, x.Id, x)).ToImmutableArray(); + } + + /// + /// + /// if this property is not mentioned in this entry. + /// + string Title { get; } + + /// + /// + /// if this property is not mentioned in this entry. + /// + bool? IsSingleSelect { get; } + + /// + /// + /// if this property is not mentioned in this entry. + /// + bool? IsRequired { get; } + + /// + /// + /// if this property is not mentioned in this entry. + /// + bool? IsInOnboarding { get; } + + /// + /// + /// if this property is not mentioned in this entry. + /// + GuildOnboardingPromptType? Type { get; } + + /// + /// + /// if this property is not mentioned in this entry. + /// + IReadOnlyCollection Options { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketOnboardingPromptUpdatedAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketOnboardingPromptUpdatedAuditLogData.cs new file mode 100644 index 00000000..ad168d49 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketOnboardingPromptUpdatedAuditLogData.cs @@ -0,0 +1,38 @@ +using Discord.Rest; +using Discord.API.AuditLogs; + +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + + +/// +/// Contains a piece of audit log data related to an onboarding prompt update. +/// +public class SocketOnboardingPromptUpdatedAuditLogData : ISocketAuditLogData +{ + internal SocketOnboardingPromptUpdatedAuditLogData(SocketOnboardingPromptInfo before, SocketOnboardingPromptInfo after) + { + Before = before; + After = after; + } + + internal static SocketOnboardingPromptUpdatedAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var changes = entry.Changes; + + var (before, after) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new SocketOnboardingPromptUpdatedAuditLogData(new(before, discord), new(after, discord)); + } + + /// + /// Gets the onboarding prompt information after the changes. + /// + SocketOnboardingPromptInfo After { get; set; } + + /// + /// Gets the onboarding prompt information before the changes. + /// + SocketOnboardingPromptInfo Before { get; set; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketOnboardingUpdatedAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketOnboardingUpdatedAuditLogData.cs new file mode 100644 index 00000000..1ee9499c --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketOnboardingUpdatedAuditLogData.cs @@ -0,0 +1,37 @@ +namespace Discord.WebSocket; + +using Discord.Rest; +using Discord.API.AuditLogs; + +using EntryModel = Discord.API.AuditLogEntry; + +/// +/// Contains a piece of audit log data related to a guild update. +/// +public class SocketOnboardingUpdatedAuditLogData : ISocketAuditLogData +{ + internal SocketOnboardingUpdatedAuditLogData(SocketOnboardingInfo before, SocketOnboardingInfo after) + { + Before = before; + After = after; + } + + internal static SocketOnboardingUpdatedAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var changes = entry.Changes; + + var (before, after) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new SocketOnboardingUpdatedAuditLogData(new(before, discord), new(after, discord)); + } + + /// + /// Gets the onboarding information after the changes. + /// + SocketOnboardingInfo After { get; set; } + + /// + /// Gets the onboarding information before the changes. + /// + SocketOnboardingInfo Before { get; set; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketOverwriteCreateAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketOverwriteCreateAuditLogData.cs new file mode 100644 index 00000000..79f9b8cc --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketOverwriteCreateAuditLogData.cs @@ -0,0 +1,52 @@ +using System.Linq; + +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data for a permissions overwrite creation. +/// +public class SocketOverwriteCreateAuditLogData : ISocketAuditLogData +{ + private SocketOverwriteCreateAuditLogData(ulong channelId, Overwrite overwrite) + { + ChannelId = channelId; + Overwrite = overwrite; + } + + internal static SocketOverwriteCreateAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var changes = entry.Changes; + + var denyModel = changes.FirstOrDefault(x => x.ChangedProperty == "deny"); + var allowModel = changes.FirstOrDefault(x => x.ChangedProperty == "allow"); + + var deny = denyModel.NewValue.ToObject(discord.ApiClient.Serializer); + var allow = allowModel.NewValue.ToObject(discord.ApiClient.Serializer); + + var permissions = new OverwritePermissions(allow, deny); + + var id = entry.Options.OverwriteTargetId.Value; + var type = entry.Options.OverwriteType; + + return new SocketOverwriteCreateAuditLogData(entry.TargetId.Value, new Overwrite(id, type, permissions)); + } + + /// + /// Gets the ID of the channel that the overwrite was created from. + /// + /// + /// A representing the snowflake identifier for the channel that the overwrite was + /// created from. + /// + public ulong ChannelId { get; } + + /// + /// Gets the permission overwrite object that was created. + /// + /// + /// An object representing the overwrite that was created. + /// + public Overwrite Overwrite { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketOverwriteDeleteAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketOverwriteDeleteAuditLogData.cs new file mode 100644 index 00000000..6065200a --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketOverwriteDeleteAuditLogData.cs @@ -0,0 +1,51 @@ +using System.Linq; +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to the deletion of a permission overwrite. +/// +public class SocketOverwriteDeleteAuditLogData : ISocketAuditLogData +{ + private SocketOverwriteDeleteAuditLogData(ulong channelId, Overwrite deletedOverwrite) + { + ChannelId = channelId; + Overwrite = deletedOverwrite; + } + + internal static SocketOverwriteDeleteAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var changes = entry.Changes; + + var denyModel = changes.FirstOrDefault(x => x.ChangedProperty == "deny"); + var allowModel = changes.FirstOrDefault(x => x.ChangedProperty == "allow"); + + var deny = denyModel.OldValue.ToObject(discord.ApiClient.Serializer); + var allow = allowModel.OldValue.ToObject(discord.ApiClient.Serializer); + + var permissions = new OverwritePermissions(allow, deny); + + var id = entry.Options.OverwriteTargetId.Value; + var type = entry.Options.OverwriteType; + + return new SocketOverwriteDeleteAuditLogData(entry.TargetId!.Value, new Overwrite(id, type, permissions)); + } + + /// + /// Gets the ID of the channel that the overwrite was deleted from. + /// + /// + /// A representing the snowflake identifier for the channel that the overwrite was + /// deleted from. + /// + public ulong ChannelId { get; } + + /// + /// Gets the permission overwrite object that was deleted. + /// + /// + /// An object representing the overwrite that was deleted. + /// + public Overwrite Overwrite { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketOverwriteUpdateAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketOverwriteUpdateAuditLogData.cs new file mode 100644 index 00000000..fd21a97d --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketOverwriteUpdateAuditLogData.cs @@ -0,0 +1,83 @@ +using System.Linq; + +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to the update of a permission overwrite. +/// +public class SocketOverwriteUpdateAuditLogData : ISocketAuditLogData +{ + private SocketOverwriteUpdateAuditLogData(ulong channelId, OverwritePermissions before, OverwritePermissions after, ulong targetId, PermissionTarget targetType) + { + ChannelId = channelId; + OldPermissions = before; + NewPermissions = after; + OverwriteTargetId = targetId; + OverwriteType = targetType; + } + + internal static SocketOverwriteUpdateAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var changes = entry.Changes; + + var denyModel = changes.FirstOrDefault(x => x.ChangedProperty == "deny"); + var allowModel = changes.FirstOrDefault(x => x.ChangedProperty == "allow"); + + var beforeAllow = allowModel?.OldValue?.ToObject(discord.ApiClient.Serializer); + var afterAllow = allowModel?.NewValue?.ToObject(discord.ApiClient.Serializer); + var beforeDeny = denyModel?.OldValue?.ToObject(discord.ApiClient.Serializer); + var afterDeny = denyModel?.NewValue?.ToObject(discord.ApiClient.Serializer); + + var beforePermissions = new OverwritePermissions(beforeAllow ?? 0, beforeDeny ?? 0); + var afterPermissions = new OverwritePermissions(afterAllow ?? 0, afterDeny ?? 0); + + var type = entry.Options.OverwriteType; + + return new SocketOverwriteUpdateAuditLogData(entry.TargetId.Value, beforePermissions, afterPermissions, entry.Options.OverwriteTargetId.Value, type); + } + + /// + /// Gets the ID of the channel that the overwrite was updated from. + /// + /// + /// A representing the snowflake identifier for the channel that the overwrite was + /// updated from. + /// + public ulong ChannelId { get; } + + /// + /// Gets the overwrite permissions before the changes. + /// + /// + /// An overwrite permissions object representing the overwrite permissions that the overwrite had before + /// the changes were made. + /// + public OverwritePermissions OldPermissions { get; } + + /// + /// Gets the overwrite permissions after the changes. + /// + /// + /// An overwrite permissions object representing the overwrite permissions that the overwrite had after the + /// changes. + /// + public OverwritePermissions NewPermissions { get; } + + /// + /// Gets the ID of the overwrite that was updated. + /// + /// + /// A representing the snowflake identifier of the overwrite that was updated. + /// + public ulong OverwriteTargetId { get; } + + /// + /// Gets the target of the updated permission overwrite. + /// + /// + /// The target of the updated permission overwrite. + /// + public PermissionTarget OverwriteType { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketPruneAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketPruneAuditLogData.cs new file mode 100644 index 00000000..5da0a973 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketPruneAuditLogData.cs @@ -0,0 +1,39 @@ +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to a guild prune. +/// +public class SocketPruneAuditLogData : ISocketAuditLogData +{ + private SocketPruneAuditLogData(int pruneDays, int membersRemoved) + { + PruneDays = pruneDays; + MembersRemoved = membersRemoved; + } + + internal static SocketPruneAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + return new SocketPruneAuditLogData(entry.Options.PruneDeleteMemberDays!.Value, entry.Options.PruneMembersRemoved!.Value); + } + + /// + /// Gets the threshold for a guild member to not be kicked. + /// + /// + /// An representing the amount of days that a member must have been seen in the server, + /// to avoid being kicked. (i.e. If a user has not been seen for more than , they will be + /// kicked from the server) + /// + public int PruneDays { get; } + + /// + /// Gets the number of members that were kicked during the purge. + /// + /// + /// An representing the number of members that were removed from this guild for having + /// not been seen within . + /// + public int MembersRemoved { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketRoleCreateAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketRoleCreateAuditLogData.cs new file mode 100644 index 00000000..ea600bbb --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketRoleCreateAuditLogData.cs @@ -0,0 +1,44 @@ +using Discord.Rest; + +using EntryModel = Discord.API.AuditLogEntry; +using Model = Discord.API.AuditLogs.RoleInfoAuditLogModel; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to a role creation. +/// +public class SocketRoleCreateAuditLogData : ISocketAuditLogData +{ + private SocketRoleCreateAuditLogData(ulong id, SocketRoleEditInfo props) + { + RoleId = id; + Properties = props; + } + + internal static SocketRoleCreateAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var changes = entry.Changes; + + var (_, data) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new SocketRoleCreateAuditLogData(entry.TargetId!.Value, + new SocketRoleEditInfo(data)); + } + + /// + /// Gets the ID of the role that was created. + /// + /// + /// A representing the snowflake identifier to the role that was created. + /// + public ulong RoleId { get; } + + /// + /// Gets the role information that was created. + /// + /// + /// An information object representing the properties of the role that was created. + /// + public SocketRoleEditInfo Properties { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketRoleDeleteAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketRoleDeleteAuditLogData.cs new file mode 100644 index 00000000..dc1cd922 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketRoleDeleteAuditLogData.cs @@ -0,0 +1,43 @@ +using Discord.Rest; +using EntryModel = Discord.API.AuditLogEntry; +using Model = Discord.API.AuditLogs.RoleInfoAuditLogModel; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data relating to a role deletion. +/// +public class SocketRoleDeleteAuditLogData : ISocketAuditLogData +{ + private SocketRoleDeleteAuditLogData(ulong id, SocketRoleEditInfo props) + { + RoleId = id; + Properties = props; + } + + internal static SocketRoleDeleteAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var changes = entry.Changes; + + var (data, _) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new SocketRoleDeleteAuditLogData(entry.TargetId!.Value, + new SocketRoleEditInfo(data)); + } + + /// + /// Gets the ID of the role that was deleted. + /// + /// + /// A representing the snowflake identifier to the role that was deleted. + /// + public ulong RoleId { get; } + + /// + /// Gets the role information that was deleted. + /// + /// + /// An information object representing the properties of the role that was deleted. + /// + public SocketRoleEditInfo Properties { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketRoleEditInfo.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketRoleEditInfo.cs new file mode 100644 index 00000000..1bb99337 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketRoleEditInfo.cs @@ -0,0 +1,79 @@ +using Model = Discord.API.AuditLogs.RoleInfoAuditLogModel; + +namespace Discord.WebSocket; + +/// +/// Represents information for a role edit. +/// +public struct SocketRoleEditInfo +{ + internal SocketRoleEditInfo(Model model) + { + if (model.Color is not null) + Color = new Color(model.Color.Value); + else + Color = null; + + Mentionable = model.IsMentionable; + Hoist = model.Hoist; + Name = model.Name; + + if(model.Permissions is not null) + Permissions = new GuildPermissions(model.Permissions.Value); + else + Permissions = null; + + IconId = model.IconHash; + } + + /// + /// Gets the color of this role. + /// + /// + /// A color object representing the color assigned to this role; null if this role does not have a + /// color. + /// + public Color? Color { get; } + + /// + /// Gets a value that indicates whether this role is mentionable. + /// + /// + /// true if other members can mention this role in a text channel; otherwise false; + /// null if this is not mentioned in this entry. + /// + public bool? Mentionable { get; } + + /// + /// Gets a value that indicates whether this role is hoisted (i.e. its members will appear in a separate + /// section on the user list). + /// + /// + /// true if this role's members will appear in a separate section in the user list; otherwise + /// false; null if this is not mentioned in this entry. + /// + public bool? Hoist { get; } + + /// + /// Gets the name of this role. + /// + /// + /// A string containing the name of this role. + /// + public string Name { get; } + + /// + /// Gets the permissions assigned to this role. + /// + /// + /// A guild permissions object representing the permissions that have been assigned to this role; null + /// if no permissions have been assigned. + /// + public GuildPermissions? Permissions { get; } + + /// + /// + /// if the value was not updated in this entry. + /// + public string IconId { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketRoleUpdateAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketRoleUpdateAuditLogData.cs new file mode 100644 index 00000000..e0845a12 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketRoleUpdateAuditLogData.cs @@ -0,0 +1,51 @@ +using Discord.Rest; + +using EntryModel = Discord.API.AuditLogEntry; +using Model = Discord.API.AuditLogs.RoleInfoAuditLogModel; + + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to a role update. +/// +public class SocketRoleUpdateAuditLogData : ISocketAuditLogData +{ + private SocketRoleUpdateAuditLogData(ulong id, SocketRoleEditInfo oldProps, SocketRoleEditInfo newProps) + { + RoleId = id; + Before = oldProps; + After = newProps; + } + + internal static SocketRoleUpdateAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var changes = entry.Changes; + + var (before, after) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new SocketRoleUpdateAuditLogData(entry.TargetId!.Value, new(before), new(after)); + } + + /// + /// Gets the ID of the role that was changed. + /// + /// + /// A representing the snowflake identifier of the role that was changed. + /// + public ulong RoleId { get; } + /// + /// Gets the role information before the changes. + /// + /// + /// A role information object containing the role information before the changes were made. + /// + public SocketRoleEditInfo Before { get; } + /// + /// Gets the role information after the changes. + /// + /// + /// A role information object containing the role information after the changes were made. + /// + public SocketRoleEditInfo After { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketScheduledEventCreateAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketScheduledEventCreateAuditLogData.cs new file mode 100644 index 00000000..8530c2fb --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketScheduledEventCreateAuditLogData.cs @@ -0,0 +1,88 @@ +using Discord.API.AuditLogs; +using Discord.Rest; +using System; +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to a scheduled event creation. +/// +public class SocketScheduledEventCreateAuditLogData : ISocketAuditLogData +{ + private SocketScheduledEventCreateAuditLogData(ulong id, ScheduledEventInfoAuditLogModel model) + { + Id = id; + ChannelId = model.ChannelId; + Name = model.Name; + Description = model.Description; + ScheduledStartTime = model.StartTime; + ScheduledEndTime = model.EndTime; + PrivacyLevel = model.PrivacyLevel!.Value; + Status = model.EventStatus!.Value; + EntityType = model.EventType!.Value; + EntityId = model.EntityId; + Location = model.Location; + Image = model.Image; + } + + internal static SocketScheduledEventCreateAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var changes = entry.Changes; + + var (_, data) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new SocketScheduledEventCreateAuditLogData(entry.TargetId!.Value, data); + } + + // Doc Note: Corresponds to the *current* data + + /// + /// Gets the snowflake id of the event. + /// + public ulong Id { get; } + /// + /// Gets the snowflake id of the channel the event is associated with. + /// + public ulong? ChannelId { get; } + /// + /// Gets name of the event. + /// + public string Name { get; } + /// + /// Gets the description of the event. null if none is set. + /// + public string Description { get; } + /// + /// Gets the time the event was scheduled for. + /// + public DateTimeOffset? ScheduledStartTime { get; } + /// + /// Gets the time the event was scheduled to end. + /// + public DateTimeOffset? ScheduledEndTime { get; } + /// + /// Gets the privacy level of the event. + /// + public GuildScheduledEventPrivacyLevel PrivacyLevel { get; } + /// + /// Gets the status of the event. + /// + public GuildScheduledEventStatus Status { get; } + /// + /// Gets the type of the entity associated with the event (stage / void / external). + /// + public GuildScheduledEventType EntityType { get; } + /// + /// Gets the snowflake id of the entity associated with the event (stage / void / external). + /// + public ulong? EntityId { get; } + /// + /// Gets the metadata for the entity associated with the event. + /// + public string Location { get; } + /// + /// Gets the image hash of the image that was attached to the event. Null if not set. + /// + public string Image { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketScheduledEventDeleteAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketScheduledEventDeleteAuditLogData.cs new file mode 100644 index 00000000..cc9bffdd --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketScheduledEventDeleteAuditLogData.cs @@ -0,0 +1,97 @@ +using Discord.API.AuditLogs; +using Discord.Rest; +using System; +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to a scheduled event deletion. +/// +public class SocketScheduledEventDeleteAuditLogData : ISocketAuditLogData +{ + private SocketScheduledEventDeleteAuditLogData(ulong id, ScheduledEventInfoAuditLogModel model) + { + Id = id; + ChannelId = model.ChannelId; + Name = model.Name; + Description = model.Description; + ScheduledStartTime = model.StartTime; + ScheduledEndTime = model.EndTime; + PrivacyLevel = model.PrivacyLevel; + Status = model.EventStatus; + EntityType = model.EventType; + EntityId = model.EntityId; + Location = model.Location; + Image = model.Image; + } + + internal static SocketScheduledEventDeleteAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var changes = entry.Changes; + + var (data, _) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new SocketScheduledEventDeleteAuditLogData(entry.TargetId!.Value, data); + } + + /// + /// Gets the snowflake id of the event. + /// + public ulong Id { get; } + + /// + /// Gets the snowflake id of the channel the event is associated with. + /// + public ulong? ChannelId { get; } + + /// + /// Gets name of the event. + /// + public string Name { get; } + + /// + /// Gets the description of the event. null if none is set. + /// + public string Description { get; } + + /// + /// Gets the time the event was scheduled for. + /// + public DateTimeOffset? ScheduledStartTime { get; } + + /// + /// Gets the time the event was scheduled to end. + /// + public DateTimeOffset? ScheduledEndTime { get; } + + /// + /// Gets the privacy level of the event. + /// + public GuildScheduledEventPrivacyLevel? PrivacyLevel { get; } + + /// + /// Gets the status of the event. + /// + public GuildScheduledEventStatus? Status { get; } + + /// + /// Gets the type of the entity associated with the event (stage / void / external). + /// + public GuildScheduledEventType? EntityType { get; } + + /// + /// Gets the snowflake id of the entity associated with the event (stage / void / external). + /// + public ulong? EntityId { get; } + + /// + /// Gets the metadata for the entity associated with the event. + /// + public string Location { get; } + + /// + /// Gets the image hash of the image that was attached to the event. Null if not set. + /// + public string Image { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketScheduledEventInfo.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketScheduledEventInfo.cs new file mode 100644 index 00000000..16552689 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketScheduledEventInfo.cs @@ -0,0 +1,80 @@ +using Discord.API.AuditLogs; +using System; + +namespace Discord.WebSocket; + +/// +/// Represents information for a scheduled event. +/// +public class SocketScheduledEventInfo +{ + /// + /// Gets the snowflake id of the channel the event is associated with. + /// + public ulong? ChannelId { get; } + + /// + /// Gets name of the event. + /// + public string Name { get; } + + /// + /// Gets the description of the event. null if none is set. + /// + public string Description { get; } + + /// + /// Gets the time the event was scheduled for. + /// + public DateTimeOffset? ScheduledStartTime { get; } + + /// + /// Gets the time the event was scheduled to end. + /// + public DateTimeOffset? ScheduledEndTime { get; } + + /// + /// Gets the privacy level of the event. + /// + public GuildScheduledEventPrivacyLevel? PrivacyLevel { get; } + + /// + /// Gets the status of the event. + /// + public GuildScheduledEventStatus? Status { get; } + + /// + /// Gets the type of the entity associated with the event (stage / void / external). + /// + public GuildScheduledEventType? EntityType { get; } + + /// + /// Gets the snowflake id of the entity associated with the event (stage / void / external). + /// + public ulong? EntityId { get; } + + /// + /// Gets the metadata for the entity associated with the event. + /// + public string Location { get; } + + /// + /// Gets the image hash of the image that was attached to the event. Null if not set. + /// + public string Image { get; } + + internal SocketScheduledEventInfo(ScheduledEventInfoAuditLogModel model) + { + ChannelId = model.ChannelId; + Name = model.Name; + Description = model.Description; + ScheduledStartTime = model.StartTime; + ScheduledEndTime = model.EndTime; + PrivacyLevel = model.PrivacyLevel; + Status = model.EventStatus; + EntityType = model.EventType; + EntityId = model.EntityId; + Location = model.Location; + Image = model.Image; + } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketScheduledEventUpdateAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketScheduledEventUpdateAuditLogData.cs new file mode 100644 index 00000000..c1bbb070 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketScheduledEventUpdateAuditLogData.cs @@ -0,0 +1,44 @@ +using Discord.API.AuditLogs; +using Discord.Rest; +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to a scheduled event updates. +/// +public class SocketScheduledEventUpdateAuditLogData : ISocketAuditLogData +{ + private SocketScheduledEventUpdateAuditLogData(ulong id, SocketScheduledEventInfo before, SocketScheduledEventInfo after) + { + Id = id; + Before = before; + After = after; + } + + internal static SocketScheduledEventUpdateAuditLogData Create(BaseDiscordClient discord, EntryModel entry) + { + var changes = entry.Changes; + + var (before, after) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new SocketScheduledEventUpdateAuditLogData(entry.TargetId!.Value, new(before), new(after)); + } + + // Doc Note: Corresponds to the *current* data + + /// + /// Gets the snowflake id of the event. + /// + public ulong Id { get; } + + /// + /// Gets the state before the change. + /// + public SocketScheduledEventInfo Before { get; } + + /// + /// Gets the state after the change. + /// + public SocketScheduledEventInfo After { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketStageInfo.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketStageInfo.cs new file mode 100644 index 00000000..e6af05be --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketStageInfo.cs @@ -0,0 +1,23 @@ +namespace Discord.WebSocket; + +/// +/// Represents information for a stage. +/// +public class SocketStageInfo +{ + /// + /// Gets the topic of the stage channel. + /// + public string Topic { get; } + + /// + /// Gets the privacy level of the stage channel. + /// + public StagePrivacyLevel? PrivacyLevel { get; } + + internal SocketStageInfo(StagePrivacyLevel? level, string topic) + { + Topic = topic; + PrivacyLevel = level; + } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketStageInstanceCreateAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketStageInstanceCreateAuditLogData.cs new file mode 100644 index 00000000..c4ff73d9 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketStageInstanceCreateAuditLogData.cs @@ -0,0 +1,41 @@ +using System.Linq; +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to a stage going live. +/// +public class SocketStageInstanceCreateAuditLogData : ISocketAuditLogData +{ + /// + /// Gets the topic of the stage channel. + /// + public string Topic { get; } + + /// + /// Gets the privacy level of the stage channel. + /// + public StagePrivacyLevel PrivacyLevel { get; } + + /// + /// Gets the Id of the stage channel. + /// + public ulong StageChannelId { get; } + + internal SocketStageInstanceCreateAuditLogData(string topic, StagePrivacyLevel privacyLevel, ulong channelId) + { + Topic = topic; + PrivacyLevel = privacyLevel; + StageChannelId = channelId; + } + + internal static SocketStageInstanceCreateAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var topic = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "topic").NewValue.ToObject(discord.ApiClient.Serializer); + var privacyLevel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "privacy_level").NewValue.ToObject(discord.ApiClient.Serializer); + var channelId = entry.Options.ChannelId; + + return new SocketStageInstanceCreateAuditLogData(topic, privacyLevel, channelId ?? 0); + } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketStageInstanceDeleteAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketStageInstanceDeleteAuditLogData.cs new file mode 100644 index 00000000..5ff40dbc --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketStageInstanceDeleteAuditLogData.cs @@ -0,0 +1,41 @@ +using System.Linq; +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to a stage instance deleted. +/// +public class SocketStageInstanceDeleteAuditLogData : ISocketAuditLogData +{ + /// + /// Gets the topic of the stage channel. + /// + public string Topic { get; } + + /// + /// Gets the privacy level of the stage channel. + /// + public StagePrivacyLevel PrivacyLevel { get; } + + /// + /// Gets the Id of the stage channel. + /// + public ulong StageChannelId { get; } + + internal SocketStageInstanceDeleteAuditLogData(string topic, StagePrivacyLevel privacyLevel, ulong channelId) + { + Topic = topic; + PrivacyLevel = privacyLevel; + StageChannelId = channelId; + } + + internal static SocketStageInstanceDeleteAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var topic = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "topic").OldValue.ToObject(discord.ApiClient.Serializer); + var privacyLevel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "privacy_level").OldValue.ToObject(discord.ApiClient.Serializer); + var channelId = entry.Options.ChannelId; + + return new SocketStageInstanceDeleteAuditLogData(topic, privacyLevel, channelId ?? 0); + } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketStageInstanceUpdatedAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketStageInstanceUpdatedAuditLogData.cs new file mode 100644 index 00000000..20e5d5ef --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketStageInstanceUpdatedAuditLogData.cs @@ -0,0 +1,47 @@ +using System.Linq; +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to a stage instance update. +/// +public class SocketStageInstanceUpdatedAuditLogData : ISocketAuditLogData +{ + /// + /// Gets the Id of the stage channel. + /// + public ulong StageChannelId { get; } + + /// + /// Gets the stage information before the changes. + /// + public SocketStageInfo Before { get; } + + /// + /// Gets the stage information after the changes. + /// + public SocketStageInfo After { get; } + + internal SocketStageInstanceUpdatedAuditLogData(ulong channelId, SocketStageInfo before, SocketStageInfo after) + { + StageChannelId = channelId; + Before = before; + After = after; + } + + internal static SocketStageInstanceUpdatedAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var channelId = entry.Options.ChannelId.Value; + + var topic = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "topic"); + var privacy = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "privacy"); + + var oldTopic = topic?.OldValue.ToObject(); + var newTopic = topic?.NewValue.ToObject(); + var oldPrivacy = privacy?.OldValue.ToObject(); + var newPrivacy = privacy?.NewValue.ToObject(); + + return new SocketStageInstanceUpdatedAuditLogData(channelId, new SocketStageInfo(oldPrivacy, oldTopic), new SocketStageInfo(newPrivacy, newTopic)); + } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketStickerCreatedAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketStickerCreatedAuditLogData.cs new file mode 100644 index 00000000..14048b4e --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketStickerCreatedAuditLogData.cs @@ -0,0 +1,29 @@ +using Discord.API.AuditLogs; +using Discord.Rest; +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to a sticker creation. +/// +public class SocketStickerCreatedAuditLogData : ISocketAuditLogData +{ + internal SocketStickerCreatedAuditLogData(SocketStickerInfo data) + { + Data = data; + } + + internal static SocketStickerCreatedAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var changes = entry.Changes; + var (_, data) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new SocketStickerCreatedAuditLogData(new(data)); + } + + /// + /// Gets the sticker information after the changes. + /// + public SocketStickerInfo Data { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketStickerDeletedAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketStickerDeletedAuditLogData.cs new file mode 100644 index 00000000..191b72af --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketStickerDeletedAuditLogData.cs @@ -0,0 +1,29 @@ +using Discord.API.AuditLogs; +using Discord.Rest; +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to a sticker removal. +/// +public class SocketStickerDeletedAuditLogData : ISocketAuditLogData +{ + internal SocketStickerDeletedAuditLogData(SocketStickerInfo data) + { + Data = data; + } + + internal static SocketStickerDeletedAuditLogData Create(BaseDiscordClient discord, EntryModel entry) + { + var changes = entry.Changes; + var (data, _) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new SocketStickerDeletedAuditLogData(new(data)); + } + + /// + /// Gets the sticker information before the changes. + /// + public SocketStickerInfo Data { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketStickerInfo.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketStickerInfo.cs new file mode 100644 index 00000000..e2a44b51 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketStickerInfo.cs @@ -0,0 +1,31 @@ +using Discord.API.AuditLogs; + +namespace Discord.WebSocket; + +/// +/// Represents information for a guild. +/// +public class SocketStickerInfo +{ + internal SocketStickerInfo(StickerInfoAuditLogModel model) + { + Name = model.Name; + Tags = model.Tags; + Description = model.Description; + } + + /// + /// Gets the name of the sticker. if the value was not updated in this entry. + /// + public string Name { get; set; } + + /// + /// Gets tags of the sticker. if the value was not updated in this entry. + /// + public string Tags { get; set; } + + /// + /// Gets the description of the sticker. if the value was not updated in this entry. + /// + public string Description { get; set; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketStickerUpdatedAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketStickerUpdatedAuditLogData.cs new file mode 100644 index 00000000..682e7e67 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketStickerUpdatedAuditLogData.cs @@ -0,0 +1,35 @@ +using Discord.API.AuditLogs; +using Discord.Rest; +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to a sticker update. +/// +public class SocketStickerUpdatedAuditLogData : ISocketAuditLogData +{ + internal SocketStickerUpdatedAuditLogData(SocketStickerInfo before, SocketStickerInfo after) + { + Before = before; + After = after; + } + + internal static SocketStickerUpdatedAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var changes = entry.Changes; + var (before, after) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new SocketStickerUpdatedAuditLogData(new(before), new (after)); + } + + /// + /// Gets the sticker information before the changes. + /// + public SocketStickerInfo Before { get; } + + /// + /// Gets the sticker information after the changes. + /// + public SocketStickerInfo After { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketThreadCreateAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketThreadCreateAuditLogData.cs new file mode 100644 index 00000000..3ecff7cf --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketThreadCreateAuditLogData.cs @@ -0,0 +1,109 @@ +using Discord.API.AuditLogs; +using Discord.Rest; +using System.Collections.Generic; +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to a thread creation. +/// +public class SocketThreadCreateAuditLogData : ISocketAuditLogData +{ + private SocketThreadCreateAuditLogData(ulong id, ThreadInfoAuditLogModel model) + { + ThreadId = id; + + ThreadName = model.Name; + IsArchived = model.IsArchived!.Value; + AutoArchiveDuration = model.ArchiveDuration!.Value; + IsLocked = model.IsLocked!.Value; + SlowModeInterval = model.SlowModeInterval; + AppliedTags = model.AppliedTags; + Flags = model.ChannelFlags; + ThreadType = model.Type; + } + + internal static SocketThreadCreateAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var changes = entry.Changes; + + var (_, data) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new SocketThreadCreateAuditLogData(entry.TargetId!.Value, data); + } + + /// + /// Gets the snowflake ID of the thread. + /// + /// + /// A representing the snowflake identifier for the thread. + /// + public ulong ThreadId { get; } + + /// + /// Gets the name of the thread. + /// + /// + /// A string containing the name of the thread. + /// + public string ThreadName { get; } + + /// + /// Gets the type of the thread. + /// + /// + /// The type of thread. + /// + public ThreadType ThreadType { get; } + + /// + /// Gets the value that indicates whether the thread is archived. + /// + /// + /// true if this thread has the Archived flag enabled; otherwise false. + /// + public bool IsArchived { get; } + + /// + /// Gets the auto archive duration of the thread. + /// + /// + /// The thread auto archive duration of the thread. + /// + public ThreadArchiveDuration AutoArchiveDuration { get; } + + /// + /// Gets the value that indicates whether the thread is locked. + /// + /// + /// true if this thread has the Locked flag enabled; otherwise false. + /// + public bool IsLocked { get; } + + /// + /// Gets the slow-mode delay of the thread. + /// + /// + /// An representing the time in seconds required before the user can send another + /// message; 0 if disabled. + /// null if this is not mentioned in this entry. + /// + public int? SlowModeInterval { get; } + + /// + /// Gets the applied tags of this thread. + /// + /// + /// if the property was not updated. + /// + public IReadOnlyCollection AppliedTags { get; } + + /// + /// Gets the flags of the thread channel. + /// + /// + /// if the property was not updated. + /// + public ChannelFlags? Flags { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketThreadDeleteAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketThreadDeleteAuditLogData.cs new file mode 100644 index 00000000..e6520beb --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketThreadDeleteAuditLogData.cs @@ -0,0 +1,111 @@ +using Discord.API.AuditLogs; +using Discord.Rest; +using System.Collections.Generic; +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to a thread deletion. +/// +public class SocketThreadDeleteAuditLogData : ISocketAuditLogData +{ + private SocketThreadDeleteAuditLogData(ulong id, ThreadInfoAuditLogModel model) + { + ThreadId = id; + + ThreadName = model.Name; + IsArchived = model.IsArchived!.Value; + AutoArchiveDuration = model.ArchiveDuration!.Value; + IsLocked = model.IsLocked!.Value; + SlowModeInterval = model.SlowModeInterval; + AppliedTags = model.AppliedTags; + Flags = model.ChannelFlags; + ThreadType = model.Type; + } + + internal static SocketThreadDeleteAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var changes = entry.Changes; + + var (data, _) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new SocketThreadDeleteAuditLogData(entry.TargetId!.Value, data); + } + + /// + /// Gets the snowflake ID of the deleted thread. + /// + /// + /// A representing the snowflake identifier for the deleted thread. + /// + /// + public ulong ThreadId { get; } + + /// + /// Gets the name of the deleted thread. + /// + /// + /// A string containing the name of the deleted thread. + /// + /// + public string ThreadName { get; } + + /// + /// Gets the type of the deleted thread. + /// + /// + /// The type of thread that was deleted. + /// + public ThreadType ThreadType { get; } + + /// + /// Gets the value that indicates whether the deleted thread was archived. + /// + /// + /// true if this thread had the Archived flag enabled; otherwise false. + /// + public bool IsArchived { get; } + + /// + /// Gets the thread auto archive duration of the deleted thread. + /// + /// + /// The thread auto archive duration of the thread that was deleted. + /// + public ThreadArchiveDuration AutoArchiveDuration { get; } + + /// + /// Gets the value that indicates whether the deleted thread was locked. + /// + /// + /// true if this thread had the Locked flag enabled; otherwise false. + /// + public bool IsLocked { get; } + + /// + /// Gets the slow-mode delay of the deleted thread. + /// + /// + /// An representing the time in seconds required before the user can send another + /// message; 0 if disabled. + /// null if this is not mentioned in this entry. + /// + public int? SlowModeInterval { get; } + + /// + /// Gets the applied tags of this thread. + /// + /// + /// if this is not mentioned in this entry. + /// + public IReadOnlyCollection AppliedTags { get; } + + /// + /// Gets the flags of the thread channel. + /// + /// + /// if this is not mentioned in this entry. + /// + public ChannelFlags? Flags { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketThreadInfo.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketThreadInfo.cs new file mode 100644 index 00000000..e202df39 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketThreadInfo.cs @@ -0,0 +1,83 @@ +using Discord.API.AuditLogs; +using System.Collections.Generic; + +namespace Discord.WebSocket; + +/// +/// Represents information for a thread. +/// +public class SocketThreadInfo +{ + /// + /// Gets the name of the thread. + /// + public string Name { get; } + + /// + /// Gets the value that indicates whether the thread is archived. + /// + /// + /// if the property was not updated. + /// + public bool? IsArchived { get; } + + /// + /// Gets the auto archive duration of thread. + /// + /// + /// if the property was not updated. + /// + public ThreadArchiveDuration? AutoArchiveDuration { get; } + + /// + /// Gets the value that indicates whether the thread is locked. + /// + /// + /// if the property was not updated. + /// + public bool? IsLocked { get; } + + /// + /// Gets the slow-mode delay of the thread. + /// + /// + /// if the property was not updated. + /// + public int? SlowModeInterval { get; } + + /// + /// Gets the applied tags of this thread. + /// + /// + /// if the property was not updated. + /// + public IReadOnlyCollection AppliedTags { get; } + + /// + /// Gets the flags of the thread channel. + /// + /// + /// if the property was not updated. + /// + public ChannelFlags? Flags { get; } + + /// + /// Gets the type of the thread. + /// + /// + /// if the property was not updated. + /// + public ThreadType Type { get; } + + internal SocketThreadInfo(ThreadInfoAuditLogModel model) + { + Name = model.Name; + IsArchived = model.IsArchived; + AutoArchiveDuration = model.ArchiveDuration; + IsLocked = model.IsLocked; + SlowModeInterval = model.SlowModeInterval; + AppliedTags = model.AppliedTags; + Flags = model.ChannelFlags; + Type = model.Type; + } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketThreadUpdateAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketThreadUpdateAuditLogData.cs new file mode 100644 index 00000000..5b5583b7 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketThreadUpdateAuditLogData.cs @@ -0,0 +1,51 @@ +using Discord.API.AuditLogs; +using Discord.Rest; +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to a thread update. +/// +public class SocketThreadUpdateAuditLogData : ISocketAuditLogData +{ + private SocketThreadUpdateAuditLogData(ThreadType type, ThreadInfo before, ThreadInfo after) + { + ThreadType = type; + Before = before; + After = after; + } + + internal static SocketThreadUpdateAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var changes = entry.Changes; + + var (before, after) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new SocketThreadUpdateAuditLogData(before.Type, new(before), new (after)); + } + + /// + /// Gets the type of the thread. + /// + /// + /// The type of thread. + /// + public ThreadType ThreadType { get; } + + /// + /// Gets the thread information before the changes. + /// + /// + /// A thread information object representing the thread before the changes were made. + /// + public ThreadInfo Before { get; } + + /// + /// Gets the thread information after the changes. + /// + /// + /// A thread information object representing the thread after the changes were made. + /// + public ThreadInfo After { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketUnbanAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketUnbanAuditLogData.cs new file mode 100644 index 00000000..c86845da --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketUnbanAuditLogData.cs @@ -0,0 +1,39 @@ +using Discord.Rest; +using System.Linq; +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to an unban. +/// +public class SocketUnbanAuditLogData : ISocketAuditLogData +{ + private SocketUnbanAuditLogData(Cacheable user) + { + Target = user; + } + + internal static SocketUnbanAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var cachedUser = discord.GetUser(entry.TargetId!.Value); + var cacheableUser = new Cacheable( + cachedUser, + entry.TargetId.Value, + cachedUser is not null, + async () => + { + var user = await discord.ApiClient.GetUserAsync(entry.TargetId.Value); + return user is not null ? RestUser.Create(discord, user) : null; + }); + return new SocketUnbanAuditLogData(cacheableUser); + } + + /// + /// Gets the user that was unbanned. + /// + /// + /// A cacheable user object representing the user that was unbanned. + /// + public Cacheable Target { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketWebhookCreateAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketWebhookCreateAuditLogData.cs new file mode 100644 index 00000000..3e4c5f8a --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketWebhookCreateAuditLogData.cs @@ -0,0 +1,71 @@ +using Discord.Rest; + +using EntryModel = Discord.API.AuditLogEntry; +using Model = Discord.API.AuditLogs.WebhookInfoAuditLogModel; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to a webhook creation. +/// +public class SocketWebhookCreateAuditLogData : ISocketAuditLogData +{ + private SocketWebhookCreateAuditLogData(ulong webhookId, Model model) + { + WebhookId = webhookId; + Name = model.Name; + Type = model.Type!.Value; + ChannelId = model.ChannelId!.Value; + Avatar = model.AvatarHash; + } + + internal static SocketWebhookCreateAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var changes = entry.Changes; + + var (_, data) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new SocketWebhookCreateAuditLogData(entry.TargetId!.Value, data); + } + + /// + /// Gets the webhook id. + /// + /// + /// The webhook identifier. + /// + public ulong WebhookId { get; } + + /// + /// Gets the type of webhook that was created. + /// + /// + /// The type of webhook that was created. + /// + public WebhookType Type { get; } + + /// + /// Gets the name of the webhook. + /// + /// + /// A string containing the name of the webhook. + /// + public string Name { get; } + + /// + /// Gets the ID of the channel that the webhook could send to. + /// + /// + /// A representing the snowflake identifier of the channel that the webhook could send + /// to. + /// + public ulong ChannelId { get; } + + /// + /// Gets the hash value of the webhook's avatar. + /// + /// + /// A string containing the hash of the webhook's avatar. + /// + public string Avatar { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketWebhookDeleteAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketWebhookDeleteAuditLogData.cs new file mode 100644 index 00000000..d168398d --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketWebhookDeleteAuditLogData.cs @@ -0,0 +1,71 @@ +using Discord.Rest; + +using Model = Discord.API.AuditLogs.WebhookInfoAuditLogModel; +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to a webhook deletion. +/// +public class SocketWebhookDeleteAuditLogData : ISocketAuditLogData +{ + private SocketWebhookDeleteAuditLogData(ulong id, Model model) + { + WebhookId = id; + ChannelId = model.ChannelId!.Value; + Name = model.Name; + Type = model.Type!.Value; + Avatar = model.AvatarHash; + } + + internal static SocketWebhookDeleteAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var changes = entry.Changes; + + var (data, _) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new SocketWebhookDeleteAuditLogData(entry.TargetId!.Value,data); + } + + /// + /// Gets the ID of the webhook that was deleted. + /// + /// + /// A representing the snowflake identifier of the webhook that was deleted. + /// + public ulong WebhookId { get; } + + /// + /// Gets the ID of the channel that the webhook could send to. + /// + /// + /// A representing the snowflake identifier of the channel that the webhook could send + /// to. + /// + public ulong ChannelId { get; } + + /// + /// Gets the type of the webhook that was deleted. + /// + /// + /// The type of webhook that was deleted. + /// + public WebhookType Type { get; } + + /// + /// Gets the name of the webhook that was deleted. + /// + /// + /// A string containing the name of the webhook that was deleted. + /// + public string Name { get; } + + /// + /// Gets the hash value of the webhook's avatar. + /// + /// + /// A string containing the hash of the webhook's avatar. + /// + public string Avatar { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketWebhookInfo.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketWebhookInfo.cs new file mode 100644 index 00000000..1b001483 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketWebhookInfo.cs @@ -0,0 +1,39 @@ +using Model = Discord.API.AuditLogs.WebhookInfoAuditLogModel; + +namespace Discord.WebSocket; + +/// +/// Represents information for a webhook. +/// +public struct SocketWebhookInfo +{ + internal SocketWebhookInfo(Model model) + { + Name = model.Name; + ChannelId = model.ChannelId; + Avatar = model.AvatarHash; + } + + /// + /// Gets the name of this webhook. + /// + /// + /// A string containing the name of this webhook. + /// + public string Name { get; } + /// + /// Gets the ID of the channel that this webhook sends to. + /// + /// + /// A representing the snowflake identifier of the channel that this webhook can send + /// to. + /// + public ulong? ChannelId { get; } + /// + /// Gets the hash value of this webhook's avatar. + /// + /// + /// A string containing the hash of this webhook's avatar. + /// + public string Avatar { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketWebhookUpdateAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketWebhookUpdateAuditLogData.cs new file mode 100644 index 00000000..4bcba25d --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/DataTypes/SocketWebhookUpdateAuditLogData.cs @@ -0,0 +1,44 @@ +using Discord.Rest; + +using EntryModel = Discord.API.AuditLogEntry; +using Model = Discord.API.AuditLogs.WebhookInfoAuditLogModel; + + +namespace Discord.WebSocket; + +/// +/// Contains a piece of audit log data related to a webhook update. +/// +public class SocketWebhookUpdateAuditLogData : ISocketAuditLogData +{ + private SocketWebhookUpdateAuditLogData(SocketWebhookInfo before, SocketWebhookInfo after) + { + Before = before; + After = after; + } + + internal static SocketWebhookUpdateAuditLogData Create(DiscordSocketClient discord, EntryModel entry) + { + var changes = entry.Changes; + + var (before, after) = AuditLogHelper.CreateAuditLogEntityInfo(changes, discord); + + return new SocketWebhookUpdateAuditLogData(new(before), new(after)); + } + + /// + /// Gets the webhook information before the changes. + /// + /// + /// A webhook information object representing the webhook before the changes were made. + /// + public SocketWebhookInfo Before { get; } + + /// + /// Gets the webhook information after the changes. + /// + /// + /// A webhook information object representing the webhook after the changes were made. + /// + public SocketWebhookInfo After { get; } +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/ISocketAuditLogData.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/ISocketAuditLogData.cs new file mode 100644 index 00000000..4703fbb4 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/ISocketAuditLogData.cs @@ -0,0 +1,9 @@ +namespace Discord.WebSocket; + +/// +/// Represents data applied to a . +/// +public interface ISocketAuditLogData : IAuditLogData +{ + +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/SocketAuditLogEntry.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/SocketAuditLogEntry.cs new file mode 100644 index 00000000..edb5be64 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/SocketAuditLogEntry.cs @@ -0,0 +1,55 @@ +using Discord.Rest; +using System; +using System.Linq; + +using Model = Discord.API.AuditLog; +using EntryModel = Discord.API.Gateway.AuditLogCreatedEvent; + +namespace Discord.WebSocket; + +/// +/// Represents a Socket-based audit log entry. +/// +public class SocketAuditLogEntry : SocketEntity, IAuditLogEntry +{ + private SocketAuditLogEntry(DiscordSocketClient discord, EntryModel model) + : base(discord, model.Id) + { + Action = model.Action; + Data = SocketAuditLogHelper.CreateData(discord, model); + Reason = model.Reason; + + var guild = discord.State.GetGuild(model.GuildId); + User = guild?.GetUser(model.UserId ?? 0); + } + + internal static SocketAuditLogEntry Create(DiscordSocketClient discord, EntryModel model) + { + return new SocketAuditLogEntry(discord, model); + } + + /// + public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id); + + /// + public ActionType Action { get; } + + /// + public ISocketAuditLogData Data { get; } + + /// + public SocketUser User { get; private set; } + + /// + public string Reason { get; } + + #region IAuditLogEntry + + /// + IUser IAuditLogEntry.User => User; + + /// + IAuditLogData IAuditLogEntry.Data => Data; + + #endregion +} diff --git a/src/Discord.Net.WebSocket/Entities/AuditLogs/SocketAuditLogHelper.cs b/src/Discord.Net.WebSocket/Entities/AuditLogs/SocketAuditLogHelper.cs new file mode 100644 index 00000000..e90c1cf0 --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/AuditLogs/SocketAuditLogHelper.cs @@ -0,0 +1,96 @@ +using System; +using System.Collections.Generic; + +using EntryModel = Discord.API.AuditLogEntry; + +namespace Discord.WebSocket; + +internal static class SocketAuditLogHelper +{ + private static readonly Dictionary> CreateMapping + = new () + { + [ActionType.GuildUpdated] = SocketGuildUpdateAuditLogData.Create, + + [ActionType.ChannelCreated] = SocketChannelCreateAuditLogData.Create, + [ActionType.ChannelUpdated] = SocketChannelUpdateAuditLogData.Create, + [ActionType.ChannelDeleted] = SocketChannelDeleteAuditLogData.Create, + + [ActionType.OverwriteCreated] = SocketOverwriteCreateAuditLogData.Create, + [ActionType.OverwriteUpdated] = SocketOverwriteUpdateAuditLogData.Create, + [ActionType.OverwriteDeleted] = SocketOverwriteDeleteAuditLogData.Create, + + [ActionType.Kick] = SocketKickAuditLogData.Create, + [ActionType.Prune] = SocketPruneAuditLogData.Create, + [ActionType.Ban] = SocketBanAuditLogData.Create, + [ActionType.Unban] = SocketUnbanAuditLogData.Create, + [ActionType.MemberUpdated] = SocketMemberUpdateAuditLogData.Create, + [ActionType.MemberRoleUpdated] = SocketMemberRoleAuditLogData.Create, + [ActionType.MemberMoved] = SocketMemberMoveAuditLogData.Create, + [ActionType.MemberDisconnected] = SocketMemberDisconnectAuditLogData.Create, + [ActionType.BotAdded] = SocketBotAddAuditLogData.Create, + + [ActionType.RoleCreated] = SocketRoleCreateAuditLogData.Create, + [ActionType.RoleUpdated] = SocketRoleUpdateAuditLogData.Create, + [ActionType.RoleDeleted] = SocketRoleDeleteAuditLogData.Create, + + [ActionType.InviteCreated] = SocketInviteCreateAuditLogData.Create, + [ActionType.InviteUpdated] = SocketInviteUpdateAuditLogData.Create, + [ActionType.InviteDeleted] = SocketInviteDeleteAuditLogData.Create, + + [ActionType.WebhookCreated] = SocketWebhookCreateAuditLogData.Create, + [ActionType.WebhookUpdated] = SocketWebhookUpdateAuditLogData.Create, + [ActionType.WebhookDeleted] = SocketWebhookDeleteAuditLogData.Create, + + [ActionType.EmojiCreated] = SocketEmoteCreateAuditLogData.Create, + [ActionType.EmojiUpdated] = SocketEmoteUpdateAuditLogData.Create, + [ActionType.EmojiDeleted] = SocketEmoteDeleteAuditLogData.Create, + + [ActionType.MessageDeleted] = SocketMessageDeleteAuditLogData.Create, + [ActionType.MessageBulkDeleted] = SocketMessageBulkDeleteAuditLogData.Create, + [ActionType.MessagePinned] = SocketMessagePinAuditLogData.Create, + [ActionType.MessageUnpinned] = SocketMessageUnpinAuditLogData.Create, + + [ActionType.EventCreate] = SocketScheduledEventCreateAuditLogData.Create, + [ActionType.EventUpdate] = SocketScheduledEventUpdateAuditLogData.Create, + [ActionType.EventDelete] = SocketScheduledEventDeleteAuditLogData.Create, + + [ActionType.ThreadCreate] = SocketThreadCreateAuditLogData.Create, + [ActionType.ThreadUpdate] = SocketThreadUpdateAuditLogData.Create, + [ActionType.ThreadDelete] = SocketThreadDeleteAuditLogData.Create, + + [ActionType.ApplicationCommandPermissionUpdate] = SocketCommandPermissionUpdateAuditLogData.Create, + + [ActionType.IntegrationCreated] = SocketIntegrationCreatedAuditLogData.Create, + [ActionType.IntegrationUpdated] = SocketIntegrationUpdatedAuditLogData.Create, + [ActionType.IntegrationDeleted] = SocketIntegrationDeletedAuditLogData.Create, + + [ActionType.StageInstanceCreated] = SocketStageInstanceCreateAuditLogData.Create, + [ActionType.StageInstanceUpdated] = SocketStageInstanceUpdatedAuditLogData.Create, + [ActionType.StageInstanceDeleted] = SocketStageInstanceDeleteAuditLogData.Create, + + [ActionType.StickerCreated] = SocketStickerCreatedAuditLogData.Create, + [ActionType.StickerUpdated] = SocketStickerUpdatedAuditLogData.Create, + [ActionType.StickerDeleted] = SocketStickerDeletedAuditLogData.Create, + + [ActionType.AutoModerationRuleCreate] = SocketAutoModRuleCreatedAuditLogData.Create, + [ActionType.AutoModerationRuleUpdate] = AutoModRuleUpdatedAuditLogData.Create, + [ActionType.AutoModerationRuleDelete] = SocketAutoModRuleDeletedAuditLogData.Create, + + [ActionType.AutoModerationBlockMessage] = SocketAutoModBlockedMessageAuditLogData.Create, + [ActionType.AutoModerationFlagToChannel] = SocketAutoModFlaggedMessageAuditLogData.Create, + [ActionType.AutoModerationUserCommunicationDisabled] = SocketAutoModTimeoutUserAuditLogData.Create, + + [ActionType.OnboardingQuestionCreated] = SocketOnboardingPromptCreatedAuditLogData.Create, + [ActionType.OnboardingQuestionUpdated] = SocketOnboardingPromptUpdatedAuditLogData.Create, + [ActionType.OnboardingUpdated] = SocketOnboardingUpdatedAuditLogData.Create, + }; + + public static ISocketAuditLogData CreateData(DiscordSocketClient discord, EntryModel entry) + { + if (CreateMapping.TryGetValue(entry.Action, out var func)) + return func(discord, entry); + + return null; + } +} diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketForumChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketForumChannel.cs index ddfe7634..73b817cb 100644 --- a/src/Discord.Net.WebSocket/Entities/Channels/SocketForumChannel.cs +++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketForumChannel.cs @@ -81,7 +81,7 @@ namespace Discord.WebSocket DefaultSortOrder = model.DefaultSortOrder.GetValueOrDefault(); - Tags = model.ForumTags.GetValueOrDefault(Array.Empty()).Select( + Tags = model.ForumTags.GetValueOrDefault(Array.Empty()).Select( x => new ForumTag(x.Id, x.Name, x.EmojiId.GetValueOrDefault(null), x.EmojiName.GetValueOrDefault(), x.Moderated) ).ToImmutableArray(); diff --git a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs index 297de2ed..9180ad92 100644 --- a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs +++ b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs @@ -49,6 +49,8 @@ namespace Discord.WebSocket private ConcurrentDictionary _automodRules; private ImmutableArray _emotes; + private readonly AuditLogCache _auditLogs; + private AudioClient _audioClient; private VoiceStateUpdateParams _voiceStateUpdateParams; #pragma warning restore IDISP002, IDISP006 @@ -415,6 +417,7 @@ namespace Discord.WebSocket _audioLock = new SemaphoreSlim(1, 1); _emotes = ImmutableArray.Create(); _automodRules = new ConcurrentDictionary(); + _auditLogs = new AuditLogCache(client); } internal static SocketGuild Create(DiscordSocketClient discord, ClientState state, ExtendedModel model) { @@ -1403,9 +1406,36 @@ namespace Discord.WebSocket /// /// A task that represents the asynchronous get operation. The task result contains a read-only collection /// of the requested audit log entries. - /// + /// public IAsyncEnumerable> GetAuditLogsAsync(int limit, RequestOptions options = null, ulong? beforeId = null, ulong? userId = null, ActionType? actionType = null, ulong? afterId = null) => GuildHelper.GetAuditLogsAsync(this, Discord, beforeId, limit, options, userId: userId, actionType: actionType, afterId: afterId); + + /// + /// Gets all cached audit log entries from this guild. + /// + public IReadOnlyCollection CachedAuditLogs => _auditLogs?.AuditLogs ?? ImmutableArray.Create(); + + /// + /// Gets cached audit log entry with the provided id. + /// + /// + /// Returns if no entry with provided id was found in cache. + /// + public SocketAuditLogEntry GetCachedAuditLog(ulong id) + => _auditLogs.Get(id); + + /// + /// Gets audit log entries with the specified type from cache. + /// + public IReadOnlyCollection GetCachedAuditLogs(int limit = DiscordConfig.MaxAuditLogEntriesPerBatch, ActionType? action = null, + ulong? fromEntryId = null, Direction direction = Direction.Before) + { + return _auditLogs.GetMany(fromEntryId, direction, limit, action); + } + + internal void AddAuditLog(SocketAuditLogEntry entry) + => _auditLogs.Add(entry); + #endregion #region Webhooks