From f1a809193df9dbfa324926b4fd92beacd2d399ba Mon Sep 17 00:00:00 2001 From: Quahu Date: Mon, 15 Jul 2024 16:01:21 +0200 Subject: [PATCH] Deserialize gateway guild presences lazily and ignore bad data --- .../Models/GatewayGuildJsonModel.cs | 29 +++++++++++++++++-- .../Dispatches/Guild/GUILD_CREATE.cs | 2 +- .../Transient/Guild/TransientGatewayGuild.cs | 2 +- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/Disqord.Gateway.Api/Models/GatewayGuildJsonModel.cs b/src/Disqord.Gateway.Api/Models/GatewayGuildJsonModel.cs index b3ea5c98f..b8c0451ff 100644 --- a/src/Disqord.Gateway.Api/Models/GatewayGuildJsonModel.cs +++ b/src/Disqord.Gateway.Api/Models/GatewayGuildJsonModel.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using Disqord.Models; using Disqord.Serialization.Json; using Qommon; @@ -33,11 +34,35 @@ public class GatewayGuildJsonModel : GuildJsonModel public ChannelJsonModel[] Threads = null!; [JsonProperty("presences")] - public PresenceJsonModel[] Presences = null!; + public IJsonNode[] Presences = null!; [JsonProperty("stage_instances")] public StageInstanceJsonModel[] StageInstances = null!; [JsonProperty("guild_scheduled_events")] public GuildScheduledEventJsonModel[] GuildScheduledEvents = null!; -} \ No newline at end of file + + // Not ideal - handling the deserialization error at the serializer level would be better + public IEnumerable CreatePresences() + { + foreach (var node in Presences) + { + PresenceJsonModel? model = null; + try + { + model = node.ToType(); + } + catch + { + // Ignore bad presence data. + } + + if (model == null) + { + continue; + } + + yield return model; + } + } +} diff --git a/src/Disqord.Gateway/Default/Dispatcher/Dispatches/Guild/GUILD_CREATE.cs b/src/Disqord.Gateway/Default/Dispatcher/Dispatches/Guild/GUILD_CREATE.cs index a982fb443..c4089262e 100644 --- a/src/Disqord.Gateway/Default/Dispatcher/Dispatches/Guild/GUILD_CREATE.cs +++ b/src/Disqord.Gateway/Default/Dispatcher/Dispatches/Guild/GUILD_CREATE.cs @@ -154,7 +154,7 @@ private IGatewayGuild UpdateCache(GatewayGuildJsonModel model, bool isPending) if (CacheProvider.TryGetPresences(model.Id, out var presenceCache)) { - foreach (var presenceModel in model.Presences) + foreach (var presenceModel in model.CreatePresences()) { if (isPending) { diff --git a/src/Disqord.Gateway/Entities/Transient/Guild/TransientGatewayGuild.cs b/src/Disqord.Gateway/Entities/Transient/Guild/TransientGatewayGuild.cs index 151b2477d..f544c36e4 100644 --- a/src/Disqord.Gateway/Entities/Transient/Guild/TransientGatewayGuild.cs +++ b/src/Disqord.Gateway/Entities/Transient/Guild/TransientGatewayGuild.cs @@ -138,7 +138,7 @@ public IReadOnlyDictionary Stickers private IReadOnlyDictionary? _channels; - public IReadOnlyDictionary Presences => _presences ??= Model.Presences.ToReadOnlyDictionary(Client, + public IReadOnlyDictionary Presences => _presences ??= Model.CreatePresences().ToReadOnlyDictionary(Client, (model, _) => model.User.Id, (model, client) => new TransientPresence(client, model) as IPresence);