public override async ValueTask <EventArgs> HandleDispatchAsync(IGatewayApiClient shard, UnavailableGuildJsonModel model) { CachedGuild guild = null; var isPending = _readyHandler.IsPendingGuild(shard.Id, model.Id); if (model.Unavailable.HasValue || isPending) // Note: apparently `model.Unavailable` is provided for pending GUILD_CREATEs but not GUILD_DELETEs. { try { if (CacheProvider.TryGetGuilds(out var cache)) { guild = cache.GetValueOrDefault(model.Id); guild?.Update(model); } if (isPending) { shard.Logger.LogInformation("Pending guild {0} is unavailable.", model.Id.RawValue); } else { if (guild != null) { shard.Logger.LogInformation("Guild {0} ({1}) became unavailable.", guild.Name, guild.Id.RawValue); } else { shard.Logger.LogInformation("Uncached guild {0} became unavailable.", model.Id.RawValue); } } // Invoke the event and possibly invoke ready afterwards. await InvokeEventAsync(new GuildUnavailableEventArgs(model.Id, guild)).ConfigureAwait(false); } finally { if (isPending) { _readyHandler.PopPendingGuild(shard.Id, model.Id); } } return(null); } CacheProvider.Reset(model.Id, out guild); if (guild != null) { shard.Logger.LogInformation("Left guild '{0}' ({1}).", guild.Name, guild.Id.RawValue); } else { shard.Logger.LogInformation("Left uncached guild {0}.", model.Id.RawValue); } return(new LeftGuildEventArgs(model.Id, guild)); }
public override async ValueTask <EventArgs> HandleDispatchAsync(IGatewayApiClient shard, GatewayGuildJsonModel model) { IGatewayGuild guild; var isPending = _readyHandler.IsPendingGuild(shard.Id, model.Id); if (model.Unavailable.HasValue || isPending) // Note: apparently `model.Unavailable` is provided for pending GUILD_CREATEs but not GUILD_DELETEs. { try { guild = UpdateCache(model, isPending); var logLevel = isPending ? LogLevel.Debug : LogLevel.Information; var message = isPending ? "Pending guild {0} ({1}) is available." : "Guild {0} ({1}) became available."; shard.Logger.Log(logLevel, message, guild.Name, guild.Id.RawValue); // Invoke the event and possibly invoke ready afterwards. await InvokeEventAsync(new GuildAvailableEventArgs(guild)).ConfigureAwait(false); } finally { if (isPending) { _readyHandler.PopPendingGuild(shard.Id, model.Id); } } return(null); } guild = UpdateCache(model, true); shard.Logger.LogInformation("Joined guild {0} ({1}).", guild.Name, guild.Id.RawValue); return(new JoinedGuildEventArgs(guild)); }
public override async ValueTask <EventArgs> HandleDispatchAsync(IGatewayApiClient shard, GatewayGuildJsonModel model) { IGatewayGuild guild = null; // Check if the event is guild availability or we joined a new guild. if (model.Unavailable.HasValue) { // A guild became available. var isPending = _readyHandler.IsPendingGuild(shard.Id, model.Id); try { if (CacheProvider.TryGetGuilds(out var guildCache)) { if (isPending) { guild = new CachedGuild(Client, model); guildCache.Add(model.Id, guild as CachedGuild); } else { guild = guildCache.GetValueOrDefault(model.Id); guild?.Update(model); } } if (guild == null) { guild = new TransientGatewayGuild(Client, model); } // TODO: optimise member cache retrieval if (CacheProvider.TryGetMembers(model.Id, out var memberCache)) { foreach (var memberModel in model.Members) { Dispatcher.GetOrAddMember(model.Id, memberModel); } } if (CacheProvider.TryGetChannels(model.Id, out var channelCache)) { foreach (var channelModel in model.Channels) { if (isPending) { var channel = CachedGuildChannel.Create(Client, model.Id, channelModel); channelCache.Add(channel.Id, channel); } else { var channel = channelCache.GetValueOrDefault(channelModel.Id); channel?.Update(channelModel); } } } if (CacheProvider.TryGetRoles(model.Id, out var roleCache)) { foreach (var roleModel in model.Roles) { if (isPending) { var role = new CachedRole(Client, model.Id, roleModel); roleCache.Add(role.Id, role); } else { var role = roleCache.GetValueOrDefault(roleModel.Id); role?.Update(roleModel); } } } if (CacheProvider.TryGetVoiceStates(model.Id, out var voiceStateCache)) { foreach (var voiceStateModel in model.VoiceStates) { if (isPending) { var voiceState = new CachedVoiceState(Client, model.Id, voiceStateModel); voiceStateCache.Add(voiceState.Id, voiceState); } else { var voiceState = voiceStateCache.GetValueOrDefault(voiceStateModel.UserId); voiceState?.Update(voiceStateModel); } } } var logLevel = isPending ? LogLevel.Debug : LogLevel.Information; var message = isPending ? "Pending guild {0} ({1}) is available." : "Guild {0} ({1}) became available."; shard.Logger.Log(logLevel, message, guild.Name, guild.Id.RawValue); // Invoke the event and possibly invoke ready afterwards. await InvokeEventAsync(new GuildAvailableEventArgs(guild)).ConfigureAwait(false); } finally { if (isPending) { _readyHandler.PopPendingGuild(shard.Id, model.Id); } } return(null); } else { // We joined a new guild. if (Client.CacheProvider.TryGetGuilds(out var cache)) { guild = new CachedGuild(Client, model); cache.Add(model.Id, guild as CachedGuild); } else { guild = new TransientGatewayGuild(Client, model); } // TODO: optimise member cache retrieval if (CacheProvider.TryGetMembers(model.Id, out var memberCache)) { foreach (var memberModel in model.Members) { Dispatcher.GetOrAddMember(model.Id, memberModel); } } if (CacheProvider.TryGetChannels(model.Id, out var channelCache)) { foreach (var channelModel in model.Channels) { var channel = CachedGuildChannel.Create(Client, model.Id, channelModel); channelCache.Add(channel.Id, channel); } } if (CacheProvider.TryGetRoles(model.Id, out var roleCache)) { foreach (var roleModel in model.Roles) { var role = new CachedRole(Client, model.Id, roleModel); roleCache.Add(role.Id, role); } } shard.Logger.LogInformation("Joined guild {0} ({1}).", guild.Name, guild.Id.RawValue); return(new JoinedGuildEventArgs(guild)); } }
public override async ValueTask <EventArgs> HandleDispatchAsync(IGatewayApiClient shard, UnavailableGuildJsonModel model) { CachedGuild guild = null; if (model.Unavailable.HasValue) { var isPending = _readyHandler.IsPendingGuild(shard.Id, model.Id); try { if (CacheProvider.TryGetGuilds(out var cache)) { if (isPending) { // TODO: cache the id or such if the guild isn't available } else { guild = cache.GetValueOrDefault(model.Id); guild?.Update(model); } } if (isPending) { shard.Logger.LogInformation("Pending guild {0} is unavailable.", model.Id.RawValue); } else { if (guild != null) { shard.Logger.LogInformation("Guild {0} ({1}) became unavailable.", guild.Name, guild.Id.RawValue); } else { shard.Logger.LogInformation("Uncached guild {0} became unavailable.", model.Id.RawValue); } } // Invoke the event and possibly invoke ready afterwards. await InvokeEventAsync(new GuildUnavailableEventArgs(model.Id, guild)).ConfigureAwait(false); } finally { if (isPending) { _readyHandler.PopPendingGuild(shard.Id, model.Id); } } return(null); } else { if (Client.CacheProvider.TryGetGuilds(out var cache)) { cache.TryRemove(model.Id, out guild); } Client.CacheProvider.TryRemoveCache <CachedGuildChannel>(model.Id, out _); Client.CacheProvider.TryRemoveCache <CachedRole>(model.Id, out _); Client.CacheProvider.TryRemoveCache <CachedVoiceState>(model.Id, out _); if (guild == null) { shard.Logger.LogInformation("Left uncached guild {0}.", model.Id.RawValue); return(null); } shard.Logger.LogInformation("Left guild '{0}' ({1}).", guild.Name, guild.Id.RawValue); return(new LeftGuildEventArgs(model.Id, guild)); } }