diff --git a/DisCatSharp/Clients/DiscordClient.Dispatch.cs b/DisCatSharp/Clients/DiscordClient.Dispatch.cs index 8afd62434..df8823171 100644 --- a/DisCatSharp/Clients/DiscordClient.Dispatch.cs +++ b/DisCatSharp/Clients/DiscordClient.Dispatch.cs @@ -27,7 +27,7 @@ namespace DisCatSharp; /// public sealed partial class DiscordClient { - #region Private Fields +#region Private Fields private string _resumeGatewayUrl; private string _sessionId; @@ -76,9 +76,9 @@ internal TimeoutHandler(DiscordMember mbr, DiscordGuild guild, DateTime? too, Da } } - #endregion +#endregion - #region Dispatch Handler +#region Dispatch Handler /// /// Handles the dispatch payloads. @@ -98,7 +98,8 @@ internal async Task HandleDispatchAsync(GatewayPayload payload) PayloadObject = dat }).ConfigureAwait(false); */ - #region Default objects + +#region Default objects var payloadString = dat.ToString(); DiscordChannel chn; @@ -118,11 +119,12 @@ internal async Task HandleDispatchAsync(GatewayPayload payload) DiscordEntitlement ent = default; JToken rawMbr = default; var rawRefMsg = dat["referenced_message"]; // TODO: Can we remove this? - #endregion + +#endregion switch (payload.EventName.ToLowerInvariant()) { - #region Gateway Status +#region Gateway Status case "ready": var glds = (JArray)dat["guilds"]!; @@ -133,9 +135,9 @@ internal async Task HandleDispatchAsync(GatewayPayload payload) await this.OnResumedAsync().ConfigureAwait(false); break; - #endregion +#endregion - #region Channel +#region Channel case "channel_create": chn = DiscordJson.DeserializeObject(payloadString, this); @@ -168,9 +170,9 @@ internal async Task HandleDispatchAsync(GatewayPayload payload) // It's fired incorrectly. break; - #endregion +#endregion - #region Guild +#region Guild case "guild_create": await this.OnGuildCreateEventAsync(dat.ToDiscordObject(), (JArray)dat["members"]!, dat["presences"]!.ToDiscordObject>()).ConfigureAwait(false); @@ -216,9 +218,11 @@ internal async Task HandleDispatchAsync(GatewayPayload payload) await this.OnGuildIntegrationsUpdateEventAsync(this.GuildsInternal[gid]).ConfigureAwait(false); break; - #endregion - #region Guild Automod +#endregion + +#region Guild Automod + case "auto_moderation_rule_create": await this.OnAutomodRuleCreated(dat.ToDiscordObject()).ConfigureAwait(false); break; @@ -232,9 +236,10 @@ internal async Task HandleDispatchAsync(GatewayPayload payload) gid = (ulong)dat["guild_id"]!; await this.OnAutomodActionExecuted(this.GuildsInternal[gid], dat).ConfigureAwait(false); break; - #endregion - #region Guild Ban +#endregion + +#region Guild Ban case "guild_ban_add": usr = DiscordJson.DeserializeObject(dat["user"]!.ToString(), this); @@ -248,9 +253,9 @@ internal async Task HandleDispatchAsync(GatewayPayload payload) await this.OnGuildBanRemoveEventAsync(usr, this.GuildsInternal[gid]).ConfigureAwait(false); break; - #endregion +#endregion - #region Guild Event +#region Guild Event case "guild_scheduled_event_create": gse = DiscordJson.DeserializeObject(payloadString, this); @@ -282,9 +287,9 @@ internal async Task HandleDispatchAsync(GatewayPayload payload) await this.OnGuildScheduledEventUserRemovedEventAsync((ulong)dat["guild_scheduled_event_id"]!, uid, this.GuildsInternal[gid]).ConfigureAwait(false); break; - #endregion +#endregion - #region Guild Integration +#region Guild Integration case "integration_create": gid = (ulong)dat["guild_id"]!; @@ -317,9 +322,10 @@ internal async Task HandleDispatchAsync(GatewayPayload payload) await this.OnGuildIntegrationDeleteEventAsync(this.GuildsInternal[gid], (ulong)dat["id"], (ulong?)dat["application_id"]).ConfigureAwait(false); break; - #endregion - #region Guild Member +#endregion + +#region Guild Member case "guild_member_add": gid = (ulong)dat["guild_id"]!; @@ -350,9 +356,9 @@ internal async Task HandleDispatchAsync(GatewayPayload payload) await this.OnGuildMembersChunkEventAsync(dat).ConfigureAwait(false); break; - #endregion +#endregion - #region Guild Role +#region Guild Role case "guild_role_create": gid = (ulong)dat["guild_id"]!; @@ -369,9 +375,9 @@ internal async Task HandleDispatchAsync(GatewayPayload payload) await this.OnGuildRoleDeleteEventAsync((ulong)dat["role_id"]!, this.GuildsInternal[gid]).ConfigureAwait(false); break; - #endregion +#endregion - #region Invite +#region Invite case "invite_create": gid = (ulong)dat["guild_id"]!; @@ -385,9 +391,9 @@ internal async Task HandleDispatchAsync(GatewayPayload payload) await this.OnInviteDeleteEventAsync(cid, gid, dat).ConfigureAwait(false); break; - #endregion +#endregion - #region Message +#region Message case "message_ack": cid = (ulong)dat["channel_id"]!; @@ -407,8 +413,9 @@ internal async Task HandleDispatchAsync(GatewayPayload payload) refUsr = DiscordJson.DeserializeObject(rawRefMsg.SelectToken("author")!.ToString(), this); if (rawRefMsg.SelectToken("member") != null) - refMbr = DiscordJson.DeserializeObject(json: rawRefMsg.SelectToken("member")!.ToString(), this); + refMbr = DiscordJson.DeserializeObject(rawRefMsg.SelectToken("member")!.ToString(), this); } + await this.OnMessageCreateEventAsync(dat.ToDiscordObject(), dat["author"].ToObject(), mbr, refUsr, refMbr).ConfigureAwait(false); break; @@ -424,7 +431,7 @@ internal async Task HandleDispatchAsync(GatewayPayload payload) refUsr = DiscordJson.DeserializeObject(rawRefMsg.SelectToken("author")!.ToString(), this); if (rawRefMsg.SelectToken("member") != null) - refMbr = DiscordJson.DeserializeObject(json: rawRefMsg.SelectToken("member")!.ToString(), this); + refMbr = DiscordJson.DeserializeObject(rawRefMsg.SelectToken("member")!.ToString(), this); } await this.OnMessageUpdateEventAsync(DiscordJson.DeserializeObject(payloadString, this), dat["author"] != null ? DiscordJson.DeserializeObject(dat["author"]!.ToString(), this) : null, mbr!, refUsr!, refMbr!).ConfigureAwait(false); @@ -439,9 +446,9 @@ internal async Task HandleDispatchAsync(GatewayPayload payload) await this.OnMessageBulkDeleteEventAsync(dat["ids"]!.ToObject()!, (ulong)dat["channel_id"]!, (ulong?)dat["guild_id"]).ConfigureAwait(false); break; - #endregion +#endregion - #region Message Reaction +#region Message Reaction case "message_reaction_add": rawMbr = dat["member"]!; @@ -464,9 +471,9 @@ internal async Task HandleDispatchAsync(GatewayPayload payload) await this.OnMessageReactionRemoveEmojiAsync((ulong)dat["message_id"]!, (ulong)dat["channel_id"]!, (ulong)dat["guild_id"]!, DiscordJson.DeserializeObject(dat["emoji"]!.ToString(), this)).ConfigureAwait(false); break; - #endregion +#endregion - #region Stage Instance +#region Stage Instance case "stage_instance_create": stg = DiscordJson.DeserializeObject(payloadString, this); @@ -483,9 +490,9 @@ internal async Task HandleDispatchAsync(GatewayPayload payload) await this.OnStageInstanceDeleteEventAsync(stg).ConfigureAwait(false); break; - #endregion +#endregion - #region Thread +#region Thread case "thread_create": trd = DiscordJson.DeserializeObject(payloadString, this); @@ -520,17 +527,19 @@ internal async Task HandleDispatchAsync(GatewayPayload payload) await this.OnThreadMembersUpdateEventAsync(this.GuildsInternal[gid], (ulong)dat["id"]!, (JArray)dat["added_members"]!, (JArray)dat["removed_member_ids"]!, (int)dat["member_count"]!).ConfigureAwait(false); break; - #endregion +#endregion + +#region Activities - #region Activities case "embedded_activity_update": gid = (ulong)dat["guild_id"]!; cid = (ulong)dat["channel_id"]!; await this.OnEmbeddedActivityUpdateAsync((JObject)dat["embedded_activity"]!, this.GuildsInternal[gid], cid, (JArray)dat["users"]!, (ulong)dat["embedded_activity"]["application_id"]!).ConfigureAwait(false); break; - #endregion - #region User/Presence Update +#endregion + +#region User/Presence Update case "presence_update": await this.OnPresenceUpdateEventAsync(dat, (JObject)dat["user"]!).ConfigureAwait(false); @@ -546,9 +555,9 @@ internal async Task HandleDispatchAsync(GatewayPayload payload) await this.OnUserUpdateEventAsync(usr).ConfigureAwait(false); break; - #endregion +#endregion - #region Voice +#region Voice case "voice_state_update": await this.OnVoiceStateUpdateEventAsync(dat).ConfigureAwait(false); @@ -559,9 +568,9 @@ internal async Task HandleDispatchAsync(GatewayPayload payload) await this.OnVoiceServerUpdateEventAsync((string)dat["endpoint"]!, (string)dat["token"]!, this.GuildsInternal[gid]).ConfigureAwait(false); break; - #endregion +#endregion - #region Interaction/Integration/Application +#region Interaction/Integration/Application case "interaction_create": rawMbr = dat["member"]!; @@ -613,9 +622,9 @@ internal async Task HandleDispatchAsync(GatewayPayload payload) await this.OnApplicationCommandPermissionsUpdateAsync(pms, (ulong)dat["id"]!, gid, aid).ConfigureAwait(false); break; - #endregion +#endregion - #region Misc +#region Misc case "gift_code_update": //Not supposed to be dispatched to bots break; @@ -659,15 +668,15 @@ internal async Task HandleDispatchAsync(GatewayPayload payload) this.Logger.LogWarning(LoggerEvents.WebSocketReceive, "Unknown event: {name}\npayload: {payload}", payload.EventName, dat.ToString(Formatting.Indented)); break; - #endregion +#endregion } } - #endregion +#endregion - #region Events +#region Events - #region Gateway +#region Gateway /// /// Handles the ready event. @@ -723,12 +732,14 @@ internal async Task OnReadyEventAsync(ReadyPayload ready, JArray rawGuilds) guild.MembersInternal = new(); if (rawMembers != null) - { foreach (var xj in rawMembers) { var xtm = xj.ToObject(); - var xu = new DiscordUser(xtm.User) { Discord = this }; + var xu = new DiscordUser(xtm.User) + { + Discord = this + }; xu = this.UserCache.AddOrUpdate(xtm.User.Id, xu, (id, old) => { old.Username = xu.Username; @@ -738,9 +749,11 @@ internal async Task OnReadyEventAsync(ReadyPayload ready, JArray rawGuilds) return old; }); - guild.MembersInternal[xtm.User.Id] = new(xtm) { Discord = this, GuildId = guild.Id }; + guild.MembersInternal[xtm.User.Id] = new(xtm) + { + Discord = this, GuildId = guild.Id + }; } - } guild.EmojisInternal ??= new(); @@ -787,9 +800,9 @@ internal Task OnResumedAsync() return this._resumed.InvokeAsync(this, new(this.ServiceProvider)); } - #endregion +#endregion - #region Channel +#region Channel /// /// Handles the channel create event. @@ -806,7 +819,10 @@ internal async Task OnChannelCreateEventAsync(DiscordChannel channel) await this.RefreshChannelsAsync(channel.Guild.Id); }*/ - await this._channelCreated.InvokeAsync(this, new(this.ServiceProvider) { Channel = channel, Guild = channel.Guild }).ConfigureAwait(false); + await this._channelCreated.InvokeAsync(this, new(this.ServiceProvider) + { + Channel = channel, Guild = channel.Guild + }).ConfigureAwait(false); } /// @@ -845,7 +861,7 @@ internal async Task OnChannelUpdateEventAsync(DiscordChannel channel) PerUserRateLimit = channelNew.PerUserRateLimit, RtcRegionId = channelNew.RtcRegionId, QualityMode = channelNew.QualityMode, - DefaultAutoArchiveDuration = channelNew.DefaultAutoArchiveDuration, + DefaultAutoArchiveDuration = channelNew.DefaultAutoArchiveDuration }; channelNew.Bitrate = channel.Bitrate; @@ -867,7 +883,6 @@ internal async Task OnChannelUpdateEventAsync(DiscordChannel channel) channelNew.PermissionOverwritesInternal.AddRange(channel.PermissionOverwritesInternal); - if (channel.Type == ChannelType.Forum) { channelOld.PostCreateUserRateLimit = channelNew.PostCreateUserRateLimit; @@ -901,25 +916,25 @@ internal async Task OnChannelUpdateEventAsync(DiscordChannel channel) channelNew.DefaultReactionEmoji = null; channelNew.DefaultSortOrder = null; } + channelOld.Initialize(this); channelNew.Initialize(this); if (this.Configuration.AutoRefreshChannelCache && gld != null) - { await this.RefreshChannelsAsync(channel.Guild.Id).ConfigureAwait(false); - } } else if (gld != null) { gld.ChannelsInternal[channel.Id] = channel; if (this.Configuration.AutoRefreshChannelCache) - { await this.RefreshChannelsAsync(channel.Guild.Id).ConfigureAwait(false); - } } - await this._channelUpdated.InvokeAsync(this, new(this.ServiceProvider) { ChannelAfter = channelNew, Guild = gld, ChannelBefore = channelOld }).ConfigureAwait(false); + await this._channelUpdated.InvokeAsync(this, new(this.ServiceProvider) + { + ChannelAfter = channelNew, Guild = gld, ChannelBefore = channelOld + }).ConfigureAwait(false); } /// @@ -938,7 +953,10 @@ internal async Task OnChannelDeleteEventAsync(DiscordChannel channel) { var dmChannel = channel as DiscordDmChannel; - await this._dmChannelDeleted.InvokeAsync(this, new(this.ServiceProvider) { Channel = dmChannel }).ConfigureAwait(false); + await this._dmChannelDeleted.InvokeAsync(this, new(this.ServiceProvider) + { + Channel = dmChannel + }).ConfigureAwait(false); } else { @@ -947,11 +965,12 @@ internal async Task OnChannelDeleteEventAsync(DiscordChannel channel) if (gld.ChannelsInternal.TryRemove(channel.Id, out var cachedChannel)) channel = cachedChannel; if (this.Configuration.AutoRefreshChannelCache) - { await this.RefreshChannelsAsync(channel.Guild.Id).ConfigureAwait(false); - } - await this._channelDeleted.InvokeAsync(this, new(this.ServiceProvider) { Channel = channel, Guild = gld }).ConfigureAwait(false); + await this._channelDeleted.InvokeAsync(this, new(this.ServiceProvider) + { + Channel = channel, Guild = gld + }).ConfigureAwait(false); } } @@ -984,9 +1003,7 @@ internal async Task OnChannelPinsUpdateAsync(ulong? guildId, ulong channelId, Da var ea = new ChannelPinsUpdateEventArgs(this.ServiceProvider) { - Guild = guild, - Channel = channel, - LastPinTimestamp = lastPinTimestamp + Guild = guild, Channel = channel, LastPinTimestamp = lastPinTimestamp }; await this._channelPinsUpdated.InvokeAsync(this, ea).ConfigureAwait(false); } @@ -1004,16 +1021,14 @@ internal async Task OnVoiceChannelStatusUpdateAsync(ulong guildId, ulong channel var ea = new VoiceChannelStatusUpdateEventArgs(this.ServiceProvider) { - Guild = guild, - Channel = channel, - Status = status + Guild = guild, Channel = channel, Status = status }; await this._voiceChannelStatusUpdated.InvokeAsync(this, ea).ConfigureAwait(false); } - #endregion +#endregion - #region Guild +#region Guild /// /// Handles the guild create event. @@ -1024,20 +1039,16 @@ internal async Task OnVoiceChannelStatusUpdateAsync(ulong guildId, ulong channel internal async Task OnGuildCreateEventAsync(DiscordGuild guild, JArray rawMembers, IEnumerable presences) { if (presences != null) - { foreach (var xp in presences) { xp.Discord = this; xp.GuildId = guild.Id; xp.Activity = new(xp.RawActivity); if (xp.RawActivities != null) - { xp.InternalActivities = xp.RawActivities .Select(x => new DiscordActivity(x)).ToArray(); - } this.PresencesInternal[xp.InternalUser.Id] = xp; } - } var exists = this.GuildsInternal.TryGetValue(guild.Id, out var foundGuild); @@ -1084,11 +1095,13 @@ internal async Task OnGuildCreateEventAsync(DiscordGuild guild, JArray rawMember xc.GuildId = guild.Id; xc.Initialize(this); } + foreach (var xt in guild.ThreadsInternal.Values) { xt.GuildId = guild.Id; xt.Discord = this; } + foreach (var xe in guild.EmojisInternal.Values) xe.Discord = this; foreach (var xs in guild.StickersInternal.Values) @@ -1100,11 +1113,13 @@ internal async Task OnGuildCreateEventAsync(DiscordGuild guild, JArray rawMember xsi.Discord = this; xsi.GuildId = guild.Id; } + foreach (var xr in guild.RolesInternal.Values) { xr.Discord = this; xr.GuildId = guild.Id; } + foreach (var xse in guild.ScheduledEventsInternal.Values) { xse.Discord = this; @@ -1118,9 +1133,15 @@ internal async Task OnGuildCreateEventAsync(DiscordGuild guild, JArray rawMember Volatile.Write(ref this._guildDownloadCompleted, dcompl); if (exists) - await this._guildAvailable.InvokeAsync(this, new(this.ServiceProvider) { Guild = guild }).ConfigureAwait(false); + await this._guildAvailable.InvokeAsync(this, new(this.ServiceProvider) + { + Guild = guild + }).ConfigureAwait(false); else - await this._guildCreated.InvokeAsync(this, new(this.ServiceProvider) { Guild = guild }).ConfigureAwait(false); + await this._guildCreated.InvokeAsync(this, new(this.ServiceProvider) + { + Guild = guild + }).ConfigureAwait(false); if (dcompl && !old) await this._guildDownloadCompletedEv.InvokeAsync(this, new(this.Guilds, this.ServiceProvider)).ConfigureAwait(false); @@ -1228,11 +1249,13 @@ internal async Task OnGuildUpdateEventAsync(DiscordGuild guild, JArray rawMember xc.GuildId = guild.Id; xc.Initialize(this); } + foreach (var xc in guild.ThreadsInternal.Values) { xc.GuildId = guild.Id; xc.Discord = this; } + foreach (var xe in guild.EmojisInternal.Values) xe.Discord = this; foreach (var xs in guild.StickersInternal.Values) @@ -1244,11 +1267,13 @@ internal async Task OnGuildUpdateEventAsync(DiscordGuild guild, JArray rawMember xr.Discord = this; xr.GuildId = guild.Id; } + foreach (var xsi in guild.StageInstancesInternal.Values) { xsi.Discord = this; xsi.GuildId = guild.Id; } + foreach (var xse in guild.ScheduledEventsInternal.Values) { xse.Discord = this; @@ -1257,7 +1282,10 @@ internal async Task OnGuildUpdateEventAsync(DiscordGuild guild, JArray rawMember xse.Creator.Discord = this; } - await this._guildUpdated.InvokeAsync(this, new(this.ServiceProvider) { GuildBefore = oldGuild, GuildAfter = guild }).ConfigureAwait(false); + await this._guildUpdated.InvokeAsync(this, new(this.ServiceProvider) + { + GuildBefore = oldGuild, GuildAfter = guild + }).ConfigureAwait(false); } /// @@ -1273,14 +1301,20 @@ internal async Task OnGuildDeleteEventAsync(DiscordGuild guild) gld.IsUnavailable = true; - await this._guildUnavailable.InvokeAsync(this, new(this.ServiceProvider) { Guild = guild, Unavailable = true }).ConfigureAwait(false); + await this._guildUnavailable.InvokeAsync(this, new(this.ServiceProvider) + { + Guild = guild, Unavailable = true + }).ConfigureAwait(false); } else { if (!this.GuildsInternal.TryRemove(guild.Id, out var gld)) return; - await this._guildDeleted.InvokeAsync(this, new(this.ServiceProvider) { Guild = gld }).ConfigureAwait(false); + await this._guildDeleted.InvokeAsync(this, new(this.ServiceProvider) + { + Guild = gld + }).ConfigureAwait(false); } } @@ -1293,7 +1327,7 @@ internal async Task OnGuildAuditLogEntryCreateEventAsync(DiscordGuild guild, JOb { try { - var auditLogAction = DiscordJson.ToDiscordObject(auditLogCreateEntry); + /*var auditLogAction = DiscordJson.ToDiscordObject(auditLogCreateEntry); List workaroundAuditLogEntryList = new() { new() @@ -1303,11 +1337,14 @@ internal async Task OnGuildAuditLogEntryCreateEventAsync(DiscordGuild guild, JOb auditLogAction } } - }; + };*/ - var dataList = await guild.ProcessAuditLog(workaroundAuditLogEntryList).ConfigureAwait(false); + //var dataList = await guild.ProcessAuditLog(workaroundAuditLogEntryList).ConfigureAwait(false); - await this._guildAuditLogEntryCreated.InvokeAsync(this, new(this.ServiceProvider) { Guild = guild, AuditLogEntry = dataList[0] }).ConfigureAwait(false); + await this._guildAuditLogEntryCreated.InvokeAsync(this, new(this.ServiceProvider) + { + Guild = guild, AuditLogEntry = auditLogCreateEntry + }).ConfigureAwait(false); } catch (Exception) { } @@ -1322,7 +1359,12 @@ internal async Task OnGuildAuditLogEntryCreateEventAsync(DiscordGuild guild, JOb /// The presences. internal async Task OnGuildSyncEventAsync(DiscordGuild guild, bool isLarge, JArray rawMembers, IEnumerable presences) { - presences = presences.Select(xp => { xp.Discord = this; xp.Activity = new(xp.RawActivity); return xp; }); + presences = presences.Select(xp => + { + xp.Discord = this; + xp.Activity = new(xp.RawActivity); + return xp; + }); foreach (var xp in presences) this.PresencesInternal[xp.InternalUser.Id] = xp; @@ -1331,7 +1373,10 @@ internal async Task OnGuildSyncEventAsync(DiscordGuild guild, bool isLarge, JArr this.UpdateCachedGuild(guild, rawMembers); - await this._guildAvailable.InvokeAsync(this, new(this.ServiceProvider) { Guild = guild }).ConfigureAwait(false); + await this._guildAvailable.InvokeAsync(this, new(this.ServiceProvider) + { + Guild = guild + }).ConfigureAwait(false); } /// @@ -1352,9 +1397,7 @@ internal async Task OnGuildEmojisUpdateEventAsync(DiscordGuild guild, IEnumerabl var ea = new GuildEmojisUpdateEventArgs(this.ServiceProvider) { - Guild = guild, - EmojisAfter = guild.Emojis, - EmojisBefore = new ReadOnlyConcurrentDictionary(oldEmojis) + Guild = guild, EmojisAfter = guild.Emojis, EmojisBefore = new ReadOnlyConcurrentDictionary(oldEmojis) }; await this._guildEmojisUpdated.InvokeAsync(this, ea).ConfigureAwait(false); } @@ -1377,6 +1420,7 @@ internal async Task OnStickersUpdatedAsync(IEnumerable newSticke nst.User.Discord = this; this.UserCache.AddOrUpdate(nst.User.Id, nst.User, (old, @new) => @new); } + nst.Discord = this; guild.StickersInternal[nst.Id] = nst; @@ -1384,9 +1428,7 @@ internal async Task OnStickersUpdatedAsync(IEnumerable newSticke var sea = new GuildStickersUpdateEventArgs(this.ServiceProvider) { - Guild = guild, - StickersBefore = oldStickers, - StickersAfter = guild.Stickers + Guild = guild, StickersBefore = oldStickers, StickersAfter = guild.Stickers }; await this._guildStickersUpdated.InvokeAsync(this, sea).ConfigureAwait(false); @@ -1448,7 +1490,7 @@ internal async Task OnAutomodActionExecuted(DiscordGuild guild, JObject rawPaylo var channelId = rawPayload.TryGetValue("channel_id", out var value) ? (ulong?)value : null; var messageId = rawPayload.TryGetValue("message_id", out var value1) ? (ulong?)value1 : null; var alertMessageId = rawPayload.TryGetValue("alert_system_message_id", out var value2) ? (ulong?)value2 : null; - var content = rawPayload.TryGetValue("content", out var value3) ?(string?)value3 : null; + var content = rawPayload.TryGetValue("content", out var value3) ? (string?)value3 : null; var matchedKeyword = rawPayload.TryGetValue("matched_keyword", out var value4) ? (string?)value4 : null; var matchedContent = rawPayload.TryGetValue("matched_content", out var value5) ? (string?)value5 : null; @@ -1470,9 +1512,9 @@ internal async Task OnAutomodActionExecuted(DiscordGuild guild, JObject rawPaylo await this._automodActionExecuted.InvokeAsync(this, ea).ConfigureAwait(false); } - #endregion +#endregion - #region Guild Ban +#region Guild Ban /// /// Handles the guild ban add event. @@ -1481,7 +1523,10 @@ internal async Task OnAutomodActionExecuted(DiscordGuild guild, JObject rawPaylo /// The guild. internal async Task OnGuildBanAddEventAsync(TransportUser user, DiscordGuild guild) { - var usr = new DiscordUser(user) { Discord = this }; + var usr = new DiscordUser(user) + { + Discord = this + }; usr = this.UserCache.AddOrUpdate(user.Id, usr, (id, old) => { old.Username = usr.Username; @@ -1492,11 +1537,13 @@ internal async Task OnGuildBanAddEventAsync(TransportUser user, DiscordGuild gui }); if (!guild.Members.TryGetValue(user.Id, out var mbr)) - mbr = new(usr) { Discord = this, GuildId = guild.Id }; + mbr = new(usr) + { + Discord = this, GuildId = guild.Id + }; var ea = new GuildBanAddEventArgs(this.ServiceProvider) { - Guild = guild, - Member = mbr + Guild = guild, Member = mbr }; await this._guildBanAdded.InvokeAsync(this, ea).ConfigureAwait(false); } @@ -1508,7 +1555,10 @@ internal async Task OnGuildBanAddEventAsync(TransportUser user, DiscordGuild gui /// The guild. internal async Task OnGuildBanRemoveEventAsync(TransportUser user, DiscordGuild guild) { - var usr = new DiscordUser(user) { Discord = this }; + var usr = new DiscordUser(user) + { + Discord = this + }; usr = this.UserCache.AddOrUpdate(user.Id, usr, (id, old) => { old.Username = usr.Username; @@ -1519,18 +1569,20 @@ internal async Task OnGuildBanRemoveEventAsync(TransportUser user, DiscordGuild }); if (!guild.Members.TryGetValue(user.Id, out var mbr)) - mbr = new(usr) { Discord = this, GuildId = guild.Id }; + mbr = new(usr) + { + Discord = this, GuildId = guild.Id + }; var ea = new GuildBanRemoveEventArgs(this.ServiceProvider) { - Guild = guild, - Member = mbr + Guild = guild, Member = mbr }; await this._guildBanRemoved.InvokeAsync(this, ea).ConfigureAwait(false); } - #endregion +#endregion - #region Guild Scheduled Event +#region Guild Scheduled Event /// /// Handles the scheduled event create event. @@ -1557,7 +1609,10 @@ internal async Task OnGuildScheduledEventCreateEventAsync(DiscordScheduledEvent }); } - await this._guildScheduledEventCreated.InvokeAsync(this, new(this.ServiceProvider) { ScheduledEvent = scheduledEvent, Guild = scheduledEvent.Guild }).ConfigureAwait(false); + await this._guildScheduledEventCreated.InvokeAsync(this, new(this.ServiceProvider) + { + ScheduledEvent = scheduledEvent, Guild = scheduledEvent.Guild + }).ConfigureAwait(false); } /// @@ -1572,9 +1627,7 @@ internal async Task OnGuildScheduledEventUpdateEventAsync(DiscordScheduledEvent DiscordScheduledEvent oldEvent; if (!guild.ScheduledEventsInternal.ContainsKey(scheduledEvent.Id)) - { oldEvent = null; - } else { var ev = guild.ScheduledEventsInternal[scheduledEvent.Id]; @@ -1597,8 +1650,8 @@ internal async Task OnGuildScheduledEventUpdateEventAsync(DiscordScheduledEvent UserCount = ev.UserCount, CoverImageHash = ev.CoverImageHash }; - } + if (scheduledEvent.Creator != null) { scheduledEvent.Creator.Discord = this; @@ -1616,18 +1669,27 @@ internal async Task OnGuildScheduledEventUpdateEventAsync(DiscordScheduledEvent if (scheduledEvent.Status == ScheduledEventStatus.Completed) { guild.ScheduledEventsInternal.TryRemove(scheduledEvent.Id, out var deletedEvent); - await this._guildScheduledEventDeleted.InvokeAsync(this, new(this.ServiceProvider) { ScheduledEvent = scheduledEvent, Guild = guild, Reason = ScheduledEventStatus.Completed }).ConfigureAwait(false); + await this._guildScheduledEventDeleted.InvokeAsync(this, new(this.ServiceProvider) + { + ScheduledEvent = scheduledEvent, Guild = guild, Reason = ScheduledEventStatus.Completed + }).ConfigureAwait(false); } else if (scheduledEvent.Status == ScheduledEventStatus.Canceled) { guild.ScheduledEventsInternal.TryRemove(scheduledEvent.Id, out var deletedEvent); scheduledEvent.Status = ScheduledEventStatus.Canceled; - await this._guildScheduledEventDeleted.InvokeAsync(this, new(this.ServiceProvider) { ScheduledEvent = scheduledEvent, Guild = guild, Reason = ScheduledEventStatus.Canceled }).ConfigureAwait(false); + await this._guildScheduledEventDeleted.InvokeAsync(this, new(this.ServiceProvider) + { + ScheduledEvent = scheduledEvent, Guild = guild, Reason = ScheduledEventStatus.Canceled + }).ConfigureAwait(false); } else { this.UpdateScheduledEvent(scheduledEvent, guild); - await this._guildScheduledEventUpdated.InvokeAsync(this, new(this.ServiceProvider) { ScheduledEventBefore = oldEvent, ScheduledEventAfter = scheduledEvent, Guild = guild }).ConfigureAwait(false); + await this._guildScheduledEventUpdated.InvokeAsync(this, new(this.ServiceProvider) + { + ScheduledEventBefore = oldEvent, ScheduledEventAfter = scheduledEvent, Guild = guild + }).ConfigureAwait(false); } } @@ -1657,7 +1719,10 @@ internal async Task OnGuildScheduledEventDeleteEventAsync(DiscordScheduledEvent }); } - await this._guildScheduledEventDeleted.InvokeAsync(this, new(this.ServiceProvider) { ScheduledEvent = scheduledEvent, Guild = scheduledEvent.Guild, Reason = scheduledEvent.Status }).ConfigureAwait(false); + await this._guildScheduledEventDeleted.InvokeAsync(this, new(this.ServiceProvider) + { + ScheduledEvent = scheduledEvent, Guild = scheduledEvent.Guild, Reason = scheduledEvent.Status + }).ConfigureAwait(false); guild.ScheduledEventsInternal.TryRemove(scheduledEvent.Id, out var deletedEvent); } @@ -1671,10 +1736,7 @@ internal async Task OnGuildScheduledEventUserAddedEventAsync(ulong guildSchedule { var scheduledEvent = this.InternalGetCachedScheduledEvent(guildScheduledEventId) ?? this.UpdateScheduledEvent(new() { - Id = guildScheduledEventId, - GuildId = guild.Id, - Discord = this, - UserCount = 0 + Id = guildScheduledEventId, GuildId = guild.Id, Discord = this, UserCount = 0 }, guild); scheduledEvent.UserCount++; @@ -1686,7 +1748,10 @@ internal async Task OnGuildScheduledEventUserAddedEventAsync(ulong guildSchedule var member = guild.Members.TryGetValue(userId, out var mem) ? mem : guild.GetMemberAsync(userId).Result; member.Discord = this; - await this._guildScheduledEventUserAdded.InvokeAsync(this, new(this.ServiceProvider) { ScheduledEvent = scheduledEvent, Guild = guild, User = user, Member = member }).ConfigureAwait(false); + await this._guildScheduledEventUserAdded.InvokeAsync(this, new(this.ServiceProvider) + { + ScheduledEvent = scheduledEvent, Guild = guild, User = user, Member = member + }).ConfigureAwait(false); } /// @@ -1699,10 +1764,7 @@ internal async Task OnGuildScheduledEventUserRemovedEventAsync(ulong guildSchedu { var scheduledEvent = this.InternalGetCachedScheduledEvent(guildScheduledEventId) ?? this.UpdateScheduledEvent(new() { - Id = guildScheduledEventId, - GuildId = guild.Id, - Discord = this, - UserCount = 0 + Id = guildScheduledEventId, GuildId = guild.Id, Discord = this, UserCount = 0 }, guild); scheduledEvent.UserCount = scheduledEvent.UserCount == 0 ? 0 : scheduledEvent.UserCount - 1; @@ -1714,12 +1776,15 @@ internal async Task OnGuildScheduledEventUserRemovedEventAsync(ulong guildSchedu var member = guild.Members.TryGetValue(userId, out var mem) ? mem : guild.GetMemberAsync(userId).Result; member.Discord = this; - await this._guildScheduledEventUserRemoved.InvokeAsync(this, new(this.ServiceProvider) { ScheduledEvent = scheduledEvent, Guild = guild, User = user, Member = member }).ConfigureAwait(false); + await this._guildScheduledEventUserRemoved.InvokeAsync(this, new(this.ServiceProvider) + { + ScheduledEvent = scheduledEvent, Guild = guild, User = user, Member = member + }).ConfigureAwait(false); } - #endregion +#endregion - #region Guild Integration +#region Guild Integration /// /// Handles the guild integration create event. @@ -1730,7 +1795,10 @@ internal async Task OnGuildIntegrationCreateEventAsync(DiscordGuild guild, Disco { integration.Discord = this; - await this._guildIntegrationCreated.InvokeAsync(this, new(this.ServiceProvider) { Integration = integration, Guild = guild }).ConfigureAwait(false); + await this._guildIntegrationCreated.InvokeAsync(this, new(this.ServiceProvider) + { + Integration = integration, Guild = guild + }).ConfigureAwait(false); } /// @@ -1742,7 +1810,10 @@ internal async Task OnGuildIntegrationUpdateEventAsync(DiscordGuild guild, Disco { integration.Discord = this; - await this._guildIntegrationUpdated.InvokeAsync(this, new(this.ServiceProvider) { Integration = integration, Guild = guild }).ConfigureAwait(false); + await this._guildIntegrationUpdated.InvokeAsync(this, new(this.ServiceProvider) + { + Integration = integration, Guild = guild + }).ConfigureAwait(false); } /// @@ -1765,11 +1836,14 @@ internal async Task OnGuildIntegrationsUpdateEventAsync(DiscordGuild guild) /// The integration id. /// The optional application id. internal async Task OnGuildIntegrationDeleteEventAsync(DiscordGuild guild, ulong integrationId, ulong? applicationId) - => await this._guildIntegrationDeleted.InvokeAsync(this, new(this.ServiceProvider) { Guild = guild, IntegrationId = integrationId, ApplicationId = applicationId }).ConfigureAwait(false); + => await this._guildIntegrationDeleted.InvokeAsync(this, new(this.ServiceProvider) + { + Guild = guild, IntegrationId = integrationId, ApplicationId = applicationId + }).ConfigureAwait(false); - #endregion +#endregion - #region Guild Member +#region Guild Member /// /// Handles the guild member add event. @@ -1778,7 +1852,10 @@ internal async Task OnGuildIntegrationDeleteEventAsync(DiscordGuild guild, ulong /// The guild. internal async Task OnGuildMemberAddEventAsync(TransportMember member, DiscordGuild guild) { - var usr = new DiscordUser(member.User) { Discord = this }; + var usr = new DiscordUser(member.User) + { + Discord = this + }; usr = this.UserCache.AddOrUpdate(member.User.Id, usr, (id, old) => { old.Username = usr.Username; @@ -1790,8 +1867,7 @@ internal async Task OnGuildMemberAddEventAsync(TransportMember member, DiscordGu var mbr = new DiscordMember(member) { - Discord = this, - GuildId = guild.Id + Discord = this, GuildId = guild.Id }; guild.MembersInternal[mbr.Id] = mbr; @@ -1799,8 +1875,7 @@ internal async Task OnGuildMemberAddEventAsync(TransportMember member, DiscordGu var ea = new GuildMemberAddEventArgs(this.ServiceProvider) { - Guild = guild, - Member = mbr + Guild = guild, Member = mbr }; await this._guildMemberAdded.InvokeAsync(this, ea).ConfigureAwait(false); } @@ -1815,15 +1890,17 @@ internal async Task OnGuildMemberRemoveEventAsync(TransportUser user, DiscordGui var usr = new DiscordUser(user); if (!guild.MembersInternal.TryRemove(user.Id, out var mbr)) - mbr = new(usr) { Discord = this, GuildId = guild.Id }; + mbr = new(usr) + { + Discord = this, GuildId = guild.Id + }; guild.MemberCount--; _ = this.UserCache.AddOrUpdate(user.Id, usr, (old, @new) => @new); var ea = new GuildMemberRemoveEventArgs(this.ServiceProvider) { - Guild = guild, - Member = mbr + Guild = guild, Member = mbr }; await this._guildMemberRemoved.InvokeAsync(this, ea).ConfigureAwait(false); } @@ -1838,7 +1915,10 @@ internal async Task OnGuildMemberRemoveEventAsync(TransportUser user, DiscordGui /// Whether the member is pending. internal async Task OnGuildMemberUpdateEventAsync(TransportMember member, DiscordGuild guild, IEnumerable roles, string nick, bool? pending) { - var usr = new DiscordUser(member.User) { Discord = this }; + var usr = new DiscordUser(member.User) + { + Discord = this + }; usr = this.UserCache.AddOrUpdate(usr.Id, usr, (id, old) => { old.Username = usr.Username; @@ -1849,7 +1929,10 @@ internal async Task OnGuildMemberUpdateEventAsync(TransportMember member, Discor }); if (!guild.Members.TryGetValue(member.User.Id, out var mbr)) - mbr = new(usr) { Discord = this, GuildId = guild.Id }; + mbr = new(usr) + { + Discord = this, GuildId = guild.Id + }; var old = mbr; var gAvOld = old.GuildAvatarHash; @@ -1908,7 +1991,6 @@ internal async Task OnGuildMemberUpdateEventAsync(TransportMember member, Discor { Guild = guild, Member = mbr, - NicknameAfter = mbr.Nickname, RolesAfter = new ReadOnlyCollection(new List(mbr.Roles)), PendingAfter = mbr.IsPending, @@ -1916,7 +1998,6 @@ internal async Task OnGuildMemberUpdateEventAsync(TransportMember member, Discor AvatarHashAfter = mbr.AvatarHash, GuildAvatarHashAfter = mbr.GuildAvatarHash, UnusualDmActivityAfter = mbr.UnusualDmActivityUntil, - NicknameBefore = nickOld, RolesBefore = rolesOld, PendingBefore = pendingOld, @@ -1928,7 +2009,7 @@ internal async Task OnGuildMemberUpdateEventAsync(TransportMember member, Discor await this._guildMemberUpdated.InvokeAsync(this, eargs).ConfigureAwait(false); } - /// + /*/// /// Handles timeout events. /// /// Internally used as uid for the timer data. @@ -2032,7 +2113,7 @@ private async void TimeoutTimer(object state) this.Logger.LogTrace("Removing timeout event."); await timer.DisposeAsync().ConfigureAwait(false); this._tempTimers.Remove(tid); - } + }*/ /// /// Handles the guild members chunk event. @@ -2052,10 +2133,16 @@ internal async Task OnGuildMembersChunkEventAsync(JObject dat) foreach (var member in members) { - var mbr = new DiscordMember(member) { Discord = this, GuildId = guild.Id }; + var mbr = new DiscordMember(member) + { + Discord = this, GuildId = guild.Id + }; if (!this.UserCache.ContainsKey(mbr.Id)) - this.UserCache[mbr.Id] = new(member.User) { Discord = this }; + this.UserCache[mbr.Id] = new(member.User) + { + Discord = this + }; guild.MembersInternal[mbr.Id] = mbr; @@ -2070,7 +2157,7 @@ internal async Task OnGuildMembersChunkEventAsync(JObject dat) Members = new ReadOnlySet(mbrs), ChunkIndex = chunkIndex, ChunkCount = chunkCount, - Nonce = nonce, + Nonce = nonce }; if (dat["presences"] != null) @@ -2084,10 +2171,8 @@ internal async Task OnGuildMembersChunkEventAsync(JObject dat) presence.Activity = new(presence.RawActivity); if (presence.RawActivities != null) - { presence.InternalActivities = presence.RawActivities .Select(x => new DiscordActivity(x)).ToArray(); - } pres.Add(presence); } @@ -2104,9 +2189,9 @@ internal async Task OnGuildMembersChunkEventAsync(JObject dat) await this._guildMembersChunked.InvokeAsync(this, ea).ConfigureAwait(false); } - #endregion +#endregion - #region Guild Role +#region Guild Role /// /// Handles the guild role create event. @@ -2122,8 +2207,7 @@ internal async Task OnGuildRoleCreateEventAsync(DiscordRole role, DiscordGuild g var ea = new GuildRoleCreateEventArgs(this.ServiceProvider) { - Guild = guild, - Role = role + Guild = guild, Role = role }; await this._guildRoleCreated.InvokeAsync(this, ea).ConfigureAwait(false); } @@ -2167,9 +2251,7 @@ internal async Task OnGuildRoleUpdateEventAsync(DiscordRole role, DiscordGuild g var ea = new GuildRoleUpdateEventArgs(this.ServiceProvider) { - Guild = guild, - RoleAfter = newRole, - RoleBefore = oldRole + Guild = guild, RoleAfter = newRole, RoleBefore = oldRole }; await this._guildRoleUpdated.InvokeAsync(this, ea).ConfigureAwait(false); } @@ -2186,15 +2268,14 @@ internal async Task OnGuildRoleDeleteEventAsync(ulong roleId, DiscordGuild guild var ea = new GuildRoleDeleteEventArgs(this.ServiceProvider) { - Guild = guild, - Role = role + Guild = guild, Role = role }; await this._guildRoleDeleted.InvokeAsync(this, ea).ConfigureAwait(false); } - #endregion +#endregion - #region Invite +#region Invite /// /// Handles the invite create event. @@ -2219,9 +2300,7 @@ internal async Task OnInviteCreateEventAsync(ulong channelId, ulong guildId, Dis var ea = new InviteCreateEventArgs(this.ServiceProvider) { - Channel = channel, - Guild = guild, - Invite = invite + Channel = channel, Guild = guild, Invite = invite }; await this._inviteCreated.InvokeAsync(this, ea).ConfigureAwait(false); } @@ -2247,16 +2326,14 @@ internal async Task OnInviteDeleteEventAsync(ulong channelId, ulong guildId, JTo var ea = new InviteDeleteEventArgs(this.ServiceProvider) { - Channel = channel, - Guild = guild, - Invite = invite + Channel = channel, Guild = guild, Invite = invite }; await this._inviteDeleted.InvokeAsync(this, ea).ConfigureAwait(false); } - #endregion +#endregion - #region Message +#region Message /// /// Handles the message acknowledge event. @@ -2266,16 +2343,15 @@ internal async Task OnInviteDeleteEventAsync(ulong channelId, ulong guildId, JTo internal async Task OnMessageAckEventAsync(DiscordChannel chn, ulong messageId) { if (this.MessageCache == null || !this.MessageCache.TryGet(xm => xm.Id == messageId && xm.ChannelId == chn.Id, out var msg)) - { msg = new() { - Id = messageId, - ChannelId = chn.Id, - Discord = this, + Id = messageId, ChannelId = chn.Id, Discord = this }; - } - await this._messageAcknowledged.InvokeAsync(this, new(this.ServiceProvider) { Message = msg }).ConfigureAwait(false); + await this._messageAcknowledged.InvokeAsync(this, new(this.ServiceProvider) + { + Message = msg + }).ConfigureAwait(false); } /// @@ -2307,11 +2383,7 @@ internal async Task OnMessageCreateEventAsync(DiscordMessage message, TransportU var ea = new MessageCreateEventArgs(this.ServiceProvider) { - Message = message, - - MentionedUsers = new ReadOnlyCollection(message.MentionedUsersInternal), - MentionedRoles = message.MentionedRolesInternal != null ? new ReadOnlyCollection(message.MentionedRolesInternal) : null, - MentionedChannels = message.MentionedChannelsInternal != null ? new ReadOnlyCollection(message.MentionedChannelsInternal) : null + Message = message, MentionedUsers = new ReadOnlyCollection(message.MentionedUsersInternal), MentionedRoles = message.MentionedRolesInternal != null ? new ReadOnlyCollection(message.MentionedRolesInternal) : null, MentionedChannels = message.MentionedChannelsInternal != null ? new ReadOnlyCollection(message.MentionedChannelsInternal) : null }; await this._messageCreated.InvokeAsync(this, ea).ConfigureAwait(false); } @@ -2333,8 +2405,8 @@ internal async Task OnMessageUpdateEventAsync(DiscordMessage message, TransportU DiscordMessage oldmsg = null; if (this.Configuration.MessageCacheSize == 0 - || this.MessageCache == null - || !this.MessageCache.TryGet(xm => xm.Id == eventMessage.Id && xm.ChannelId == eventMessage.ChannelId, out message)) + || this.MessageCache == null + || !this.MessageCache.TryGet(xm => xm.Id == eventMessage.Id && xm.ChannelId == eventMessage.ChannelId, out message)) { message = eventMessage; this.PopulateMessageReactionsAndCache(message, author, member); @@ -2386,27 +2458,20 @@ internal async Task OnMessageDeleteEventAsync(ulong messageId, ulong channelId, var guild = this.InternalGetCachedGuild(guildId); if (channel == null - || this.Configuration.MessageCacheSize == 0 - || this.MessageCache == null - || !this.MessageCache.TryGet(xm => xm.Id == messageId && xm.ChannelId == channelId, out var msg)) - { + || this.Configuration.MessageCacheSize == 0 + || this.MessageCache == null + || !this.MessageCache.TryGet(xm => xm.Id == messageId && xm.ChannelId == channelId, out var msg)) msg = new() { - - Id = messageId, - ChannelId = channelId, - Discord = this, + Id = messageId, ChannelId = channelId, Discord = this }; - } if (this.Configuration.MessageCacheSize > 0) this.MessageCache?.Remove(xm => xm.Id == msg.Id && xm.ChannelId == channelId); var ea = new MessageDeleteEventArgs(this.ServiceProvider) { - Channel = channel, - Message = msg, - Guild = guild + Channel = channel, Message = msg, Guild = guild }; await this._messageDeleted.InvokeAsync(this, ea).ConfigureAwait(false); } @@ -2425,17 +2490,13 @@ internal async Task OnMessageBulkDeleteEventAsync(ulong[] messageIds, ulong chan foreach (var messageId in messageIds) { if (channel == null - || this.Configuration.MessageCacheSize == 0 - || this.MessageCache == null - || !this.MessageCache.TryGet(xm => xm.Id == messageId && xm.ChannelId == channelId, out var msg)) - { + || this.Configuration.MessageCacheSize == 0 + || this.MessageCache == null + || !this.MessageCache.TryGet(xm => xm.Id == messageId && xm.ChannelId == channelId, out var msg)) msg = new() { - Id = messageId, - ChannelId = channelId, - Discord = this, + Id = messageId, ChannelId = channelId, Discord = this }; - } if (this.Configuration.MessageCacheSize > 0) this.MessageCache?.Remove(xm => xm.Id == msg.Id && xm.ChannelId == channelId); msgs.Add(msg); @@ -2445,16 +2506,14 @@ internal async Task OnMessageBulkDeleteEventAsync(ulong[] messageIds, ulong chan var ea = new MessageBulkDeleteEventArgs(this.ServiceProvider) { - Channel = channel, - Messages = new ReadOnlyCollection(msgs), - Guild = guild + Channel = channel, Messages = new ReadOnlyCollection(msgs), Guild = guild }; await this._messagesBulkDeleted.InvokeAsync(this, ea).ConfigureAwait(false); } - #endregion +#endregion - #region Message Reaction +#region Message Reaction /// /// Handles the message reaction add event. @@ -2472,7 +2531,10 @@ internal async Task OnMessageReactionAddAsync(ulong userId, ulong messageId, ulo var guild = this.InternalGetCachedGuild(guildId); emoji.Discord = this; - var usr = this.UpdateUser(new() { Id = userId, Discord = this }, guildId, guild, mbr); + var usr = this.UpdateUser(new() + { + Id = userId, Discord = this + }, guildId, guild, mbr); DiscordMessage? msg = null; @@ -2481,22 +2543,15 @@ internal async Task OnMessageReactionAddAsync(ulong userId, ulong messageId, ulo msg ??= new() { - Id = messageId, - ChannelId = channelId, - Discord = this, - ReactionsInternal = new() + Id = messageId, ChannelId = channelId, Discord = this, ReactionsInternal = new() }; var react = msg.ReactionsInternal.FirstOrDefault(xr => xr.Emoji == emoji); if (react == null) - { msg.ReactionsInternal.Add(react = new() { - Count = 1, - Emoji = emoji, - IsMe = this.CurrentUser.Id == userId + Count = 1, Emoji = emoji, IsMe = this.CurrentUser.Id == userId }); - } else { react.Count++; @@ -2529,21 +2584,24 @@ internal async Task OnMessageReactionRemoveAsync(ulong userId, ulong messageId, { var channel = this.InternalGetCachedChannel(channelId) ?? this.InternalGetCachedThread(channelId) ?? new DiscordChannel() { - Type = ChannelType.Unknown, - Id = channelId, - GuildId = guildId, - Discord = this + Type = ChannelType.Unknown, Id = channelId, GuildId = guildId, Discord = this }; emoji.Discord = this; if (!this.UserCache.TryGetValue(userId, out var usr)) - usr = new() { Id = userId, Discord = this }; + usr = new() + { + Id = userId, Discord = this + }; if (channel?.Guild != null) usr = channel.Guild.Members.TryGetValue(userId, out var member) ? member - : new(usr) { Discord = this, GuildId = channel.GuildId.Value }; + : new(usr) + { + Discord = this, GuildId = channel.GuildId.Value + }; DiscordMessage? msg = null; @@ -2552,9 +2610,7 @@ internal async Task OnMessageReactionRemoveAsync(ulong userId, ulong messageId, msg ??= new() { - Id = messageId, - ChannelId = channelId, - Discord = this + Id = messageId, ChannelId = channelId, Discord = this }; var react = msg.ReactionsInternal?.FirstOrDefault(xr => xr.Emoji == emoji); @@ -2593,24 +2649,17 @@ internal async Task OnMessageReactionRemoveAllAsync(ulong messageId, ulong chann { var channel = this.InternalGetCachedChannel(channelId) ?? this.InternalGetCachedThread(channelId) ?? new DiscordChannel() { - Type = ChannelType.Unknown, - Id = channelId, - GuildId = guildId, - Discord = this + Type = ChannelType.Unknown, Id = channelId, GuildId = guildId, Discord = this }; if (channel == null - || this.Configuration.MessageCacheSize == 0 - || this.MessageCache == null - || !this.MessageCache.TryGet(xm => xm.Id == messageId && xm.ChannelId == channelId, out var msg)) - { + || this.Configuration.MessageCacheSize == 0 + || this.MessageCache == null + || !this.MessageCache.TryGet(xm => xm.Id == messageId && xm.ChannelId == channelId, out var msg)) msg = new() { - Id = messageId, - ChannelId = channelId, - Discord = this + Id = messageId, ChannelId = channelId, Discord = this }; - } msg.ReactionsInternal?.Clear(); @@ -2638,17 +2687,13 @@ internal async Task OnMessageReactionRemoveEmojiAsync(ulong messageId, ulong cha var channel = this.InternalGetCachedChannel(channelId) ?? this.InternalGetCachedThread(channelId); if (channel == null - || this.Configuration.MessageCacheSize == 0 - || this.MessageCache == null - || !this.MessageCache.TryGet(xm => xm.Id == messageId && xm.ChannelId == channelId, out var msg)) - { + || this.Configuration.MessageCacheSize == 0 + || this.MessageCache == null + || !this.MessageCache.TryGet(xm => xm.Id == messageId && xm.ChannelId == channelId, out var msg)) msg = new() { - Id = messageId, - ChannelId = channelId, - Discord = this + Id = messageId, ChannelId = channelId, Discord = this }; - } if (!guild.EmojisInternal.TryGetValue(partialEmoji.Id, out var emoji)) { @@ -2660,18 +2705,15 @@ internal async Task OnMessageReactionRemoveEmojiAsync(ulong messageId, ulong cha var ea = new MessageReactionRemoveEmojiEventArgs(this.ServiceProvider) { - Channel = channel, - Guild = guild, - Message = msg, - Emoji = emoji + Channel = channel, Guild = guild, Message = msg, Emoji = emoji }; await this._messageReactionRemovedEmoji.InvokeAsync(this, ea).ConfigureAwait(false); } - #endregion +#endregion - #region Stage Instance +#region Stage Instance /// /// Handles the stage instance create event. @@ -2684,7 +2726,10 @@ internal async Task OnStageInstanceCreateEventAsync(DiscordStageInstance stage) var guild = this.InternalGetCachedGuild(stage.GuildId); guild.StageInstancesInternal[stage.Id] = stage; - await this._stageInstanceCreated.InvokeAsync(this, new(this.ServiceProvider) { StageInstance = stage, Guild = stage.Guild }).ConfigureAwait(false); + await this._stageInstanceCreated.InvokeAsync(this, new(this.ServiceProvider) + { + StageInstance = stage, Guild = stage.Guild + }).ConfigureAwait(false); } /// @@ -2697,7 +2742,10 @@ internal async Task OnStageInstanceUpdateEventAsync(DiscordStageInstance stage) var guild = this.InternalGetCachedGuild(stage.GuildId); guild.StageInstancesInternal[stage.Id] = stage; - await this._stageInstanceUpdated.InvokeAsync(this, new(this.ServiceProvider) { StageInstance = stage, Guild = stage.Guild }).ConfigureAwait(false); + await this._stageInstanceUpdated.InvokeAsync(this, new(this.ServiceProvider) + { + StageInstance = stage, Guild = stage.Guild + }).ConfigureAwait(false); } /// @@ -2710,12 +2758,15 @@ internal async Task OnStageInstanceDeleteEventAsync(DiscordStageInstance stage) var guild = this.InternalGetCachedGuild(stage.GuildId); guild.StageInstancesInternal[stage.Id] = stage; - await this._stageInstanceDeleted.InvokeAsync(this, new(this.ServiceProvider) { StageInstance = stage, Guild = stage.Guild }).ConfigureAwait(false); + await this._stageInstanceDeleted.InvokeAsync(this, new(this.ServiceProvider) + { + StageInstance = stage, Guild = stage.Guild + }).ConfigureAwait(false); } - #endregion +#endregion - #region Thread +#region Thread /// /// Handles the thread create event. @@ -2726,7 +2777,10 @@ internal async Task OnThreadCreateEventAsync(DiscordThreadChannel thread) thread.Discord = this; this.InternalGetCachedGuild(thread.GuildId).ThreadsInternal.AddOrUpdate(thread.Id, thread, (oldThread, newThread) => newThread); - await this._threadCreated.InvokeAsync(this, new(this.ServiceProvider) { Thread = thread, Guild = thread.Guild, Parent = thread.Parent }).ConfigureAwait(false); + await this._threadCreated.InvokeAsync(this, new(this.ServiceProvider) + { + Thread = thread, Guild = thread.Guild, Parent = thread.Parent + }).ConfigureAwait(false); } /// @@ -2798,19 +2852,14 @@ internal async Task OnThreadUpdateEventAsync(DiscordThreadChannel thread) updateEvent = new(this.ServiceProvider) { - ThreadAfter = thread, - ThreadBefore = threadOld, - Guild = thread.Guild, - Parent = thread.Parent + ThreadAfter = thread, ThreadBefore = threadOld, Guild = thread.Guild, Parent = thread.Parent }; } else { updateEvent = new(this.ServiceProvider) { - ThreadAfter = thread, - Guild = thread.Guild, - Parent = thread.Parent + ThreadAfter = thread, Guild = thread.Guild, Parent = thread.Parent }; guild.ThreadsInternal[thread.Id] = thread; } @@ -2833,7 +2882,10 @@ internal async Task OnThreadDeleteEventAsync(DiscordThreadChannel thread) if (gld.ThreadsInternal.TryRemove(thread.Id, out var cachedThread)) thread = cachedThread; - await this._threadDeleted.InvokeAsync(this, new(this.ServiceProvider) { Thread = thread, Guild = thread.Guild, Parent = thread.Parent, Type = thread.Type }).ConfigureAwait(false); + await this._threadDeleted.InvokeAsync(this, new(this.ServiceProvider) + { + Thread = thread, Guild = thread.Guild, Parent = thread.Parent, Type = thread.Type + }).ConfigureAwait(false); } /// @@ -2849,12 +2901,13 @@ internal async Task OnThreadListSyncEventAsync(DiscordGuild guild, IReadOnlyList var channels = channelIds.Select(x => guild.GetChannel(x.Value)); //getting channel objects foreach (var chan in channels) - { chan.Discord = this; - } _ = threads.Select(x => x.Discord = this); - await this._threadListSynced.InvokeAsync(this, new(this.ServiceProvider) { Guild = guild, Channels = channels.ToList().AsReadOnly(), Threads = threads, Members = members.ToList().AsReadOnly() }).ConfigureAwait(false); + await this._threadListSynced.InvokeAsync(this, new(this.ServiceProvider) + { + Guild = guild, Channels = channels.ToList().AsReadOnly(), Threads = threads, Members = members.ToList().AsReadOnly() + }).ConfigureAwait(false); } /// @@ -2874,8 +2927,10 @@ internal async Task OnThreadMemberUpdateEventAsync(DiscordThreadChannelMember me thread.CurrentMember = member; thread.Guild.ThreadsInternal.AddOrUpdate(member.Id, thread, (oldThread, newThread) => newThread); - - await this._threadMemberUpdated.InvokeAsync(this, new(this.ServiceProvider) { ThreadMember = member, Thread = thread }).ConfigureAwait(false); + await this._threadMemberUpdated.InvokeAsync(this, new(this.ServiceProvider) + { + ThreadMember = member, Thread = thread + }).ConfigureAwait(false); } /// @@ -2901,7 +2956,6 @@ internal async Task OnThreadMembersUpdateEventAsync(DiscordGuild guild, ulong th List removedMemberIds = new(); if (membersAdded != null) - { foreach (var xj in membersAdded) { var xtm = xj.ToDiscordObject(); @@ -2913,16 +2967,16 @@ internal async Task OnThreadMembersUpdateEventAsync(DiscordGuild guild, ulong th if (xtm.Id == this.CurrentUser.Id) thread.CurrentMember = xtm; } - } var removedMembers = new List(); if (membersRemoved != null) - { foreach (var removedId in membersRemoved) - { - removedMembers.Add(guild.MembersInternal.TryGetValue((ulong)removedId, out var member) ? member : new() { Id = (ulong)removedId, GuildId = guild.Id, Discord = this }); - } - } + removedMembers.Add(guild.MembersInternal.TryGetValue((ulong)removedId, out var member) + ? member + : new() + { + Id = (ulong)removedId, GuildId = guild.Id, Discord = this + }); if (removedMemberIds.Contains(this.CurrentUser.Id)) //indicates the bot was removed from the thread thread.CurrentMember = null; @@ -2941,9 +2995,10 @@ internal async Task OnThreadMembersUpdateEventAsync(DiscordGuild guild, ulong th await this._threadMembersUpdated.InvokeAsync(this, threadMembersUpdateArg).ConfigureAwait(false); } - #endregion +#endregion + +#region Activities - #region Activities /// /// Dispatches the event. /// @@ -3003,16 +3058,15 @@ internal async Task OnEmbeddedActivityUpdateAsync(JObject trActivity, DiscordGui } }*/ - #endregion +#endregion - #region User/Presence Update +#region User/Presence Update /// /// Handles the presence update event. /// /// The raw presence. /// The raw user. - internal async Task OnPresenceUpdateEventAsync(JObject rawPresence, JObject rawUser) { var uid = (ulong)rawUser["id"]!; @@ -3025,7 +3079,8 @@ internal async Task OnPresenceUpdateEventAsync(JObject rawPresence, JObject rawU } else { - presence = DiscordJson.DeserializeObject(rawPresence.ToString(), this); ; + presence = DiscordJson.DeserializeObject(rawPresence.ToString(), this); + ; presence.Discord = this; presence.Activity = new(presence.RawActivity); this.PresencesInternal[presence.InternalUser.Id] = presence; @@ -3033,9 +3088,7 @@ internal async Task OnPresenceUpdateEventAsync(JObject rawPresence, JObject rawU // reuse arrays / avoid linq (this is a hot zone) if (presence.Activities == null || rawPresence["activities"] == null) - { presence.InternalActivities = Array.Empty(); - } else { if (presence.InternalActivities.Length != presence.RawActivities.Length) @@ -3070,10 +3123,12 @@ internal async Task OnPresenceUpdateEventAsync(JObject rawPresence, JObject rawU /// Handles the user settings update event. /// /// The transport user. - internal async Task OnUserSettingsUpdateEventAsync(TransportUser user) { - var usr = new DiscordUser(user) { Discord = this }; + var usr = new DiscordUser(user) + { + Discord = this + }; var ea = new UserSettingsUpdateEventArgs(this.ServiceProvider) { @@ -3086,7 +3141,6 @@ internal async Task OnUserSettingsUpdateEventAsync(TransportUser user) /// Handles the user update event. /// /// The transport user. - internal async Task OnUserUpdateEventAsync(TransportUser user) { var usrOld = new DiscordUser @@ -3113,21 +3167,19 @@ internal async Task OnUserUpdateEventAsync(TransportUser user) var ea = new UserUpdateEventArgs(this.ServiceProvider) { - UserAfter = this.CurrentUser, - UserBefore = usrOld + UserAfter = this.CurrentUser, UserBefore = usrOld }; await this._userUpdated.InvokeAsync(this, ea).ConfigureAwait(false); } - #endregion +#endregion - #region Voice +#region Voice /// /// Handles the voice state update event. /// /// The raw voice state update object. - internal async Task OnVoiceStateUpdateEventAsync(JObject raw) { var gid = (ulong)raw["guild_id"]; @@ -3140,9 +3192,7 @@ internal async Task OnVoiceStateUpdateEventAsync(JObject raw) gld.VoiceStatesInternal.TryRemove(uid, out var vstateOld); if (vstateNew.Channel != null) - { gld.VoiceStatesInternal[vstateNew.UserId] = vstateNew; - } if (gld.MembersInternal.TryGetValue(uid, out var mbr)) { @@ -3152,7 +3202,10 @@ internal async Task OnVoiceStateUpdateEventAsync(JObject raw) else { var transportMbr = vstateNew.TransportMember; - this.UpdateUser(new(transportMbr.User) { Discord = this }, gid, gld, transportMbr); + this.UpdateUser(new(transportMbr.User) + { + Discord = this + }, gid, gld, transportMbr); } var ea = new VoiceStateUpdateEventArgs(this.ServiceProvider) @@ -3161,7 +3214,6 @@ internal async Task OnVoiceStateUpdateEventAsync(JObject raw) Channel = vstateNew.Channel, User = vstateNew.User, SessionId = vstateNew.SessionId, - Before = vstateOld, After = vstateNew }; @@ -3174,28 +3226,24 @@ internal async Task OnVoiceStateUpdateEventAsync(JObject raw) /// The new endpoint. /// The new token. /// The guild. - internal async Task OnVoiceServerUpdateEventAsync(string endpoint, string token, DiscordGuild guild) { var ea = new VoiceServerUpdateEventArgs(this.ServiceProvider) { - Endpoint = endpoint, - VoiceToken = token, - Guild = guild + Endpoint = endpoint, VoiceToken = token, Guild = guild }; await this._voiceServerUpdated.InvokeAsync(this, ea).ConfigureAwait(false); } - #endregion +#endregion - #region Commands +#region Commands /// /// Handles the application command create event. /// /// The application command. /// The optional guild id. - internal async Task OnApplicationCommandCreateAsync(DiscordApplicationCommand cmd, ulong? guildId) { cmd.Discord = this; @@ -3203,18 +3251,14 @@ internal async Task OnApplicationCommandCreateAsync(DiscordApplicationCommand cm var guild = this.InternalGetCachedGuild(guildId); if (guild == null && guildId.HasValue) - { guild = new() { - Id = guildId.Value, - Discord = this + Id = guildId.Value, Discord = this }; - } var ea = new ApplicationCommandEventArgs(this.ServiceProvider) { - Guild = guild, - Command = cmd + Guild = guild, Command = cmd }; await this._applicationCommandCreated.InvokeAsync(this, ea).ConfigureAwait(false); @@ -3225,7 +3269,6 @@ internal async Task OnApplicationCommandCreateAsync(DiscordApplicationCommand cm /// /// The application command. /// The optional guild id. - internal async Task OnApplicationCommandUpdateAsync(DiscordApplicationCommand cmd, ulong? guildId) { cmd.Discord = this; @@ -3233,18 +3276,14 @@ internal async Task OnApplicationCommandUpdateAsync(DiscordApplicationCommand cm var guild = this.InternalGetCachedGuild(guildId); if (guild == null && guildId.HasValue) - { guild = new() { - Id = guildId.Value, - Discord = this + Id = guildId.Value, Discord = this }; - } var ea = new ApplicationCommandEventArgs(this.ServiceProvider) { - Guild = guild, - Command = cmd + Guild = guild, Command = cmd }; await this._applicationCommandUpdated.InvokeAsync(this, ea).ConfigureAwait(false); @@ -3255,7 +3294,6 @@ internal async Task OnApplicationCommandUpdateAsync(DiscordApplicationCommand cm /// /// The application command. /// The optional guild id. - internal async Task OnApplicationCommandDeleteAsync(DiscordApplicationCommand cmd, ulong? guildId) { cmd.Discord = this; @@ -3263,18 +3301,14 @@ internal async Task OnApplicationCommandDeleteAsync(DiscordApplicationCommand cm var guild = this.InternalGetCachedGuild(guildId); if (guild == null && guildId.HasValue) - { guild = new() { - Id = guildId.Value, - Discord = this + Id = guildId.Value, Discord = this }; - } var ea = new ApplicationCommandEventArgs(this.ServiceProvider) { - Guild = guild, - Command = cmd + Guild = guild, Command = cmd }; await this._applicationCommandDeleted.InvokeAsync(this, ea).ConfigureAwait(false); @@ -3292,15 +3326,11 @@ internal async Task OnGuildApplicationCommandCountsUpdateAsync(int chatInputComm { var guild = this.InternalGetCachedGuild(guildId) ?? new DiscordGuild { - Id = guildId, - Discord = this + Id = guildId, Discord = this }; var ea = new GuildApplicationCommandCountEventArgs(this.ServiceProvider) { - SlashCommands = chatInputCommandCount, - UserContextMenuCommands = userContextMenuCommandCount, - MessageContextMenuCommands = messageContextMenuCount, - Guild = guild + SlashCommands = chatInputCommandCount, UserContextMenuCommands = userContextMenuCommandCount, MessageContextMenuCommands = messageContextMenuCount, Guild = guild }; await this._guildApplicationCommandCountUpdated.InvokeAsync(this, ea).ConfigureAwait(false); @@ -3331,28 +3361,22 @@ internal async Task OnApplicationCommandPermissionsUpdateAsync(IEnumerable /// Handles the interaction create event. @@ -3371,7 +3395,11 @@ internal async Task OnInteractionCreateAsync(ulong? guildId, ulong channelId, Tr //this.Logger.LogDebug("Interaction from {guild} on shard {shard}", guildId.HasValue ? guildId.Value : "dm", this.ShardId); //this.Logger.LogDebug("Interaction: {interaction}", rawInteraction); } - var usr = new DiscordUser(user) { Discord = this }; + + var usr = new DiscordUser(user) + { + Discord = this + }; interaction.ChannelId = channelId; interaction.GuildId = guildId; @@ -3380,13 +3408,14 @@ internal async Task OnInteractionCreateAsync(ulong? guildId, ulong channelId, Tr if (member != null) { - usr = new DiscordMember(member) { GuildId = guildId.Value, Discord = this }; + usr = new DiscordMember(member) + { + GuildId = guildId.Value, Discord = this + }; this.UpdateUser(usr, guildId, interaction.Guild, member); } else - { this.UserCache.AddOrUpdate(usr.Id, usr, (old, @new) => @new); - } usr.Locale = interaction.Locale; interaction.User = usr; @@ -3395,16 +3424,13 @@ internal async Task OnInteractionCreateAsync(ulong? guildId, ulong channelId, Tr if (resolved != null) { if (resolved.Users != null) - { foreach (var c in resolved.Users) { c.Value.Discord = this; this.UserCache.AddOrUpdate(c.Value.Id, c.Value, (old, @new) => @new); } - } if (resolved.Members != null) - { foreach (var c in resolved.Members) { c.Value.Discord = this; @@ -3413,10 +3439,8 @@ internal async Task OnInteractionCreateAsync(ulong? guildId, ulong channelId, Tr c.Value.User.Discord = this; this.UserCache.AddOrUpdate(c.Value.User.Id, c.Value.User, (old, @new) => @new); } - } if (resolved.Channels != null) - { foreach (var c in resolved.Channels) { c.Value.Discord = this; @@ -3433,10 +3457,8 @@ internal async Task OnInteractionCreateAsync(ulong? guildId, ulong channelId, Tr catch (Exception) { } } } - } if (resolved.Roles != null) - { foreach (var c in resolved.Roles) { c.Value.Discord = this; @@ -3444,11 +3466,8 @@ internal async Task OnInteractionCreateAsync(ulong? guildId, ulong channelId, Tr if (guildId.HasValue) c.Value.GuildId = guildId.Value; } - } - if (resolved.Messages != null) - { foreach (var m in resolved.Messages) { m.Value.Discord = this; @@ -3456,8 +3475,6 @@ internal async Task OnInteractionCreateAsync(ulong? guildId, ulong channelId, Tr if (guildId.HasValue) m.Value.GuildId = guildId.Value; } - } - if (resolved.Attachments != null) foreach (var a in resolved.Attachments) @@ -3471,10 +3488,10 @@ internal async Task OnInteractionCreateAsync(ulong? guildId, ulong channelId, Tr interaction.Message.Discord = this; interaction.Message.ChannelId = interaction.ChannelId; } + var cea = new ComponentInteractionCreateEventArgs(this.ServiceProvider) { - Message = interaction.Message, - Interaction = interaction + Message = interaction.Message, Interaction = interaction }; await this._componentInteractionCreated.InvokeAsync(this, cea).ConfigureAwait(false); @@ -3494,10 +3511,7 @@ internal async Task OnInteractionCreateAsync(ulong? guildId, ulong channelId, Tr var ea = new ContextMenuInteractionCreateEventArgs(this.ServiceProvider) { - Interaction = interaction, - TargetUser = targetMember ?? targetUser, - TargetMessage = targetMessage, - Type = interaction.Data.Type + Interaction = interaction, TargetUser = targetMember ?? targetUser, TargetMessage = targetMessage, Type = interaction.Data.Type }; await this._contextMenuInteractionCreated.InvokeAsync(this, ea).ConfigureAwait(false); } @@ -3513,9 +3527,9 @@ internal async Task OnInteractionCreateAsync(ulong? guildId, ulong channelId, Tr } } - #endregion +#endregion - #region Misc +#region Misc /// /// Handles the entitlement create event. @@ -3556,65 +3570,63 @@ internal async Task OnEntitlementDeleteAsync(DiscordEntitlement entitlement) await this._entitlementDeleted.InvokeAsync(this, ea).ConfigureAwait(false); } - /// - /// Handles the typing start event. - /// - /// The user id. - /// The channel id. - /// The channel. - /// The optional guild id. - /// The time when the user started typing. - /// The transport member. - internal async Task OnTypingStartEventAsync(ulong userId, ulong channelId, DiscordChannel channel, ulong? guildId, DateTimeOffset started, TransportMember mbr) - { - if (channel == null) - { - channel = new() - { - Discord = this, - Id = channelId, - GuildId = guildId ?? default, - }; - } - - var guild = this.InternalGetCachedGuild(guildId); - var usr = this.UpdateUser(new() { Id = userId, Discord = this }, guildId, guild, mbr); - var ea = new TypingStartEventArgs(this.ServiceProvider) + /// + /// Handles the typing start event. + /// + /// The user id. + /// The channel id. + /// The channel. + /// The optional guild id. + /// The time when the user started typing. + /// The transport member. + internal async Task OnTypingStartEventAsync(ulong userId, ulong channelId, DiscordChannel channel, ulong? guildId, DateTimeOffset started, TransportMember mbr) + { + if (channel == null) + channel = new() { - Channel = channel, - User = usr, - Guild = guild, - StartedAt = started + Discord = this, Id = channelId, GuildId = guildId ?? default }; - await this._typingStarted.InvokeAsync(this, ea).ConfigureAwait(false); - } - /// - /// Handles the webhooks update. - /// - /// The channel. - /// The guild. - internal async Task OnWebhooksUpdateAsync(DiscordChannel channel, DiscordGuild guild) + var guild = this.InternalGetCachedGuild(guildId); + var usr = this.UpdateUser(new() { - var ea = new WebhooksUpdateEventArgs(this.ServiceProvider) - { - Channel = channel, - Guild = guild - }; - await this._webhooksUpdated.InvokeAsync(this, ea).ConfigureAwait(false); - } + Id = userId, Discord = this + }, guildId, guild, mbr); + var ea = new TypingStartEventArgs(this.ServiceProvider) + { + Channel = channel, User = usr, Guild = guild, StartedAt = started + }; + await this._typingStarted.InvokeAsync(this, ea).ConfigureAwait(false); + } - /// - /// Handles all unknown events. - /// - /// The payload. - internal async Task OnUnknownEventAsync(GatewayPayload payload) + /// + /// Handles the webhooks update. + /// + /// The channel. + /// The guild. + internal async Task OnWebhooksUpdateAsync(DiscordChannel channel, DiscordGuild guild) + { + var ea = new WebhooksUpdateEventArgs(this.ServiceProvider) { - var ea = new UnknownEventArgs(this.ServiceProvider) { EventName = payload.EventName, Json = (payload.Data as JObject)?.ToString() }; - await this._unknownEvent.InvokeAsync(this, ea).ConfigureAwait(false); - } + Channel = channel, Guild = guild + }; + await this._webhooksUpdated.InvokeAsync(this, ea).ConfigureAwait(false); + } + + /// + /// Handles all unknown events. + /// + /// The payload. + internal async Task OnUnknownEventAsync(GatewayPayload payload) + { + var ea = new UnknownEventArgs(this.ServiceProvider) + { + EventName = payload.EventName, Json = (payload.Data as JObject)?.ToString() + }; + await this._unknownEvent.InvokeAsync(this, ea).ConfigureAwait(false); + } - #endregion +#endregion - #endregion +#endregion } diff --git a/DisCatSharp/Entities/Guild/DiscordAuditLogObjects.cs b/DisCatSharp/Entities/Guild/DiscordAuditLogObjects.cs deleted file mode 100644 index 89cda0ffb..000000000 --- a/DisCatSharp/Entities/Guild/DiscordAuditLogObjects.cs +++ /dev/null @@ -1,831 +0,0 @@ -using System; -using System.Collections.Generic; - -using DisCatSharp.Enums; - -namespace DisCatSharp.Entities; - -/// -/// Represents an audit log entry. -/// -public abstract class DiscordAuditLogEntry : SnowflakeObject -{ - /// - /// Gets the entry's action type. - /// - public AuditLogActionType ActionType { get; internal set; } - - /// - /// Gets the user responsible for the action. - /// - public DiscordUser UserResponsible { get; internal set; } - - /// - /// Gets the reason defined in the action. - /// - public string Reason { get; internal set; } - - /// - /// Gets the category under which the action falls. - /// - public AuditLogActionCategory ActionCategory { get; internal set; } -} - -/// -/// Represents a description of how a property changed. -/// -/// Type of the changed property. -public sealed class PropertyChange -{ - /// - /// The property's value before it was changed. - /// - public T Before { get; internal set; } - - /// - /// The property's value after it was changed. - /// - public T After { get; internal set; } -} - -/// -/// Represents a audit log guild entry. -/// -public sealed class DiscordAuditLogGuildEntry : DiscordAuditLogEntry -{ - /// - /// Gets the affected guild. - /// - public DiscordGuild Target { get; internal set; } - - /// - /// Gets the name change. - /// - public PropertyChange NameChange { get; internal set; } - - /// - /// Gets the owner change. - /// - public PropertyChange OwnerChange { get; internal set; } - - /// - /// Gets the icon change. - /// - public PropertyChange IconChange { get; internal set; } - - /// - /// Gets the verification level change. - /// - public PropertyChange VerificationLevelChange { get; internal set; } - - /// - /// Gets the afk channel change. - /// - public PropertyChange AfkChannelChange { get; internal set; } - - /// - /// Gets the system channel flags change. - /// - public PropertyChange SystemChannelFlagsChange { get; internal set; } - - /// - /// - /// - public PropertyChange WidgetChannelChange { get; internal set; } - - /// - /// - /// - public PropertyChange RulesChannelChange { get; internal set; } - - /// - /// - /// - public PropertyChange PublicUpdatesChannelChange { get; internal set; } - - /// - /// - /// - public PropertyChange NotificationSettingsChange { get; internal set; } - - /// - /// - /// - public PropertyChange SystemChannelChange { get; internal set; } - - /// - /// - /// - public PropertyChange ExplicitContentFilterChange { get; internal set; } - - /// - /// - /// - public PropertyChange MfaLevelChange { get; internal set; } - - /// - /// - /// - public PropertyChange SplashChange { get; internal set; } - - /// - /// - /// - public PropertyChange RegionChange { get; internal set; } - - /// - /// - /// - public PropertyChange VanityUrlCodeChange { get; internal set; } - - /// - /// - /// - public PropertyChange PremiumProgressBarChange { get; internal set; } - - /// - /// Initializes a new instance of the class. - /// - internal DiscordAuditLogGuildEntry() { } -} - -/// -/// Represents a audit log channel entry. -/// -public sealed class DiscordAuditLogChannelEntry : DiscordAuditLogEntry -{ - /// - /// Gets the affected channel. - /// - public DiscordChannel Target { get; internal set; } - - /// - /// Gets the description of channel's name change. - /// - public PropertyChange NameChange { get; internal set; } - - /// - /// Gets the description of channel's type change. - /// - public PropertyChange TypeChange { get; internal set; } - - /// - /// Gets the description of channel's nsfw flag change. - /// - public PropertyChange NsfwChange { get; internal set; } - - /// - /// Gets the rtc region id change. - /// - public PropertyChange RtcRegionIdChange { get; internal set; } - - /// - /// Gets the description of channel's bitrate change. - /// - public PropertyChange BitrateChange { get; internal set; } - - /// - /// Gets the description of channel permission overwrites' change. - /// - public PropertyChange> OverwriteChange { get; internal set; } - - /// - /// Gets the description of channel's topic change. - /// - public PropertyChange TopicChange { get; internal set; } - - /// - /// Gets the user limit change. - /// - public PropertyChange UserLimitChange { get; internal set; } - - /// - /// Gets the description of channel's slow mode timeout change. - /// - public PropertyChange PerUserRateLimitChange { get; internal set; } - - /// - /// Gets the channel flags change. - /// - public PropertyChange ChannelFlagsChange { get; internal set; } - - /// - /// Gets the default auto archive duration change. - /// - public PropertyChange DefaultAutoArchiveDurationChange { get; internal set; } - - /// - /// Gets the default available tags change. - /// - public PropertyChange> AvailableTagsChange { get; internal set; } - - /// - /// Initializes a new instance of the class. - /// - internal DiscordAuditLogChannelEntry() { } -} - -/// -/// Represents a audit log overwrite entry. -/// -public sealed class DiscordAuditLogOverwriteEntry : DiscordAuditLogEntry -{ - /// - /// Gets the affected overwrite. - /// - public DiscordOverwrite Target { get; internal set; } - - /// - /// Gets the channel for which the overwrite was changed. - /// - public DiscordChannel Channel { get; internal set; } - - /// - /// Gets the description of overwrite's allow value change. - /// - public PropertyChange AllowChange { get; internal set; } - - /// - /// Gets the description of overwrite's deny value change. - /// - public PropertyChange DenyChange { get; internal set; } - - /// - /// Gets the description of overwrite's type change. - /// - public PropertyChange TypeChange { get; internal set; } - - /// - /// Gets the description of overwrite's target id change. - /// - public PropertyChange TargetIdChange { get; internal set; } - - /// - /// Initializes a new instance of the class. - /// - internal DiscordAuditLogOverwriteEntry() { } -} - -/// -/// Represents a audit log kick entry. -/// -public sealed class DiscordAuditLogKickEntry : DiscordAuditLogEntry -{ - /// - /// Gets the kicked member. - /// - public DiscordMember Target { get; internal set; } - - /// - /// Initializes a new instance of the class. - /// - internal DiscordAuditLogKickEntry() { } -} - -/// -/// Represents a audit log prune entry. -/// -public sealed class DiscordAuditLogPruneEntry : DiscordAuditLogEntry -{ - /// - /// Gets the number inactivity days after which members were pruned. - /// - public int Days { get; internal set; } - - /// - /// Gets the number of members pruned. - /// - public int Toll { get; internal set; } - - /// - /// Initializes a new instance of the class. - /// - internal DiscordAuditLogPruneEntry() { } -} - -/// -/// Represents a audit log ban entry. -/// -public sealed class DiscordAuditLogBanEntry : DiscordAuditLogEntry -{ - /// - /// Gets the banned member. - /// - public DiscordMember Target { get; internal set; } - - /// - /// Initializes a new instance of the class. - /// - internal DiscordAuditLogBanEntry() { } -} - -/// -/// Represents a audit log member update entry. -/// -public sealed class DiscordAuditLogMemberUpdateEntry : DiscordAuditLogEntry -{ - /// - /// Gets the affected member. - /// - public DiscordMember Target { get; internal set; } - - /// - /// Gets the description of member's nickname change. - /// - public PropertyChange NicknameChange { get; internal set; } - - /// - /// Gets the roles that were removed from the member. - /// - public IReadOnlyList RemovedRoles { get; internal set; } - - /// - /// Gets the roles that were added to the member. - /// - public IReadOnlyList AddedRoles { get; internal set; } - - /// - /// Gets the description of member's mute status change. - /// - public PropertyChange MuteChange { get; internal set; } - - /// - /// Gets the description of member's deaf status change. - /// - public PropertyChange DeafenChange { get; internal set; } - - /// - /// Get's the timeout change. - /// - public PropertyChange CommunicationDisabledUntilChange { get; internal set; } - - /// - /// Initializes a new instance of the class. - /// - internal DiscordAuditLogMemberUpdateEntry() { } -} - -/// -/// Represents a audit log role update entry. -/// -public sealed class DiscordAuditLogRoleUpdateEntry : DiscordAuditLogEntry -{ - /// - /// Gets the affected role. - /// - public DiscordRole Target { get; internal set; } - - /// - /// Gets the description of role's name change. - /// - public PropertyChange NameChange { get; internal set; } - - /// - /// Gets the description of role's color change. - /// - public PropertyChange ColorChange { get; internal set; } - - /// - /// Gets the description of role's permission set change. - /// - public PropertyChange PermissionChange { get; internal set; } - - /// - /// Gets the description of the role's position change. - /// - public PropertyChange PositionChange { get; internal set; } - - /// - /// Gets the description of the role's mentionability change. - /// - public PropertyChange MentionableChange { get; internal set; } - - /// - /// Gets the description of the role's hoist status change. - /// - public PropertyChange HoistChange { get; internal set; } - - /// - /// Gets the role icon hash change. - /// - public PropertyChange IconHashChange { get; internal set; } - - /// - /// Initializes a new instance of the class. - /// - internal DiscordAuditLogRoleUpdateEntry() { } -} - -/// -/// Represents a audit log invite entry. -/// -public sealed class DiscordAuditLogInviteEntry : DiscordAuditLogEntry -{ - /// - /// Gets the affected invite. - /// - public DiscordInvite Target { get; internal set; } - - /// - /// Gets the description of invite's max age change. - /// - public PropertyChange MaxAgeChange { get; internal set; } - - /// - /// Gets the description of invite's code change. - /// - public PropertyChange CodeChange { get; internal set; } - - /// - /// Gets the description of invite's temporariness change. - /// - public PropertyChange TemporaryChange { get; internal set; } - - /// - /// Gets the description of invite's inviting member change. - /// - public PropertyChange InviterChange { get; internal set; } - - /// - /// Gets the description of invite's target channel change. - /// - public PropertyChange ChannelChange { get; internal set; } - - /// - /// Gets the description of invite's use count change. - /// - public PropertyChange UsesChange { get; internal set; } - - /// - /// Gets the description of invite's max use count change. - /// - public PropertyChange MaxUsesChange { get; internal set; } - - /// - /// Initializes a new instance of the class. - /// - internal DiscordAuditLogInviteEntry() { } -} - -/// -/// Represents a audit log webhook entry. -/// -public sealed class DiscordAuditLogWebhookEntry : DiscordAuditLogEntry -{ - /// - /// Gets the affected webhook. - /// - public DiscordWebhook Target { get; internal set; } - - /// - /// Undocumented. - /// - public PropertyChange IdChange { get; internal set; } - - /// - /// Gets the description of webhook's name change. - /// - public PropertyChange NameChange { get; internal set; } - - /// - /// Gets the description of webhook's target channel change. - /// - public PropertyChange ChannelChange { get; internal set; } - - /// - /// Gets the description of webhook's type change. - /// - public PropertyChange TypeChange { get; internal set; } - - /// - /// Gets the description of webhook's avatar change. - /// - public PropertyChange AvatarHashChange { get; internal set; } - - /// - /// Initializes a new instance of the class. - /// - internal DiscordAuditLogWebhookEntry() { } -} - -/// -/// Represents a audit log emoji entry. -/// -public sealed class DiscordAuditLogEmojiEntry : DiscordAuditLogEntry -{ - /// - /// Gets the affected emoji. - /// - public DiscordEmoji Target { get; internal set; } - - /// - /// Gets the description of emoji's name change. - /// - public PropertyChange NameChange { get; internal set; } - - /// - /// Initializes a new instance of the class. - /// - internal DiscordAuditLogEmojiEntry() { } -} - -/// -/// Represents a audit log sticker entry. -/// -public sealed class DiscordAuditLogStickerEntry : DiscordAuditLogEntry -{ - /// - /// Gets the affected sticker. - /// - public DiscordSticker Target { get; internal set; } - - /// - /// Gets the description of sticker's name change. - /// - public PropertyChange NameChange { get; internal set; } - - /// - /// Gets the description of sticker's description change. - /// - public PropertyChange DescriptionChange { get; internal set; } - - /// - /// Gets the description of sticker's tags change. - /// - public PropertyChange TagsChange { get; internal set; } - - /// - /// Gets the description of sticker's tags change. - /// - public PropertyChange AssetChange { get; internal set; } - - /// - /// Gets the description of sticker's guild id change. - /// - public PropertyChange GuildIdChange { get; internal set; } - - /// - /// Gets the description of sticker's availability change. - /// - public PropertyChange AvailabilityChange { get; internal set; } - - /// - /// Gets the description of sticker's id change. - /// - public PropertyChange IdChange { get; internal set; } - - /// - /// Gets the description of sticker's type change. - /// - public PropertyChange TypeChange { get; internal set; } - - /// - /// Gets the description of sticker's format change. - /// - public PropertyChange FormatChange { get; internal set; } - - /// - /// Initializes a new instance of the class. - /// - internal DiscordAuditLogStickerEntry() { } -} - -/// -/// Represents a audit log message entry. -/// -public sealed class DiscordAuditLogMessageEntry : DiscordAuditLogEntry -{ - /// - /// Gets the affected message. Note that more often than not, this will only have ID specified. - /// - public DiscordMessage Target { get; internal set; } - - /// - /// Gets the channel in which the action occurred. - /// - public DiscordChannel Channel { get; internal set; } - - /// - /// Gets the number of messages that were affected. - /// - public int? MessageCount { get; internal set; } - - /// - /// Initializes a new instance of the class. - /// - internal DiscordAuditLogMessageEntry() { } -} - -/// -/// Represents a audit log message pin entry. -/// -public sealed class DiscordAuditLogMessagePinEntry : DiscordAuditLogEntry -{ - /// - /// Gets the affected message's user. - /// - public DiscordUser Target { get; internal set; } - - /// - /// Gets the channel the message is in. - /// - public DiscordChannel Channel { get; internal set; } - - /// - /// Gets the message the pin action was for. - /// - public DiscordMessage Message { get; internal set; } - - /// - /// Initializes a new instance of the class. - /// - internal DiscordAuditLogMessagePinEntry() { } -} - -/// -/// Represents a audit log bot add entry. -/// -public sealed class DiscordAuditLogBotAddEntry : DiscordAuditLogEntry -{ - /// - /// Gets the bot that has been added to the guild. - /// - public DiscordUser TargetBot { get; internal set; } -} - -/// -/// Represents a audit log member move entry. -/// -public sealed class DiscordAuditLogMemberMoveEntry : DiscordAuditLogEntry -{ - /// - /// Gets the channel the members were moved in. - /// - public DiscordChannel Channel { get; internal set; } - - /// - /// Gets the amount of users that were moved out from the voice channel. - /// - public int UserCount { get; internal set; } -} - -/// -/// Represents a audit log member disconnect entry. -/// -public sealed class DiscordAuditLogMemberDisconnectEntry : DiscordAuditLogEntry -{ - /// - /// Gets the amount of users that were disconnected from the voice channel. - /// - public int UserCount { get; internal set; } -} - -/// -/// Represents a audit log integration entry. -/// -public sealed class DiscordAuditLogIntegrationEntry : DiscordAuditLogEntry -{ - /// - /// The type of integration. - /// - public PropertyChange Type { get; internal set; } - - /// - /// Gets the description of emoticons' change. - /// - public PropertyChange EnableEmoticons { get; internal set; } - - /// - /// Gets the description of expire grace period's change. - /// - public PropertyChange ExpireGracePeriod { get; internal set; } - - /// - /// Gets the description of expire behavior change. - /// - public PropertyChange ExpireBehavior { get; internal set; } -} - -/// -/// Represents a audit log stage entry. -/// -public sealed class DiscordAuditLogStageEntry : DiscordAuditLogEntry -{ - /// - /// Gets the affected stage instance - /// - public DiscordStageInstance Target { get; internal set; } - - /// - /// Gets the description of stage instance's topic change. - /// - public PropertyChange TopicChange { get; internal set; } - - /// - /// Initializes a new instance of the class. - /// - internal DiscordAuditLogStageEntry() { } -} - -/// -/// Represents a audit log event entry. -/// -public sealed class DiscordAuditLogGuildScheduledEventEntry : DiscordAuditLogEntry -{ - /// - /// Gets the affected event - /// - public DiscordScheduledEvent Target { get; internal set; } - - /// - /// Gets the channel change. - /// - public PropertyChange ChannelIdChange { get; internal set; } - - /// - /// Gets the name change. - /// - public PropertyChange NameChange { get; internal set; } - - /// - /// Gets the description change. - /// - public PropertyChange DescriptionChange { get; internal set; } - - /* Will be added https://github.com/discord/discord-api-docs/pull/3586#issuecomment-969137241 - public PropertyChange<> ScheduledStartTimeChange { get; internal set; } - - public PropertyChange<> ScheduledEndTimeChange { get; internal set; } - */ - - /// - /// Gets the location change. - /// - public PropertyChange LocationChange { get; internal set; } - - /// - /// Gets the status change. - /// - public PropertyChange StatusChange { get; internal set; } - - /// - /// Gets the entity type change. - /// - public PropertyChange EntityTypeChange { get; internal set; } - - /// - /// Initializes a new instance of the class. - /// - internal DiscordAuditLogGuildScheduledEventEntry() { } -} - -/// -/// Represents a audit log thread entry. -/// -public sealed class DiscordAuditLogThreadEntry : DiscordAuditLogEntry -{ - /// - /// Gets the affected thread - /// - public DiscordThreadChannel Target { get; internal set; } - - /// - /// Gets the name of the thread. - /// - public PropertyChange NameChange { get; internal set; } - - /// - /// Gets the type of the thread. - /// - public PropertyChange TypeChange { get; internal set; } - - /// - /// Gets the archived state of the thread. - /// - public PropertyChange ArchivedChange { get; internal set; } - - /// - /// Gets the locked state of the thread. - /// - public PropertyChange LockedChange { get; internal set; } - - /// - /// Gets the invitable state of the thread. - /// - public PropertyChange InvitableChange { get; internal set; } - - /// - /// Gets the new auto archive duration of the thread. - /// - public PropertyChange AutoArchiveDurationChange { get; internal set; } - - /// - /// Gets the new ratelimit of the thread. - /// - public PropertyChange PerUserRateLimitChange { get; internal set; } - - /// - /// Initializes a new instance of the class. - /// - internal DiscordAuditLogThreadEntry() { } -} diff --git a/DisCatSharp/Entities/Guild/DiscordGuild.AuditLog.cs b/DisCatSharp/Entities/Guild/DiscordGuild.AuditLog.cs deleted file mode 100644 index e3c780d3f..000000000 --- a/DisCatSharp/Entities/Guild/DiscordGuild.AuditLog.cs +++ /dev/null @@ -1,1351 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Globalization; -using System.Linq; -using System.Threading.Tasks; - -using DisCatSharp.Enums; -using DisCatSharp.Exceptions; -using DisCatSharp.Net; -using DisCatSharp.Net.Abstractions; - -using Microsoft.Extensions.Logging; - -using Newtonsoft.Json.Linq; - -namespace DisCatSharp.Entities; - -public partial class DiscordGuild -{ - // TODO: Rework audit logs! - - /// - /// Gets audit log entries for this guild. - /// - /// Maximum number of entries to fetch. - /// Filter by member responsible. - /// Filter by action type. - /// A collection of requested audit log entries. - /// Thrown when the client does not have the permission. - /// Thrown when Discord is unable to process the request. - public async Task> GetAuditLogsAsync(int? limit = null, DiscordMember byMember = null, AuditLogActionType? actionType = null) - { - var alrs = new List(); - int ac = 1, tc = 0, rmn = 100; - var last = 0ul; - while (ac > 0) - { - rmn = limit != null ? limit.Value - tc : 100; - rmn = Math.Min(100, rmn); - if (rmn <= 0) break; - - var alr = await this.Discord.ApiClient.GetAuditLogsAsync(this.Id, rmn, null, last == 0 ? null : last, byMember?.Id, (int?)actionType).ConfigureAwait(false); - ac = alr.Entries.Count; - tc += ac; - if (ac > 0) - { - last = alr.Entries[alr.Entries.Count - 1].Id; - alrs.Add(alr); - } - } - - var auditLogResult = await this.ProcessAuditLog(alrs).ConfigureAwait(false); - return auditLogResult; - } - - /// - /// Proceesses audit log objects. - /// - /// A list of raw audit log objects. - /// The processed audit log list as readonly. - internal async Task> ProcessAuditLog(List auditLogApiResult) - { - List amr = new(); - if (auditLogApiResult.Any(ar => ar.Users != null && ar.Users.Any())) - amr = auditLogApiResult.SelectMany(xa => xa.Users) - .GroupBy(xu => xu.Id) - .Select(xgu => xgu.First()).ToList(); - - if (amr.Any()) - foreach (var xau in amr) - { - if (this.Discord.UserCache.ContainsKey(xau.Id)) - continue; - - var xtu = new TransportUser - { - Id = xau.Id, - Username = xau.Username, - Discriminator = xau.Discriminator, - AvatarHash = xau.AvatarHash - }; - var xu = new DiscordUser(xtu) { Discord = this.Discord }; - xu = this.Discord.UserCache.AddOrUpdate(xu.Id, xu, (id, old) => - { - old.Username = xu.Username; - old.Discriminator = xu.Discriminator; - old.AvatarHash = xu.AvatarHash; - old.GlobalName = xu.GlobalName; - return old; - }); - } - - List atgse = new(); - if (auditLogApiResult.Any(ar => ar.ScheduledEvents != null && ar.ScheduledEvents.Any())) - atgse = auditLogApiResult.SelectMany(xa => xa.ScheduledEvents) - .GroupBy(xse => xse.Id) - .Select(xgse => xgse.First()).ToList(); - - List ath = new(); - if (auditLogApiResult.Any(ar => ar.Threads != null && ar.Threads.Any())) - ath = auditLogApiResult.SelectMany(xa => xa.Threads) - .GroupBy(xt => xt.Id) - .Select(xgt => xgt.First()).ToList(); - - List aig = new(); - if (auditLogApiResult.Any(ar => ar.Integrations != null && ar.Integrations.Any())) - aig = auditLogApiResult.SelectMany(xa => xa.Integrations) - .GroupBy(xi => xi.Id) - .Select(xgi => xgi.First()).ToList(); - - List ahr = new(); - if (auditLogApiResult.Any(ar => ar.Webhooks != null && ar.Webhooks.Any())) - ahr = auditLogApiResult.SelectMany(xa => xa.Webhooks) - .GroupBy(xh => xh.Id) - .Select(xgh => xgh.First()).ToList(); - - List ams = new(); - Dictionary amd = new(); - if (amr.Any()) - ams = amr.Select(xau => this.MembersInternal != null && this.MembersInternal.TryGetValue(xau.Id, out var member) ? member : new() { Discord = this.Discord, Id = xau.Id, GuildId = this.Id }).ToList(); - if (ams.Any()) - amd = ams.ToDictionary(xm => xm.Id, xm => xm); - -#pragma warning disable CS0219 - Dictionary dtc = null; - Dictionary di = null; - Dictionary dse = null; -#pragma warning restore - - Dictionary ahd = null; - if (ahr.Any()) - { - var whr = await this.GetWebhooksAsync().ConfigureAwait(false); - var whs = whr.ToDictionary(xh => xh.Id, xh => xh); - - var amh = ahr.Select(xah => whs.TryGetValue(xah.Id, out var webhook) ? webhook : new() { Discord = this.Discord, Name = xah.Name, Id = xah.Id, AvatarHash = xah.AvatarHash, ChannelId = xah.ChannelId, GuildId = xah.GuildId, Token = xah.Token }); - ahd = amh.ToDictionary(xh => xh.Id, xh => xh); - } - - var acs = auditLogApiResult.SelectMany(xa => xa.Entries).OrderByDescending(xa => xa.Id); - var entries = new List(); - foreach (var xac in acs) - { - DiscordAuditLogEntry entry = null; - ulong t1, t2; - int t3, t4; - long t5, t6; - bool p1, p2; - switch (xac.ActionType) - { - case AuditLogActionType.Invalid: - break; - - case AuditLogActionType.GuildUpdate: - entry = new DiscordAuditLogGuildEntry - { - Target = this - }; - - var entrygld = entry as DiscordAuditLogGuildEntry; - foreach (var xc in xac.Changes) - { - PropertyChange GetChannelChange() - { - ulong.TryParse(xc.NewValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t1); - ulong.TryParse(xc.OldValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t2); - - return new() - { - Before = this.GetChannel(t1) ?? new DiscordChannel { Id = t1, Discord = this.Discord, GuildId = this.Id }, - After = this.GetChannel(t2) ?? new DiscordChannel { Id = t1, Discord = this.Discord, GuildId = this.Id } - }; - } - - switch (xc.Key.ToLowerInvariant()) - { - case "name": - entrygld.NameChange = new() - { - Before = xc.OldValueString, - After = xc.NewValueString - }; - break; - - case "owner_id": - entrygld.OwnerChange = new() - { - Before = this.MembersInternal != null && this.MembersInternal.TryGetValue(xc.OldValueUlong, out var oldMember) ? oldMember : await this.GetMemberAsync(xc.OldValueUlong).ConfigureAwait(false), - After = this.MembersInternal != null && this.MembersInternal.TryGetValue(xc.NewValueUlong, out var newMember) ? newMember : await this.GetMemberAsync(xc.NewValueUlong).ConfigureAwait(false) - }; - break; - - case "icon_hash": - entrygld.IconChange = new() - { - Before = xc.OldValueString != null ? $"{DiscordDomain.GetDomain(CoreDomain.DiscordCdn).Url}{Endpoints.ICONS}/{this.Id}/{xc.OldValueString}.webp" : null, - After = xc.OldValueString != null ? $"{DiscordDomain.GetDomain(CoreDomain.DiscordCdn).Url}{Endpoints.ICONS}/{this.Id}/{xc.NewValueString}.webp" : null - }; - break; - - case "verification_level": - entrygld.VerificationLevelChange = new() - { - Before = (VerificationLevel)(long)xc.OldValue, - After = (VerificationLevel)(long)xc.NewValue - }; - break; - - case "afk_channel_id": - entrygld.AfkChannelChange = GetChannelChange(); - break; - - case "system_channel_flags": - entrygld.SystemChannelFlagsChange = new() - { - Before = (SystemChannelFlags)(long)xc.OldValue, - After = (SystemChannelFlags)(long)xc.NewValue - }; - break; - - case "widget_channel_id": - entrygld.WidgetChannelChange = GetChannelChange(); - break; - - case "rules_channel_id": - entrygld.RulesChannelChange = GetChannelChange(); - break; - - case "public_updates_channel_id": - entrygld.PublicUpdatesChannelChange = GetChannelChange(); - break; - - case "splash_hash": - entrygld.SplashChange = new() - { - Before = xc.OldValueString != null ? $"{DiscordDomain.GetDomain(CoreDomain.DiscordCdn).Url}{Endpoints.SPLASHES}/{this.Id}/{xc.OldValueString}.webp?size=2048" : null, - After = xc.NewValueString != null ? $"{DiscordDomain.GetDomain(CoreDomain.DiscordCdn).Url}{Endpoints.SPLASHES}/{this.Id}/{xc.NewValueString}.webp?size=2048" : null - }; - break; - - case "default_message_notifications": - entrygld.NotificationSettingsChange = new() - { - Before = (DefaultMessageNotifications)(long)xc.OldValue, - After = (DefaultMessageNotifications)(long)xc.NewValue - }; - break; - - case "system_channel_id": - entrygld.SystemChannelChange = GetChannelChange(); - break; - - case "explicit_content_filter": - entrygld.ExplicitContentFilterChange = new() - { - Before = (ExplicitContentFilter)(long)xc.OldValue, - After = (ExplicitContentFilter)(long)xc.NewValue - }; - break; - - case "mfa_level": - entrygld.MfaLevelChange = new() - { - Before = (MfaLevel)(long)xc.OldValue, - After = (MfaLevel)(long)xc.NewValue - }; - break; - - case "region": - entrygld.RegionChange = new() - { - Before = xc.OldValueString, - After = xc.NewValueString - }; - break; - - case "vanity_url_code": - entrygld.VanityUrlCodeChange = new() - { - Before = xc.OldValueString, - After = xc.NewValueString - }; - break; - - case "premium_progress_bar_enabled": - entrygld.PremiumProgressBarChange = new() - { - Before = (bool)xc.OldValue, - After = (bool)xc.NewValue - }; - break; - - default: - if (this.Discord.Configuration.ReportMissingFields) - this.Discord.Logger.LogWarning(LoggerEvents.AuditLog, "Unknown key in guild update: {Key} - this should be reported to library developers", xc.Key); - break; - } - } - break; - - case AuditLogActionType.ChannelCreate: - case AuditLogActionType.ChannelDelete: - case AuditLogActionType.ChannelUpdate: - entry = new DiscordAuditLogChannelEntry - { - Target = this.GetChannel(xac.TargetId.Value) ?? new DiscordChannel { Id = xac.TargetId.Value, Discord = this.Discord, GuildId = this.Id } - }; - - var entrychn = entry as DiscordAuditLogChannelEntry; - foreach (var xc in xac.Changes) - { - switch (xc.Key.ToLowerInvariant()) - { - case "name": - entrychn.NameChange = new() - { - Before = xc.OldValueString, - After = xc.NewValueString - }; - break; - - case "type": - p1 = ulong.TryParse(xc.NewValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t1); - p2 = ulong.TryParse(xc.OldValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t2); - - entrychn.TypeChange = new() - { - Before = p1 ? (ChannelType?)t1 : null, - After = p2 ? (ChannelType?)t2 : null - }; - break; - - case "flags": - entrychn.ChannelFlagsChange = new() - { - Before = (ChannelFlags)(long)(xc.OldValue ?? 0L), - After = (ChannelFlags)(long)(xc.NewValue ?? 0L) - }; - break; - - case "permission_overwrites": - var olds = xc.OldValues?.OfType() - ?.Select(xjo => xjo.ToObject()) - ?.Select(xo => { xo.Discord = this.Discord; return xo; }); - - var news = xc.NewValues?.OfType() - ?.Select(xjo => xjo.ToObject()) - ?.Select(xo => { xo.Discord = this.Discord; return xo; }); - - entrychn.OverwriteChange = new() - { - Before = olds != null ? new ReadOnlyCollection(new List(olds)) : null, - After = news != null ? new ReadOnlyCollection(new List(news)) : null - }; - break; - - case "topic": - entrychn.TopicChange = new() - { - Before = xc.OldValueString, - After = xc.NewValueString - }; - break; - - case "nsfw": - entrychn.NsfwChange = new() - { - Before = (bool?)xc.OldValue, - After = (bool?)xc.NewValue - }; - break; - - case "rtc_region": - entrychn.RtcRegionIdChange = new() - { - Before = xc.OldValueString, - After = xc.NewValueString - }; - break; - - case "bitrate": - entrychn.BitrateChange = new() - { - Before = (int?)(long?)xc.OldValue, - After = (int?)(long?)xc.NewValue - }; - break; - - case "user_limit": - entrychn.UserLimitChange = new() - { - Before = (int?)(long?)xc.OldValue, - After = (int?)(long?)xc.NewValue - }; - break; - - case "rate_limit_per_user": - entrychn.PerUserRateLimitChange = new() - { - Before = (int?)(long?)xc.OldValue, - After = (int?)(long?)xc.NewValue - }; - break; - - case "default_auto_archive_duration": - entrychn.DefaultAutoArchiveDurationChange = new() - { - Before = (ThreadAutoArchiveDuration?)(long?)xc.OldValue, - After = (ThreadAutoArchiveDuration?)(long?)xc.NewValue - }; - break; - case "available_tags": - var oldTags = xc.OldValues?.OfType() - ?.Select(xjo => xjo.ToObject()) - ?.Select(xo => { xo.Discord = this.Discord; return xo; }); - - var newTags = xc.NewValues?.OfType() - ?.Select(xjo => xjo.ToObject()) - ?.Select(xo => { xo.Discord = this.Discord; return xo; }); - - entrychn.AvailableTagsChange = new() - { - Before = oldTags != null ? new List(new List(oldTags)) : null, - After = newTags != null ? new List(new List(newTags)) : null - }; - break; - - default: - if (this.Discord.Configuration.ReportMissingFields) - this.Discord.Logger.LogWarning(LoggerEvents.AuditLog, "Unknown key in channel update: {Key} - this should be reported to library developers", xc.Key); - break; - } - } - break; - - case AuditLogActionType.OverwriteCreate: - case AuditLogActionType.OverwriteDelete: - case AuditLogActionType.OverwriteUpdate: - entry = new DiscordAuditLogOverwriteEntry - { - Target = this.GetChannel(xac.TargetId.Value)?.PermissionOverwrites.FirstOrDefault(xo => xo.Id == xac.Options.Id), - Channel = this.GetChannel(xac.TargetId.Value) - }; - - var entryovr = entry as DiscordAuditLogOverwriteEntry; - foreach (var xc in xac.Changes) - { - switch (xc.Key.ToLowerInvariant()) - { - case "deny": - p1 = ulong.TryParse(xc.OldValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t1); - p2 = ulong.TryParse(xc.OldValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t2); - - entryovr.DenyChange = new() - { - Before = p1 ? (Permissions?)t1 : null, - After = p2 ? (Permissions?)t2 : null - }; - break; - - case "allow": - p1 = ulong.TryParse(xc.OldValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t1); - p2 = ulong.TryParse(xc.OldValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t2); - - entryovr.AllowChange = new() - { - Before = p1 ? (Permissions?)t1 : null, - After = p2 ? (Permissions?)t2 : null - }; - break; - - case "type": - entryovr.TypeChange = new() - { - Before = xc.OldValue != null ? (OverwriteType)(long)xc.OldValue : null, - After = xc.NewValue != null ? (OverwriteType)(long)xc.NewValue : null - }; - break; - - case "id": - p1 = ulong.TryParse(xc.OldValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t1); - p2 = ulong.TryParse(xc.NewValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t2); - - entryovr.TargetIdChange = new() - { - Before = p1 ? t1 : null, - After = p2 ? t2 : null - }; - break; - - default: - if (this.Discord.Configuration.ReportMissingFields) - this.Discord.Logger.LogWarning(LoggerEvents.AuditLog, "Unknown key in overwrite update: {Key} - this should be reported to library developers", xc.Key); - break; - } - } - break; - - case AuditLogActionType.Kick: - entry = new DiscordAuditLogKickEntry - { - Target = amd.TryGetValue(xac.TargetId.Value, out var kickMember) ? kickMember : new() { Id = xac.TargetId.Value, Discord = this.Discord, GuildId = this.Id } - }; - break; - - case AuditLogActionType.Prune: - entry = new DiscordAuditLogPruneEntry - { - Days = xac.Options.DeleteMemberDays, - Toll = xac.Options.MembersRemoved - }; - break; - - case AuditLogActionType.Ban: - case AuditLogActionType.Unban: - entry = new DiscordAuditLogBanEntry - { - Target = amd.TryGetValue(xac.TargetId.Value, out var unbanMember) ? unbanMember : new() { Id = xac.TargetId.Value, Discord = this.Discord, GuildId = this.Id } - }; - break; - - case AuditLogActionType.MemberUpdate: - case AuditLogActionType.MemberRoleUpdate: - entry = new DiscordAuditLogMemberUpdateEntry - { - Target = amd.TryGetValue(xac.TargetId.Value, out var roleUpdMember) ? roleUpdMember : new() { Id = xac.TargetId.Value, Discord = this.Discord, GuildId = this.Id } - }; - - var entrymbu = entry as DiscordAuditLogMemberUpdateEntry; - foreach (var xc in xac.Changes) - { - switch (xc.Key.ToLowerInvariant()) - { - case "nick": - entrymbu.NicknameChange = new() - { - Before = xc.OldValueString, - After = xc.NewValueString - }; - break; - - case "deaf": - entrymbu.DeafenChange = new() - { - Before = (bool?)xc.OldValue, - After = (bool?)xc.NewValue - }; - break; - - case "mute": - entrymbu.MuteChange = new() - { - Before = (bool?)xc.OldValue, - After = (bool?)xc.NewValue - }; - break; - case "communication_disabled_until": - entrymbu.CommunicationDisabledUntilChange = new() - { - Before = (DateTime?)xc.OldValue, - After = (DateTime?)xc.NewValue - }; - break; - - case "$add": - entrymbu.AddedRoles = new ReadOnlyCollection(xc.NewValues.Select(xo => (ulong)xo["id"]).Select(this.GetRole).ToList()); - break; - - case "$remove": - entrymbu.RemovedRoles = new ReadOnlyCollection(xc.NewValues.Select(xo => (ulong)xo["id"]).Select(this.GetRole).ToList()); - break; - - default: - if (this.Discord.Configuration.ReportMissingFields) - this.Discord.Logger.LogWarning(LoggerEvents.AuditLog, "Unknown key in member update: {Key} - this should be reported to library developers", xc.Key); - break; - } - } - break; - - case AuditLogActionType.RoleCreate: - case AuditLogActionType.RoleDelete: - case AuditLogActionType.RoleUpdate: - entry = new DiscordAuditLogRoleUpdateEntry - { - Target = this.GetRole(xac.TargetId.Value) ?? new DiscordRole { Id = xac.TargetId.Value, Discord = this.Discord } - }; - - var entryrol = entry as DiscordAuditLogRoleUpdateEntry; - foreach (var xc in xac.Changes) - { - switch (xc.Key.ToLowerInvariant()) - { - case "name": - entryrol.NameChange = new() - { - Before = xc.OldValueString, - After = xc.NewValueString - }; - break; - - case "color": - p1 = int.TryParse(xc.OldValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t3); - p2 = int.TryParse(xc.NewValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t4); - - entryrol.ColorChange = new() - { - Before = p1 ? t3 : null, - After = p2 ? t4 : null - }; - break; - - case "permissions": - entryrol.PermissionChange = new() - { - Before = xc.OldValue != null ? (Permissions?)long.Parse((string)xc.OldValue) : null, - After = xc.NewValue != null ? (Permissions?)long.Parse((string)xc.NewValue) : null - }; - break; - - case "position": - entryrol.PositionChange = new() - { - Before = xc.OldValue != null ? (int?)(long)xc.OldValue : null, - After = xc.NewValue != null ? (int?)(long)xc.NewValue : null, - }; - break; - - case "mentionable": - entryrol.MentionableChange = new() - { - Before = xc.OldValue != null ? (bool?)xc.OldValue : null, - After = xc.NewValue != null ? (bool?)xc.NewValue : null - }; - break; - - case "hoist": - entryrol.HoistChange = new() - { - Before = (bool?)xc.OldValue, - After = (bool?)xc.NewValue - }; - break; - - case "icon_hash": - entryrol.IconHashChange = new() - { - Before = xc.OldValueString, - After = xc.NewValueString - }; - break; - - default: - if (this.Discord.Configuration.ReportMissingFields) - this.Discord.Logger.LogWarning(LoggerEvents.AuditLog, "Unknown key in role update: {Key} - this should be reported to library developers", xc.Key); - break; - } - } - break; - - case AuditLogActionType.InviteCreate: - case AuditLogActionType.InviteDelete: - case AuditLogActionType.InviteUpdate: - entry = new DiscordAuditLogInviteEntry(); - - var inv = new DiscordInvite - { - Discord = this.Discord, - Guild = new() - { - Discord = this.Discord, - Id = this.Id, - Name = this.Name, - SplashHash = this.SplashHash - } - }; - - var entryinv = entry as DiscordAuditLogInviteEntry; - foreach (var xc in xac.Changes) - { - switch (xc.Key.ToLowerInvariant()) - { - case "max_age": - p1 = int.TryParse(xc.OldValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t3); - p2 = int.TryParse(xc.OldValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t4); - - entryinv.MaxAgeChange = new() - { - Before = p1 ? t3 : null, - After = p2 ? t4 : null - }; - break; - - case "code": - inv.Code = xc.OldValueString ?? xc.NewValueString; - - entryinv.CodeChange = new() - { - Before = xc.OldValueString, - After = xc.NewValueString - }; - break; - - case "temporary": - entryinv.TemporaryChange = new() - { - Before = xc.OldValue != null ? (bool?)xc.OldValue : null, - After = xc.NewValue != null ? (bool?)xc.NewValue : null - }; - break; - - case "inviter_id": - p1 = ulong.TryParse(xc.OldValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t1); - p2 = ulong.TryParse(xc.NewValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t2); - - entryinv.InviterChange = new() - { - Before = amd.TryGetValue(t1, out var propBeforeMember) ? propBeforeMember : new() { Id = t1, Discord = this.Discord, GuildId = this.Id }, - After = amd.TryGetValue(t2, out var propAfterMember) ? propAfterMember : new() { Id = t1, Discord = this.Discord, GuildId = this.Id }, - }; - break; - - case "channel_id": - p1 = ulong.TryParse(xc.OldValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t1); - p2 = ulong.TryParse(xc.NewValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t2); - - entryinv.ChannelChange = new() - { - Before = p1 ? this.GetChannel(t1) ?? new DiscordChannel { Id = t1, Discord = this.Discord, GuildId = this.Id } : null, - After = p2 ? this.GetChannel(t2) ?? new DiscordChannel { Id = t1, Discord = this.Discord, GuildId = this.Id } : null - }; - - var ch = entryinv.ChannelChange.Before ?? entryinv.ChannelChange.After; - var cht = ch?.Type; - inv.Channel = new() - { - Discord = this.Discord, - Id = p1 ? t1 : t2, - Name = ch?.Name, - Type = cht != null ? cht.Value : ChannelType.Unknown - }; - break; - - case "uses": - p1 = int.TryParse(xc.OldValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t3); - p2 = int.TryParse(xc.OldValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t4); - - entryinv.UsesChange = new() - { - Before = p1 ? t3 : null, - After = p2 ? t4 : null - }; - break; - - case "max_uses": - p1 = int.TryParse(xc.OldValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t3); - p2 = int.TryParse(xc.OldValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t4); - - entryinv.MaxUsesChange = new() - { - Before = p1 ? t3 : null, - After = p2 ? t4 : null - }; - break; - - // TODO: Add changes for target application - - default: - if (this.Discord.Configuration.ReportMissingFields) - this.Discord.Logger.LogWarning(LoggerEvents.AuditLog, "Unknown key in invite update: {Key} - this should be reported to library developers", xc.Key); - break; - } - } - - entryinv.Target = inv; - break; - - case AuditLogActionType.WebhookCreate: - case AuditLogActionType.WebhookDelete: - case AuditLogActionType.WebhookUpdate: - entry = new DiscordAuditLogWebhookEntry - { - Target = ahd.TryGetValue(xac.TargetId.Value, out var webhook) ? webhook : new() { Id = xac.TargetId.Value, Discord = this.Discord } - }; - - var entrywhk = entry as DiscordAuditLogWebhookEntry; - foreach (var xc in xac.Changes) - { - switch (xc.Key.ToLowerInvariant()) - { - case "application_id": // ??? - p1 = ulong.TryParse(xc.OldValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t1); - p2 = ulong.TryParse(xc.NewValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t2); - - entrywhk.IdChange = new() - { - Before = p1 ? t1 : null, - After = p2 ? t2 : null - }; - break; - - case "name": - entrywhk.NameChange = new() - { - Before = xc.OldValueString, - After = xc.NewValueString - }; - break; - - case "channel_id": - p1 = ulong.TryParse(xc.OldValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t1); - p2 = ulong.TryParse(xc.NewValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t2); - - entrywhk.ChannelChange = new() - { - Before = p1 ? this.GetChannel(t1) ?? new DiscordChannel { Id = t1, Discord = this.Discord, GuildId = this.Id } : null, - After = p2 ? this.GetChannel(t2) ?? new DiscordChannel { Id = t1, Discord = this.Discord, GuildId = this.Id } : null - }; - break; - - case "type": // ??? - p1 = int.TryParse(xc.OldValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t3); - p2 = int.TryParse(xc.NewValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t4); - - entrywhk.TypeChange = new() - { - Before = p1 ? t3 : null, - After = p2 ? t4 : null - }; - break; - - case "avatar_hash": - entrywhk.AvatarHashChange = new() - { - Before = xc.OldValueString, - After = xc.NewValueString - }; - break; - - default: - if (this.Discord.Configuration.ReportMissingFields) - this.Discord.Logger.LogWarning(LoggerEvents.AuditLog, "Unknown key in webhook update: {Key} - this should be reported to library developers", xc.Key); - break; - } - } - break; - - case AuditLogActionType.EmojiCreate: - case AuditLogActionType.EmojiDelete: - case AuditLogActionType.EmojiUpdate: - entry = new DiscordAuditLogEmojiEntry - { - Target = this.EmojisInternal.TryGetValue(xac.TargetId.Value, out var target) ? target : new() { Id = xac.TargetId.Value, Discord = this.Discord } - }; - - var entryemo = entry as DiscordAuditLogEmojiEntry; - foreach (var xc in xac.Changes) - { - switch (xc.Key.ToLowerInvariant()) - { - case "name": - entryemo.NameChange = new() - { - Before = xc.OldValueString, - After = xc.NewValueString - }; - break; - - default: - if (this.Discord.Configuration.ReportMissingFields) - this.Discord.Logger.LogWarning(LoggerEvents.AuditLog, "Unknown key in emote update: {Key} - this should be reported to library developers", xc.Key); - break; - } - } - break; - - case AuditLogActionType.StageInstanceCreate: - case AuditLogActionType.StageInstanceDelete: - case AuditLogActionType.StageInstanceUpdate: - entry = new DiscordAuditLogStageEntry - { - Target = this.StageInstancesInternal.TryGetValue(xac.TargetId.Value, out var stage) ? stage : new() { Id = xac.TargetId.Value, Discord = this.Discord } - }; - - var entrysta = entry as DiscordAuditLogStageEntry; - foreach (var xc in xac.Changes) - { - switch (xc.Key.ToLowerInvariant()) - { - case "topic": - entrysta.TopicChange = new() - { - Before = xc.OldValueString, - After = xc.NewValueString - }; - break; - - default: - if (this.Discord.Configuration.ReportMissingFields) - this.Discord.Logger.LogWarning(LoggerEvents.AuditLog, "Unknown key in stage instance update: {Key} - this should be reported to library developers", xc.Key); - break; - } - } - break; - - case AuditLogActionType.StickerCreate: - case AuditLogActionType.StickerDelete: - case AuditLogActionType.StickerUpdate: - entry = new DiscordAuditLogStickerEntry - { - Target = this.StickersInternal.TryGetValue(xac.TargetId.Value, out var sticker) ? sticker : new() { Id = xac.TargetId.Value, Discord = this.Discord } - }; - - var entrysti = entry as DiscordAuditLogStickerEntry; - foreach (var xc in xac.Changes) - { - switch (xc.Key.ToLowerInvariant()) - { - case "name": - entrysti.NameChange = new() - { - Before = xc.OldValueString, - After = xc.NewValueString - }; - break; - case "description": - entrysti.DescriptionChange = new() - { - Before = xc.OldValueString, - After = xc.NewValueString - }; - break; - case "tags": - entrysti.TagsChange = new() - { - Before = xc.OldValueString, - After = xc.NewValueString - }; - break; - case "guild_id": - entrysti.GuildIdChange = new() - { - Before = ulong.TryParse(xc.OldValueString, out var ogid) ? ogid : null, - After = ulong.TryParse(xc.NewValueString, out var ngid) ? ngid : null - }; - break; - case "available": - entrysti.AvailabilityChange = new() - { - Before = (bool?)xc.OldValue, - After = (bool?)xc.NewValue, - }; - break; - case "asset": - entrysti.AssetChange = new() - { - Before = xc.OldValueString, - After = xc.NewValueString - }; - break; - case "id": - entrysti.IdChange = new() - { - Before = ulong.TryParse(xc.OldValueString, out var oid) ? oid : null, - After = ulong.TryParse(xc.NewValueString, out var nid) ? nid : null - }; - break; - case "type": - p1 = long.TryParse(xc.OldValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t5); - p2 = long.TryParse(xc.NewValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t6); - entrysti.TypeChange = new() - { - Before = p1 ? (StickerType?)t5 : null, - After = p2 ? (StickerType?)t6 : null - }; - break; - case "format_type": - p1 = long.TryParse(xc.OldValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t5); - p2 = long.TryParse(xc.NewValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t6); - entrysti.FormatChange = new() - { - Before = p1 ? (StickerFormat?)t5 : null, - After = p2 ? (StickerFormat?)t6 : null - }; - break; - - default: - if (this.Discord.Configuration.ReportMissingFields) - this.Discord.Logger.LogWarning(LoggerEvents.AuditLog, "Unknown key in sticker update: {Key} - this should be reported to library developers", xc.Key); - break; - } - } - break; - - - - case AuditLogActionType.MessageDelete: - case AuditLogActionType.MessageBulkDelete: - { - entry = new DiscordAuditLogMessageEntry(); - - var entrymsg = entry as DiscordAuditLogMessageEntry; - - if (xac.Options != null) - { - entrymsg.Channel = this.GetChannel(xac.Options.ChannelId) ?? new DiscordChannel { Id = xac.Options.ChannelId, Discord = this.Discord, GuildId = this.Id }; - entrymsg.MessageCount = xac.Options.Count; - } - - if (entrymsg.Channel != null) - { - entrymsg.Target = this.Discord is DiscordClient dc - && dc.MessageCache != null - && dc.MessageCache.TryGet(xm => xm.Id == xac.TargetId.Value && xm.ChannelId == entrymsg.Channel.Id, out var msg) - ? msg - : new() { Discord = this.Discord, Id = xac.TargetId.Value }; - } - break; - } - - case AuditLogActionType.MessagePin: - case AuditLogActionType.MessageUnpin: - { - entry = new DiscordAuditLogMessagePinEntry(); - - var entrypin = entry as DiscordAuditLogMessagePinEntry; - - if (this.Discord is not DiscordClient dc) - { - break; - } - - if (xac.Options != null) - { - DiscordMessage message = default; - dc.MessageCache?.TryGet(x => x.Id == xac.Options.MessageId && x.ChannelId == xac.Options.ChannelId, out message); - - entrypin.Channel = this.GetChannel(xac.Options.ChannelId) ?? new DiscordChannel { Id = xac.Options.ChannelId, Discord = this.Discord, GuildId = this.Id }; - entrypin.Message = message ?? new DiscordMessage { Id = xac.Options.MessageId, Discord = this.Discord }; - } - - if (xac.TargetId.HasValue) - { - dc.UserCache.TryGetValue(xac.TargetId.Value, out var user); - entrypin.Target = user ?? new DiscordUser { Id = user.Id, Discord = this.Discord }; - } - - break; - } - - case AuditLogActionType.BotAdd: - { - entry = new DiscordAuditLogBotAddEntry(); - - if (!(this.Discord is DiscordClient dc && xac.TargetId.HasValue)) - { - break; - } - - dc.UserCache.TryGetValue(xac.TargetId.Value, out var bot); - (entry as DiscordAuditLogBotAddEntry).TargetBot = bot ?? new DiscordUser { Id = xac.TargetId.Value, Discord = this.Discord }; - - break; - } - - case AuditLogActionType.MemberMove: - entry = new DiscordAuditLogMemberMoveEntry(); - - if (xac.Options == null) - { - break; - } - - var moveentry = entry as DiscordAuditLogMemberMoveEntry; - - moveentry.UserCount = xac.Options.Count; - moveentry.Channel = this.GetChannel(xac.Options.ChannelId) ?? new DiscordChannel { Id = xac.Options.ChannelId, Discord = this.Discord, GuildId = this.Id }; - break; - - case AuditLogActionType.MemberDisconnect: - entry = new DiscordAuditLogMemberDisconnectEntry - { - UserCount = xac.Options?.Count ?? 0 - }; - break; - - case AuditLogActionType.IntegrationCreate: - case AuditLogActionType.IntegrationDelete: - case AuditLogActionType.IntegrationUpdate: - entry = new DiscordAuditLogIntegrationEntry(); - - var integentry = entry as DiscordAuditLogIntegrationEntry; - foreach (var xc in xac.Changes) - { - switch (xc.Key.ToLowerInvariant()) - { - case "type": - integentry.Type = new() - { - Before = xc.OldValueString, - After = xc.NewValueString - }; - break; - case "enable_emoticons": - integentry.EnableEmoticons = new() - { - Before = (bool?)xc.OldValue, - After = (bool?)xc.NewValue - }; - break; - case "expire_behavior": - integentry.ExpireBehavior = new() - { - Before = (int?)xc.OldValue, - After = (int?)xc.NewValue - }; - break; - case "expire_grace_period": - integentry.ExpireBehavior = new() - { - Before = (int?)xc.OldValue, - After = (int?)xc.NewValue - }; - break; - - default: - if (this.Discord.Configuration.ReportMissingFields) - this.Discord.Logger.LogWarning(LoggerEvents.AuditLog, "Unknown key in integration update: {Key} - this should be reported to library developers", xc.Key); - break; - } - } - break; - - case AuditLogActionType.ThreadCreate: - case AuditLogActionType.ThreadDelete: - case AuditLogActionType.ThreadUpdate: - entry = new DiscordAuditLogThreadEntry - { - Target = this.ThreadsInternal.TryGetValue(xac.TargetId.Value, out var thread) ? thread : new() { Id = xac.TargetId.Value, Discord = this.Discord } - }; - - var entrythr = entry as DiscordAuditLogThreadEntry; - foreach (var xc in xac.Changes) - { - switch (xc.Key.ToLowerInvariant()) - { - case "name": - entrythr.NameChange = new() - { - Before = xc.OldValueString, - After = xc.NewValueString - }; - break; - - case "type": - p1 = ulong.TryParse(xc.NewValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t1); - p2 = ulong.TryParse(xc.OldValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t2); - - entrythr.TypeChange = new() - { - Before = p1 ? (ChannelType?)t1 : null, - After = p2 ? (ChannelType?)t2 : null - }; - break; - - case "archived": - entrythr.ArchivedChange = new() - { - Before = xc.OldValue != null ? (bool?)xc.OldValue : null, - After = xc.NewValue != null ? (bool?)xc.NewValue : null - }; - break; - - case "locked": - entrythr.LockedChange = new() - { - Before = xc.OldValue != null ? (bool?)xc.OldValue : null, - After = xc.NewValue != null ? (bool?)xc.NewValue : null - }; - break; - - case "invitable": - entrythr.InvitableChange = new() - { - Before = xc.OldValue != null ? (bool?)xc.OldValue : null, - After = xc.NewValue != null ? (bool?)xc.NewValue : null - }; - break; - - case "auto_archive_duration": - p1 = long.TryParse(xc.OldValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t5); - p2 = long.TryParse(xc.NewValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t6); - - entrythr.AutoArchiveDurationChange = new() - { - Before = p1 ? (ThreadAutoArchiveDuration?)t5 : null, - After = p2 ? (ThreadAutoArchiveDuration?)t6 : null - }; - break; - - case "rate_limit_per_user": - entrythr.PerUserRateLimitChange = new() - { - Before = (int?)(long?)xc.OldValue, - After = (int?)(long?)xc.NewValue - }; - break; - - default: - if (this.Discord.Configuration.ReportMissingFields) - this.Discord.Logger.LogWarning(LoggerEvents.AuditLog, "Unknown key in thread update: {Key} - this should be reported to library developers", xc.Key); - break; - } - } - break; - - - case AuditLogActionType.GuildScheduledEventCreate: - case AuditLogActionType.GuildScheduledEventDelete: - case AuditLogActionType.GuildScheduledEventUpdate: - entry = new DiscordAuditLogGuildScheduledEventEntry - { - Target = this.ScheduledEventsInternal.TryGetValue(xac.TargetId.Value, out var scheduledEvent) ? scheduledEvent : new() { Id = xac.TargetId.Value, Discord = this.Discord } - }; - - var entryse = entry as DiscordAuditLogGuildScheduledEventEntry; - foreach (var xc in xac.Changes) - { - switch (xc.Key.ToLowerInvariant()) - { - case "channel_id": - entryse.ChannelIdChange = new() - { - Before = ulong.TryParse(xc.OldValueString, out var ogid) ? ogid : null, - After = ulong.TryParse(xc.NewValueString, out var ngid) ? ngid : null - }; - break; - - case "name": - entryse.NameChange = new() - { - Before = xc.OldValueString, - After = xc.NewValueString - }; - break; - - case "description": - entryse.DescriptionChange = new() - { - Before = xc.OldValueString, - After = xc.NewValueString - }; - break; - - case "location": - entryse.LocationChange = new() - { - Before = xc.OldValueString, - After = xc.NewValueString - }; - break; - - case "entity_type": - p1 = long.TryParse(xc.OldValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t5); - p2 = long.TryParse(xc.NewValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t6); - - entryse.EntityTypeChange = new() - { - Before = p1 ? (ScheduledEventEntityType?)t5 : null, - After = p2 ? (ScheduledEventEntityType?)t6 : null - }; - break; - - case "status": - p1 = long.TryParse(xc.OldValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t5); - p2 = long.TryParse(xc.NewValue as string, NumberStyles.Integer, CultureInfo.InvariantCulture, out t6); - - entryse.StatusChange = new() - { - Before = p1 ? (ScheduledEventStatus?)t5 : null, - After = p2 ? (ScheduledEventStatus?)t6 : null - }; - break; - - default: - if (this.Discord.Configuration.ReportMissingFields) - this.Discord.Logger.LogWarning(LoggerEvents.AuditLog, "Unknown key in scheduled event update: {Key} - this should be reported to library developers", xc.Key); - break; - } - } - break; - - // TODO: Handle ApplicationCommandPermissionUpdate - case AuditLogActionType.ApplicationCommandPermissionUpdate: - break; - - // TODO: Implement auto mod audit log - case AuditLogActionType.AutoModerationRuleCreate: - case AuditLogActionType.AutoModerationRuleUpdate: - case AuditLogActionType.AutoModerationRuleDelete: - break; - - case AuditLogActionType.AutoModerationBlockMessage: - break; - - case AuditLogActionType.AutoModerationFlagMessage: - break; - - case AuditLogActionType.AutoModerationTimeOutUser: - break; - - case AuditLogActionType.AutoModerationQuarantineUser: - break; - - case AuditLogActionType.OnboardingQuestionCreate: - case AuditLogActionType.OnboardingQuestionUpdate: - case AuditLogActionType.OnboardingUpdate: - case AuditLogActionType.ServerGuideCreate: - case AuditLogActionType.ServerGuideUpdate: - break; - - case AuditLogActionType.VoiceChannelStatusUpdate: - break; - - default: - this.Discord.Logger.LogWarning(LoggerEvents.AuditLog, "Unknown audit log action type: {Key} - this should be reported to library developers", (int)xac.ActionType); - break; - } - - if (entry == null) - continue; - - entry.ActionCategory = xac.ActionType switch - { - AuditLogActionType.ChannelCreate or AuditLogActionType.EmojiCreate or AuditLogActionType.InviteCreate or AuditLogActionType.OverwriteCreate or AuditLogActionType.RoleCreate or AuditLogActionType.WebhookCreate or AuditLogActionType.IntegrationCreate or AuditLogActionType.StickerCreate or AuditLogActionType.StageInstanceCreate or AuditLogActionType.ThreadCreate or AuditLogActionType.GuildScheduledEventCreate or AuditLogActionType.AutoModerationRuleCreate or AuditLogActionType.OnboardingQuestionCreate or AuditLogActionType.ServerGuideCreate => AuditLogActionCategory.Create, - AuditLogActionType.ChannelDelete or AuditLogActionType.EmojiDelete or AuditLogActionType.InviteDelete or AuditLogActionType.MessageDelete or AuditLogActionType.MessageBulkDelete or AuditLogActionType.OverwriteDelete or AuditLogActionType.RoleDelete or AuditLogActionType.WebhookDelete or AuditLogActionType.IntegrationDelete or AuditLogActionType.StickerDelete or AuditLogActionType.StageInstanceDelete or AuditLogActionType.ThreadDelete or AuditLogActionType.GuildScheduledEventDelete or AuditLogActionType.AutoModerationRuleDelete => AuditLogActionCategory.Delete, - AuditLogActionType.ChannelUpdate or AuditLogActionType.EmojiUpdate or AuditLogActionType.InviteUpdate or AuditLogActionType.MemberRoleUpdate or AuditLogActionType.MemberUpdate or AuditLogActionType.OverwriteUpdate or AuditLogActionType.RoleUpdate or AuditLogActionType.WebhookUpdate or AuditLogActionType.IntegrationUpdate or AuditLogActionType.StickerUpdate or AuditLogActionType.StageInstanceUpdate or AuditLogActionType.ThreadUpdate or AuditLogActionType.GuildScheduledEventUpdate or AuditLogActionType.AutoModerationRuleUpdate or AuditLogActionType.OnboardingQuestionUpdate or AuditLogActionType.OnboardingUpdate or AuditLogActionType.ServerGuideUpdate or AuditLogActionType.VoiceChannelStatusUpdate => AuditLogActionCategory.Update, - _ => AuditLogActionCategory.Other, - }; - entry.Discord = this.Discord; - entry.ActionType = xac.ActionType; - entry.Id = xac.Id; - entry.Reason = xac.Reason; - entry.UserResponsible = amd.Any() && amd.TryGetValue(xac.UserId, out var resp) ? resp : this.MembersInternal[xac.UserId]; - entries.Add(entry); - } - - return new ReadOnlyCollection(entries); - } -} diff --git a/DisCatSharp/EventArgs/Guild/GuildAuditLogEntryCreateEventArgs.cs b/DisCatSharp/EventArgs/Guild/GuildAuditLogEntryCreateEventArgs.cs index d7d358c0b..b1237660c 100644 --- a/DisCatSharp/EventArgs/Guild/GuildAuditLogEntryCreateEventArgs.cs +++ b/DisCatSharp/EventArgs/Guild/GuildAuditLogEntryCreateEventArgs.cs @@ -13,7 +13,7 @@ public class GuildAuditLogEntryCreateEventArgs : DiscordEventArgs /// Gets the audit log entry. /// Cast to correct type by action type. /// - public DiscordAuditLogEntry AuditLogEntry { get; internal set; } + public object AuditLogEntry { get; internal set; } /// /// Gets the guild in which the update occurred.