void HandlePresenceUpdateEvent(DiscordApiData data) { Snowflake guildId = data.GetSnowflake("guild_id").Value; // Update user DiscordApiData userData = data.Get("user"); Snowflake userId = userData.GetSnowflake("id").Value; if (cache.Users.TryGetValue(userId, out MutableUser mutableUser)) { mutableUser.PartialUpdate(userData); } else { // Don't throw exception since we can still update everything else... log.LogError($"[PRESENCE_UPDATE] Failed to update user {userId}, they were not in the cache!"); } // Update presence DiscordUserPresence presence = new DiscordUserPresence(userId, data); cache.GuildPresences[guildId, userId] = presence; // Update member if (cache.GuildMembers.TryGetValue(guildId, userId, out MutableGuildMember mutableMember)) { mutableMember.PartialUpdate(data); // Fire event OnPresenceUpdated?.Invoke(this, new PresenceEventArgs(shard, guildId, mutableMember.ImmutableEntity, presence)); } // It is technically valid for the member to not exist here, especially if the guild is considered large. }
void HandleGuildMemberUpdateEvent(DiscordApiData data) { Snowflake guildId = data.GetSnowflake("guild_id").Value; DiscordApiData userData = data.Get("user"); Snowflake userId = userData.GetSnowflake("id").Value; // Get user MutableUser mutableUser; if (!cache.Users.TryGetValue(userId, out mutableUser)) { mutableUser = new MutableUser(userId, false, http); cache.Users[userId] = mutableUser; } mutableUser.Update(userData); // Get member if (cache.GuildMembers.TryGetValue(guildId, userId, out MutableGuildMember mutableMember)) { // Update member mutableMember.PartialUpdate(data); // Fire event OnGuildMemberUpdated?.Invoke(this, new GuildMemberEventArgs(shard, guildId, mutableMember.ImmutableEntity)); } // It is technically valid for the member to not exist here, especially if the guild is considered large. }
void HandleGuildMemberAddEvent(DiscordApiData data) { Snowflake guildId = data.GetSnowflake("guild_id").Value; DiscordApiData userData = data.Get("user"); Snowflake userId = userData.GetSnowflake("id").Value; // Get user MutableUser mutableUser; if (!cache.Users.TryGetValue(userId, out mutableUser)) { mutableUser = new MutableUser(userId, false, http); cache.Users[userId] = mutableUser; } // Update user mutableUser.Update(userData); // Get or create member MutableGuildMember mutableMember; if (!cache.GuildMembers.TryGetValue(guildId, userId, out mutableMember)) { mutableMember = new MutableGuildMember(mutableUser, guildId, http); cache.GuildMembers[guildId, userId] = mutableMember; } // Update member mutableMember.Update(data); // Fire event OnGuildMemberAdded?.Invoke(this, new GuildMemberEventArgs(shard, guildId, mutableMember.ImmutableEntity)); }
void HandleGuildMemberRemoveEvent(DiscordApiData data) { Snowflake guildId = data.GetSnowflake("guild_id").Value; DiscordApiData userData = data.Get("user"); Snowflake userId = userData.GetSnowflake("id").Value; // Get user MutableUser mutableUser; if (!cache.Users.TryGetValue(userId, out mutableUser)) { mutableUser = new MutableUser(userId, false, http); cache.Users[userId] = mutableUser; } mutableUser.Update(userData); // Get and remove member if (cache.GuildMembers.TryRemove(guildId, userId, out MutableGuildMember mutableMember)) { // Ensure all references are removed mutableMember.ClearReferences(); // Fire event OnGuildMemberRemoved?.Invoke(this, new GuildMemberEventArgs(shard, guildId, mutableMember.ImmutableEntity)); } }
void HandleMessageReactionRemoveEvent(DiscordApiData data) { Snowflake userId = data.GetSnowflake("user_id").Value; Snowflake channelId = data.GetSnowflake("channel_id").Value; Snowflake messageId = data.GetSnowflake("message_id").Value; DiscordApiData emojiData = data.Get("emoji"); DiscordReactionEmoji emoji = new DiscordReactionEmoji(emojiData); OnMessageReactionRemoved?.Invoke(this, new MessageReactionEventArgs(shard, messageId, channelId, userId, emoji)); }
internal DiscordReaction(DiscordApiData data) { Count = data.GetInteger("count").Value; Me = data.GetBoolean("me").Value; DiscordApiData emojiData = data.Get("emoji"); if (emojiData != null) { Emoji = new DiscordReactionEmoji(emojiData); } }
void HandleMessageUpdateEvent(DiscordApiData data) { // Get author DiscordApiData authorData = data.Get("author"); if (authorData != null) { Snowflake authorId = authorData.GetSnowflake("id").Value; bool isWebhookUser = !string.IsNullOrWhiteSpace(data.GetString("webhook_id")); MutableUser mutableAuthor; if (!cache.Users.TryGetValue(authorId, out mutableAuthor)) { mutableAuthor = new MutableUser(authorId, isWebhookUser, http); cache.Users[authorId] = mutableAuthor; } mutableAuthor.Update(authorData); } // Get mentioned users IList <DiscordApiData> mentionsArray = data.GetArray("mentions"); if (mentionsArray != null) { for (int i = 0; i < mentionsArray.Count; i++) { DiscordApiData userData = mentionsArray[i]; Snowflake userId = userData.GetSnowflake("id").Value; MutableUser mutableUser; if (!cache.Users.TryGetValue(userId, out mutableUser)) { mutableUser = new MutableUser(userId, false, http); cache.Users[userId] = mutableUser; } mutableUser.Update(userData); } } // Create message DiscordMessage message = new DiscordMessage(http, data); OnMessageUpdated?.Invoke(this, new MessageUpdateEventArgs(shard, message)); }
protected override Task OnPayloadReceived(DiscordApiData payload) { VoiceOPCode op = (VoiceOPCode)payload.GetInteger("op").Value; DiscordApiData d = payload.Get("d"); PayloadCallback callback; if (payloadHandlers.TryGetValue(op, out callback)) { callback(payload, d); } else { log.LogWarning($"Missing handler for payload: {op} ({(int)op})"); } return(Task.CompletedTask); }
void HandleGuildBanRemoveEvent(DiscordApiData data) { Snowflake guildId = data.GetSnowflake("guild_id").Value; DiscordApiData userData = data.Get("user"); Snowflake userId = userData.GetSnowflake("id").Value; MutableUser mutableUser; if (!cache.Users.TryGetValue(userId, out mutableUser)) { mutableUser = new MutableUser(userId, false, http); cache.Users[userId] = mutableUser; } mutableUser.Update(userData); OnGuildBanRemoved?.Invoke(this, new GuildUserEventArgs(shard, guildId, mutableUser.ImmutableEntity)); }
void HandleGuildRoleUpdateEvent(DiscordApiData data) { Snowflake guildId = data.GetSnowflake("guild_id").Value; if (cache.Guilds.TryGetValue(guildId, out MutableGuild mutableGuild)) { DiscordApiData roleData = data.Get("role"); DiscordRole role = new DiscordRole(http, guildId, roleData); mutableGuild.Roles[role.Id] = role; mutableGuild.Dirty(); OnGuildRoleUpdated?.Invoke(this, new GuildRoleEventArgs(shard, mutableGuild.ImmutableEntity, role)); } else { throw new ShardCacheException($"Guild {guildId} was not in the cache!"); } }
void HandleGuildMembersChunkEvent(DiscordApiData data) { Snowflake guildId = data.GetSnowflake("guild_id").Value; // Get every member and ensure they are cached IList <DiscordApiData> membersData = data.GetArray("members"); DiscordGuildMember[] members = new DiscordGuildMember[membersData.Count]; for (int i = 0; i < membersData.Count; i++) { DiscordApiData memberData = membersData[i]; DiscordApiData userData = memberData.Get("user"); Snowflake userId = userData.GetSnowflake("id").Value; // Get user MutableUser mutableUser; if (!cache.Users.TryGetValue(userId, out mutableUser)) { mutableUser = new MutableUser(userId, false, http); cache.Users[userId] = mutableUser; } mutableUser.Update(userData); // Get or create member MutableGuildMember mutableMember; if (!cache.GuildMembers.TryGetValue(guildId, userId, out mutableMember)) { mutableMember = new MutableGuildMember(mutableUser, guildId, http); mutableMember.Update(memberData); cache.GuildMembers[guildId, userId] = mutableMember; } members[i] = mutableMember.ImmutableEntity; } // Fire event OnGuildMembersChunk?.Invoke(this, new GuildMemberChunkEventArgs(shard, guildId, members)); }
internal DiscordUserPresence(Snowflake userId, DiscordApiData data) { UserId = userId; DiscordApiData gameData = data.Get("game"); if (gameData != null) { if (gameData.IsNull) { Game = null; } else { Game = new DiscordGame(gameData); } } string statusStr = data.GetString("status"); if (statusStr != null) { DiscordUserStatus?status = Utils.ParseUserStatus(statusStr); if (!status.HasValue) { // If we don't have a value for the status yet, // we at least know that they aren't offline. Status = DiscordUserStatus.Online; // However, this should issue a warning. DiscoreLogger.Global.LogWarning($"[DiscordUserPresence] Failed to deserialize status for user {UserId}. " + $"status = {statusStr}"); } else { Status = status.Value; } } }
protected override async Task OnPayloadReceived(DiscordApiData payload) { GatewayOPCode op = (GatewayOPCode)payload.GetInteger("op"); DiscordApiData data = payload.Get("d"); PayloadCallback callback; if (payloadHandlers.TryGetValue(op, out callback)) { if (callback.Synchronous != null) { callback.Synchronous(payload, data); } else { await callback.Asynchronous(payload, data).ConfigureAwait(false); } } else { log.LogWarning($"Missing handler for payload: {op} ({(int)op})"); } }
internal DiscordGuildBan(DiscordApiData data) { Reason = data.GetString("reason"); User = new DiscordUser(false, data.Get("user")); }
void HandleReadyEvent(DiscordApiData data) { // Check gateway protocol int protocolVersion = data.GetInteger("v").Value; if (protocolVersion != GATEWAY_VERSION) { log.LogError($"[Ready] Gateway protocol mismatch! Expected v{GATEWAY_VERSION}, got {protocolVersion}."); } // Clear the cache cache.Clear(); // Get the current bot's user object DiscordApiData userData = data.Get("user"); Snowflake userId = userData.GetSnowflake("id").Value; MutableUser user; if (!cache.Users.TryGetValue(userId, out user)) { user = new MutableUser(userId, false, http); cache.Users[userId] = user; } user.Update(userData); shard.UserId = userId; log.LogInfo($"[Ready] user = {user.Username}#{user.Discriminator}"); // Get session ID sessionId = data.GetString("session_id"); // Get unavailable guilds foreach (DiscordApiData unavailableGuildData in data.GetArray("guilds")) { Snowflake guildId = unavailableGuildData.GetSnowflake("id").Value; cache.AddGuildId(guildId); cache.SetGuildAvailability(guildId, false); } // Get DM channels foreach (DiscordApiData dmChannelData in data.GetArray("private_channels")) { DiscordChannelType type = (DiscordChannelType)dmChannelData.GetInteger("type").Value; if (type != DiscordChannelType.DirectMessage) { // TODO: Support group DMs continue; } Snowflake channelId = dmChannelData.GetSnowflake("id").Value; DiscordApiData recipientData = dmChannelData.GetArray("recipients").First(); Snowflake recipientId = recipientData.GetSnowflake("id").Value; MutableUser recipient; if (!cache.Users.TryGetValue(recipientId, out recipient)) { recipient = new MutableUser(recipientId, false, http); cache.Users[recipientId] = recipient; } recipient.Update(recipientData); MutableDMChannel mutableDMChannel; if (!cache.DMChannels.TryGetValue(channelId, out mutableDMChannel)) { mutableDMChannel = new MutableDMChannel(channelId, recipient, http); cache.DMChannels[channelId] = mutableDMChannel; } mutableDMChannel.Update(dmChannelData); } LogServerTrace("Ready", data); // Signal that the connection is ready handshakeCompleteEvent.Set(); }
void HandleReadyEvent(DiscordApiData data) { // Check gateway protocol int protocolVersion = data.GetInteger("v").Value; if (protocolVersion != GATEWAY_VERSION) { log.LogError($"[Ready] Gateway protocol mismatch! Expected v{GATEWAY_VERSION}, got {protocolVersion}."); } // Check shard if (shard.Id != 0 || totalShards > 1) { IList <DiscordApiData> shardData = data.GetArray("shard"); if (shardData != null) { if (shardData.Count > 0 && shardData[0].ToInteger() != shard.Id) { log.LogError($"[Ready] Shard ID mismatch! Expected {shard.Id}, got {shardData[0].ToInteger()}"); } if (shardData.Count > 1 && shardData[1].ToInteger() != totalShards) { log.LogError($"[Ready] Total shards mismatch! Expected {totalShards}, got {shardData[1].ToInteger()}"); } } } // Clear the cache cache.Clear(); // Get the current bot's user object DiscordApiData userData = data.Get("user"); Snowflake userId = userData.GetSnowflake("id").Value; MutableUser user; if (!cache.Users.TryGetValue(userId, out user)) { user = new MutableUser(userId, false, http); cache.Users[userId] = user; } user.Update(userData); shard.UserId = userId; log.LogInfo($"[Ready] user = {user.Username}#{user.Discriminator}"); // Get session ID sessionId = data.GetString("session_id"); // Get unavailable guilds foreach (DiscordApiData unavailableGuildData in data.GetArray("guilds")) { Snowflake guildId = unavailableGuildData.GetSnowflake("id").Value; cache.AddGuildId(guildId); cache.SetGuildAvailability(guildId, false); } LogServerTrace("Ready", data); // Signal that the connection is ready handshakeCompleteEvent.Set(); }
void HandleGuildCreateEvent(DiscordApiData data) { Snowflake guildId = data.GetSnowflake("id").Value; bool wasUnavailable = !cache.IsGuildAvailable(guildId); // Update guild MutableGuild mutableGuild; if (!cache.Guilds.TryGetValue(guildId, out mutableGuild)) { mutableGuild = new MutableGuild(guildId, http); cache.Guilds[guildId] = mutableGuild; } mutableGuild.Update(data); // Ensure the cache guildId list contains this guild (it uses a hashset so don't worry about duplicates). cache.AddGuildId(guildId); // GUILD_CREATE specifics // Update metadata cache.GuildMetadata[guildId] = new DiscordGuildMetadata(data); // Deserialize members cache.GuildMembers.Clear(guildId); IList <DiscordApiData> membersArray = data.GetArray("members"); for (int i = 0; i < membersArray.Count; i++) { DiscordApiData memberData = membersArray[i]; DiscordApiData userData = memberData.Get("user"); Snowflake userId = userData.GetSnowflake("id").Value; MutableUser user; if (!cache.Users.TryGetValue(userId, out user)) { user = new MutableUser(userId, false, http); cache.Users[userId] = user; } user.Update(userData); MutableGuildMember member; if (!cache.GuildMembers.TryGetValue(guildId, userId, out member)) { member = new MutableGuildMember(user, guildId, http); cache.GuildMembers[guildId, userId] = member; } member.Update(memberData); } // Deserialize channels cache.ClearGuildChannels(guildId); IList <DiscordApiData> channelsArray = data.GetArray("channels"); for (int i = 0; i < channelsArray.Count; i++) { DiscordApiData channelData = channelsArray[i]; DiscordChannelType channelType = (DiscordChannelType)channelData.GetInteger("type"); DiscordGuildChannel channel = null; if (channelType == DiscordChannelType.GuildText) { channel = new DiscordGuildTextChannel(http, channelData, guildId); } else if (channelType == DiscordChannelType.GuildVoice) { channel = new DiscordGuildVoiceChannel(http, channelData, guildId); } else if (channelType == DiscordChannelType.GuildCategory) { channel = new DiscordGuildCategoryChannel(http, channelData, guildId); } if (channel != null) { cache.AddGuildChannel(channel); } } // Deserialize voice states cache.GuildVoiceStates.Clear(guildId); IList <DiscordApiData> voiceStatesArray = data.GetArray("voice_states"); for (int i = 0; i < voiceStatesArray.Count; i++) { DiscordVoiceState state = new DiscordVoiceState(guildId, voiceStatesArray[i]); UpdateMemberVoiceState(state); } // Deserialize presences cache.GuildPresences.Clear(guildId); IList <DiscordApiData> presencesArray = data.GetArray("presences"); for (int i = 0; i < presencesArray.Count; i++) { // Presence's in GUILD_CREATE do not contain full user objects, // so don't attempt to update them here. DiscordApiData presenceData = presencesArray[i]; Snowflake userId = presenceData.LocateSnowflake("user.id").Value; cache.GuildPresences[guildId, userId] = new DiscordUserPresence(userId, presenceData); } // Mark the guild as available cache.SetGuildAvailability(guildId, true); // Fire event if (wasUnavailable) { OnGuildAvailable?.Invoke(this, new GuildEventArgs(shard, mutableGuild.ImmutableEntity)); } else { OnGuildCreated?.Invoke(this, new GuildEventArgs(shard, mutableGuild.ImmutableEntity)); } }