Skip to content

Commit

Permalink
Deserialize gateway guild presences lazily and ignore bad data
Browse files Browse the repository at this point in the history
  • Loading branch information
Quahu committed Jul 15, 2024
1 parent beed8b3 commit f1a8091
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 4 deletions.
29 changes: 27 additions & 2 deletions src/Disqord.Gateway.Api/Models/GatewayGuildJsonModel.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using Disqord.Models;
using Disqord.Serialization.Json;
using Qommon;
Expand Down Expand Up @@ -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!;
}

// Not ideal - handling the deserialization error at the serializer level would be better
public IEnumerable<PresenceJsonModel> CreatePresences()
{
foreach (var node in Presences)
{
PresenceJsonModel? model = null;
try
{
model = node.ToType<PresenceJsonModel>();
}
catch
{
// Ignore bad presence data.
}

if (model == null)
{
continue;
}

yield return model;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ public IReadOnlyDictionary<Snowflake, IGuildSticker> Stickers

private IReadOnlyDictionary<Snowflake, IGuildChannel>? _channels;

public IReadOnlyDictionary<Snowflake, IPresence> Presences => _presences ??= Model.Presences.ToReadOnlyDictionary(Client,
public IReadOnlyDictionary<Snowflake, IPresence> Presences => _presences ??= Model.CreatePresences().ToReadOnlyDictionary(Client,
(model, _) => model.User.Id,
(model, client) => new TransientPresence(client, model) as IPresence);

Expand Down

0 comments on commit f1a8091

Please sign in to comment.