Exemplo n.º 1
0
        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.
        }
Exemplo n.º 2
0
        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.
        }
Exemplo n.º 3
0
        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));
        }
Exemplo n.º 4
0
        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));
            }
        }
Exemplo n.º 5
0
        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));
        }
Exemplo n.º 6
0
        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);
            }
        }
Exemplo n.º 7
0
        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));
        }
Exemplo n.º 8
0
        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);
        }
Exemplo n.º 9
0
        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));
        }
Exemplo n.º 10
0
        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!");
            }
        }
Exemplo n.º 11
0
        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));
        }
Exemplo n.º 12
0
        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;
                }
            }
        }
Exemplo n.º 13
0
        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})");
            }
        }
Exemplo n.º 14
0
 internal DiscordGuildBan(DiscordApiData data)
 {
     Reason = data.GetString("reason");
     User   = new DiscordUser(false, data.Get("user"));
 }
Exemplo n.º 15
0
        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();
        }
Exemplo n.º 16
0
        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();
        }
Exemplo n.º 17
0
        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));
            }
        }