public static void Raise(this OnChannelCreated @event, object sender, ChannelEventArgs e)
 {
     if (@event != null)
     {
         @event(sender, e);
     }
 }
 private Task OnClientChannelCreated(SocketChannel arg)
 {
     if (arg is SocketTextChannel c)
     {
         OnChannelCreated?.Invoke(this, c);
     }
     return(Task.CompletedTask);
 }
Exemple #3
0
 /// <summary>
 /// Adds a channel to this server
 /// </summary>
 /// <remarks>
 /// May throw a <see cref="ChannelOperationException"/> if used incorrectly
 /// </remarks>
 /// <param name="channel">The channel to add</param>
 /// <returns>Returns true if channel was added successfully</returns>
 public bool AddChannel(IServerChannel channel)
 {
     if (!_channelMgr.AddChannel(channel))
     {
         return(false);
     }
     OnChannelCreated.Raise(this, new ChannelEventArgs(channel));
     channel.HostServer       = this;
     channel.OnPeerConnected += (sender, e) => OnPeerConnected.Raise(this, e);
     channel.PacketProcessor  = _channelMgr.GetMainChannel().PacketProcessor;
     return(true);
 }
Exemple #4
0
        /// <summary>
        /// Creates a channel using <see cref="ChannelManager.CreateChannel{T}()"/> and adds it to this server
        /// </summary>
        /// <remarks>
        /// May throw a <see cref="ChannelOperationException"/> if used incorrectly
        /// </remarks>
        /// <code>
        /// CreateAndAddChannel{T}(ch => {
        ///     ch.Name = "Example";
        ///     ch.Port = 1000;
        ///     ...
        /// });
        /// </code>
        /// <typeparam name="T">The type of channel to create</typeparam>
        /// <param name="channelAction">An action to set channel data</param>
        /// <returns>Returns true if channel was created and added successfully</returns>
        public bool CreateAndAddChannel <T>(Action <T> channelAction) where T : IServerChannel
        {
            var channel = (IServerChannel)_channelMgr.CreateChannel <T>();

            channelAction((T)channel);
            if (!_channelMgr.AddChannel(channel))
            {
                return(false);
            }
            channel.HostServer = this;
            OnChannelCreated.Raise(this, new ChannelEventArgs(channel));
            channel.OnPeerConnected += OnPeerConnected;
            return(true);
        }
        private void SocketDataReceived(object sender, WebSocketSharp.MessageEventArgs result)
        {
            GatewayResponse payload = result.Data.Deserialize <GatewayResponse>();

            Sequence = payload.Sequence;

            switch (payload.Opcode)
            {
            case GatewayOpcode.Event:
                switch (payload.Title)
                {
                case "READY":
                    LoggedIn = true;
                    Login login = payload.Deserialize <Login>().SetJson(payload.Deserialize <JObject>()).SetClient(this);

                    this.User      = login.User;
                    this.SessionId = login.SessionId;
                    OnLoggedIn?.Invoke(this, new LoginEventArgs(login));
                    break;

                case "USER_SETTINGS_UPDATE":
                    OnSettingsUpdated?.Invoke(this, new SettingsUpdatedEventArgs(payload.Deserialize <Settings>()));
                    break;

                case "USER_UPDATE":
                    User user = payload.Deserialize <User>().SetClient(this);

                    if (user.Id == User.Id)
                    {
                        User.Update(user);
                    }

                    OnUserUpdated?.Invoke(this, new UserEventArgs(user));
                    break;

                case "GUILD_CREATE":
                    OnJoinedGuild?.Invoke(this, new GuildEventArgs(payload.Deserialize <Guild>().SetClient(this)));
                    break;

                case "GUILD_UPDATE":
                    OnGuildUpdated?.Invoke(this, new GuildEventArgs(payload.Deserialize <Guild>().SetClient(this)));
                    break;

                case "GUILD_DELETE":
                    OnLeftGuild?.Invoke(this, new GuildEventArgs(payload.Deserialize <Guild>().SetClient(this)));
                    break;

                case "GUILD_MEMBER_ADD":
                    OnUserJoinedGuild?.Invoke(this, new GuildMemberEventArgs(payload.Deserialize <GuildMemberUpdate>().SetClient(this).Member));
                    break;

                case "GUILD_MEMBER_REMOVE":
                    OnUserLeftGuild?.Invoke(this, new GuildMemberEventArgs(payload.Deserialize <GuildMemberUpdate>().SetClient(this).Member));
                    break;

                case "GUILD_MEMBER_UPDATE":
                    OnGuildMemberUpdated?.Invoke(this, new GuildMemberEventArgs(payload.Deserialize <GuildMember>().SetClient(this)));
                    break;

                case "GUILD_MEMBERS_CHUNK":
                    OnGuildMembersReceived?.Invoke(this, new GuildMembersEventArgs(payload.Deserialize <GuildMemberList>().SetClient(this)));
                    break;

                case "PRESENCE_UPDATE":
                    OnUserPresenceUpdated?.Invoke(this, new PresenceUpdatedEventArgs(payload.Deserialize <PresenceUpdate>()));
                    break;

                case "VOICE_STATE_UPDATE":
                    VoiceState state = payload.Deserialize <VoiceState>().SetClient(this);

                    if (state.ChannelId != null)
                    {
                        OnUserJoinedVoiceChannel?.Invoke(this, new VoiceStateEventArgs(state));
                    }
                    else
                    {
                        OnUserLeftVoiceChannel?.Invoke(this, new VoiceStateEventArgs(state));
                    }
                    break;

                case "GUILD_ROLE_CREATE":
                    OnRoleCreated?.Invoke(this, new RoleEventArgs(payload.Deserialize <RoleContainer>().Role.SetClient(this)));
                    break;

                case "GUILD_ROLE_UPDATE":
                    OnRoleUpdated?.Invoke(this, new RoleEventArgs(payload.Deserialize <RoleContainer>().Role.SetClient(this)));
                    break;

                case "GUILD_EMOJIS_UPDATE":
                    OnEmojisUpdated?.Invoke(this, new EmojisUpdatedEventArgs(payload.Deserialize <EmojiContainer>().SetClient(this)));
                    break;

                case "CHANNEL_CREATE":
                    OnChannelCreated?.Invoke(this, new ChannelEventArgs(payload.Deserialize <GuildChannel>().SetClient(this)));
                    break;

                case "CHANNEL_UPDATE":
                    OnChannelUpdated?.Invoke(this, new ChannelEventArgs(payload.Deserialize <GuildChannel>().SetClient(this)));
                    break;

                case "CHANNEL_DELETE":
                    OnChannelDeleted?.Invoke(this, new ChannelEventArgs(payload.Deserialize <GuildChannel>().SetClient(this)));
                    break;

                case "TYPING_START":
                    OnUserTyping?.Invoke(this, new UserTypingEventArgs(payload.Deserialize <UserTyping>()));
                    break;

                case "MESSAGE_CREATE":
                    OnMessageReceived?.Invoke(this, new MessageEventArgs(payload.Deserialize <Message>().SetClient(this)));
                    break;

                case "MESSAGE_UPDATE":
                    OnMessageEdited?.Invoke(this, new MessageEventArgs(payload.Deserialize <Message>().SetClient(this)));
                    break;

                case "MESSAGE_DELETE":
                    OnMessageDeleted?.Invoke(this, new MessageDeletedEventArgs(payload.Deserialize <DeletedMessage>()));
                    break;

                case "MESSAGE_REACTION_ADD":
                    OnMessageReactionAdded?.Invoke(this, new ReactionEventArgs(payload.Deserialize <MessageReactionUpdate>().SetClient(this)));
                    break;

                case "MESSAGE_REACTION_REMOVE":
                    OnMessageReactionRemoved?.Invoke(this, new ReactionEventArgs(payload.Deserialize <MessageReactionUpdate>().SetClient(this)));
                    break;

                case "GUILD_BAN_ADD":
                    OnUserBanned?.Invoke(this, new BanUpdateEventArgs(payload.Deserialize <BanContainer>().SetClient(this)));
                    break;

                case "GUILD_BAN_REMOVE":
                    OnUserUnbanned?.Invoke(this, new BanUpdateEventArgs(payload.Deserialize <BanContainer>().SetClient(this)));
                    break;

                case "RELATIONSHIP_ADD":
                    OnRelationshipAdded?.Invoke(this, new RelationshipEventArgs(payload.Deserialize <Relationship>().SetClient(this)));
                    break;

                case "RELATIONSHIP_REMOVE":
                    OnRelationshipRemoved?.Invoke(this, new RelationshipEventArgs(payload.Deserialize <Relationship>().SetClient(this)));
                    break;

                case "USER_CONNECTIONS_UPDATE":
                    Task.Run(() =>
                    {
                        DiscordProfile profile = this.User.GetProfile();
                        OnProfileUpdated?.Invoke(this, new ProfileUpdatedEventArgs(profile));
                    });
                    break;
                }
                break;

            case GatewayOpcode.InvalidSession:
                this.LoginToGateway();
                break;

            case GatewayOpcode.Connected:
                if (!LoggedIn)
                {
                    this.LoginToGateway();
                }
                else
                {
                    this.Resume();
                }

                this.StartHeartbeatHandlersAsync(payload.Deserialize <JObject>().GetValue("heartbeat_interval").ToObject <uint>());
                break;
            }
        }
Exemple #6
0
        private void SocketDataReceived(object sender, WebSocketSharp.MessageEventArgs result)
        {
            var payload = JsonConvert.DeserializeObject <GatewayResponse>(result.Data);

            Sequence = payload.Sequence;

            switch (payload.Opcode)
            {
            case GatewayOpcode.Event:
                switch (payload.Title)
                {
                case "READY":
                    LoggedIn = true;

                    GatewayLogin lgn = JsonConvert.DeserializeObject <GatewayLogin>(payload.Data.ToString());
                    this.User = lgn.User;
                    OnLoggedIn?.Invoke(this, new UserEventArgs(this.User));
                    break;

                case "GUILD_CREATE":
                    Guild cGuild = JsonConvert.DeserializeObject <Guild>(payload.Data.ToString());
                    cGuild.Client = this;

                    OnJoinedGuild?.Invoke(this, new GuildEventArgs(cGuild));
                    break;

                case "GUILD_UPDATE":
                    Guild uGuild = JsonConvert.DeserializeObject <Guild>(payload.Data.ToString());
                    uGuild.Client = this;

                    OnGuildUpdated?.Invoke(this, new GuildEventArgs(uGuild));
                    break;

                case "GUILD_DELETE":
                    Guild dGuild = JsonConvert.DeserializeObject <Guild>(payload.Data.ToString());
                    dGuild.Client = this;

                    OnLeftGuild?.Invoke(this, new GuildEventArgs(dGuild));
                    break;

                case "CHANNEL_CREATE":
                    Channel cChannel = JsonConvert.DeserializeObject <Channel>(payload.Data.ToString());
                    cChannel.Client = this;

                    OnChannelCreated?.Invoke(this, new ChannelEventArgs(cChannel));
                    break;

                case "CHANNEL_UPDATE":
                    Channel uChannel = JsonConvert.DeserializeObject <Channel>(payload.Data.ToString());
                    uChannel.Client = this;

                    OnChannelUpdated?.Invoke(this, new ChannelEventArgs(uChannel));
                    break;

                case "CHANNEL_DELETE":
                    Channel dChannel = JsonConvert.DeserializeObject <Channel>(payload.Data.ToString());
                    dChannel.Client = this;

                    OnChannelDeleted?.Invoke(this, new ChannelEventArgs(dChannel));
                    break;

                case "GUILD_ROLE_CREATE":
                    GatewayRole cRole = JsonConvert.DeserializeObject <GatewayRole>(payload.Data.ToString());
                    cRole.Role.Client = this;

                    OnRoleCreated?.Invoke(this, new RoleEventArgs(cRole.Role));
                    break;

                case "GUILD_ROLE_UPDATE":
                    GatewayRole uRole = JsonConvert.DeserializeObject <GatewayRole>(payload.Data.ToString());
                    uRole.Role.Client = this;

                    OnRoleUpdated?.Invoke(this, new RoleEventArgs(uRole.Role));
                    break;

                case "MESSAGE_CREATE":
                    Message cMsg = JsonConvert.DeserializeObject <Message>(payload.Data.ToString());
                    cMsg.Client = this;

                    OnMessageReceived?.Invoke(this, new MessageEventArgs(cMsg));
                    break;

                case "MESSAGE_UPDATE":
                    Message uMsg = JsonConvert.DeserializeObject <Message>(payload.Data.ToString());
                    uMsg.Client = this;

                    OnMessageEdited?.Invoke(this, new MessageEventArgs(uMsg));
                    break;

                case "MESSAGE_DELETE":
                    OnMessageDeleted?.Invoke(this, new MessageDeletedEventArgs(JsonConvert.DeserializeObject <MessageDelete>(payload.Data.ToString())));
                    break;
                }
                break;

            case GatewayOpcode.InvalidSession:
                Logout();
                break;

            case GatewayOpcode.Connected:
                //keep sending heartbeats every x second so the client's socket don't get closed
                Task.Run(async() => await this.StartHeartbeatHandlersAsync(JsonConvert.DeserializeObject <GatewayHeartbeat>(payload.Data.ToString()).Interval));

                this.LoginToGateway();
                break;
            }
        }
        private void WebSocket_OnMessageReceived(object sender, DiscordWebSocketMessage <GatewayOpcode> message)
        {
            Sequence = message.Sequence;

            switch (message.Opcode)
            {
            case GatewayOpcode.Event:
                /*
                 * Console.WriteLine(message.EventName);
                 *
                 * File.AppendAllText("Debug.log", $"{message.EventName}: {message.Data}\n");
                 */

                switch (message.EventName)
                {
                case "READY":
                    LoginEventArgs login = message.Data.ToObject <LoginEventArgs>().SetClient(this);

                    if (login.Application != null)
                    {
                        _appId = login.Application.Value <ulong>("id");
                    }

                    this.User         = login.User;
                    this.UserSettings = login.Settings;
                    this.SessionId    = login.SessionId;

                    if (Config.Cache && this.User.Type == DiscordUserType.User)
                    {
                        PrivateChannels.AddRange(login.PrivateChannels);

                        foreach (var presence in login.Presences)
                        {
                            Presences[presence.UserId] = presence;
                        }

                        foreach (var guild in login.Guilds)
                        {
                            ApplyGuild(GuildCache[guild.Id] = (SocketGuild)guild);
                            VoiceClients[guild.Id]          = new DiscordVoiceClient(this, guild.Id);
                        }

                        foreach (var settings in login.ClientGuildSettings)
                        {
                            if (settings.GuildId.HasValue)
                            {
                                GuildSettings.Add(settings.Guild.Id, settings);
                            }
                            else
                            {
                                PrivateChannelSettings = settings.ChannelOverrides.ToList();
                            }
                        }
                    }

                    LoggedIn = true;
                    State    = GatewayConnectionState.Connected;

                    if (OnLoggedIn != null)
                    {
                        Task.Run(() => OnLoggedIn.Invoke(this, login));
                    }
                    break;

                case "USER_SETTINGS_UPDATE":
                    if (UserSettings == null)
                    {
                    }

                    UserSettings.Update((JObject)message.Data);

                    if (OnSettingsUpdated != null)
                    {
                        Task.Run(() => OnSettingsUpdated.Invoke(this, new DiscordSettingsEventArgs(UserSettings)));
                    }
                    break;

                case "USER_GUILD_SETTINGS_UPDATE":
                    if (Config.Cache)
                    {
                        ClientGuildSettings settings = message.Data.ToObject <ClientGuildSettings>();

                        if (settings.GuildId.HasValue)
                        {
                            GuildSettings[settings.Guild.Id] = settings;
                        }
                        else
                        {
                            PrivateChannelSettings = settings.ChannelOverrides.ToList();
                        }
                    }
                    break;

                case "USER_UPDATE":
                    DiscordUser user = message.Data.ToObject <DiscordUser>().SetClient(this);

                    if (user.Id == User.Id)
                    {
                        User.Update(user);
                    }

                    if (Config.Cache)
                    {
                        lock (PrivateChannels.Lock)
                        {
                            foreach (var dm in PrivateChannels)
                            {
                                foreach (var recipient in dm.Recipients)
                                {
                                    if (recipient.Id == user.Id)
                                    {
                                        recipient.Update(user);

                                        break;
                                    }
                                }
                            }
                        }
                    }

                    if (OnUserUpdated != null)
                    {
                        Task.Run(() => OnUserUpdated.Invoke(this, new UserEventArgs(user)));
                    }
                    break;

                case "GUILD_MEMBER_LIST_UPDATE":
                    OnMemberListUpdate?.Invoke(this, message.Data.ToObject <GuildMemberListEventArgs>());
                    break;

                case "GUILD_CREATE":
                    if (Config.Cache || OnJoinedGuild != null)
                    {
                        var guild = message.Data.ToObject <SocketGuild>().SetClient(this);

                        VoiceClients[guild.Id] = new DiscordVoiceClient(this, guild.Id);

                        if (Config.Cache)
                        {
                            ApplyGuild(GuildCache[guild.Id] = guild);
                        }

                        if (OnJoinedGuild != null)
                        {
                            Task.Run(() => OnJoinedGuild.Invoke(this, new SocketGuildEventArgs(guild, Lurking.HasValue && Lurking.Value == guild.Id)));
                        }
                    }
                    break;

                case "GUILD_UPDATE":
                    if (Config.Cache || OnGuildUpdated != null)
                    {
                        DiscordGuild guild = message.Data.ToObject <DiscordGuild>().SetClient(this);

                        if (Config.Cache)
                        {
                            GuildCache[guild.Id].Update(guild);
                        }

                        Task.Run(() => OnGuildUpdated?.Invoke(this, new GuildEventArgs(guild)));
                    }
                    break;

                case "GUILD_DELETE":
                {
                    UnavailableGuild guild = message.Data.ToObject <UnavailableGuild>();

                    VoiceClients.Remove(guild.Id);

                    if (Lurking.HasValue && Lurking.Value == guild.Id)
                    {
                        Lurking = null;
                    }

                    if (Config.Cache)
                    {
                        if (guild.Unavailable)
                        {
                            GuildCache[guild.Id].Unavailable = true;
                        }
                        else
                        {
                            GuildCache.Remove(guild.Id);
                            GuildSettings.Remove(guild.Id);
                        }
                    }

                    if (OnLeftGuild != null)
                    {
                        Task.Run(() => OnLeftGuild.Invoke(this, new GuildUnavailableEventArgs(guild)));
                    }
                }
                break;

                case "GUILD_MEMBER_ADD":
                    if (Config.Cache || OnUserJoinedGuild != null)
                    {
                        var member = message.Data.ToObject <GuildMember>().SetClient(this);

                        if (Config.Cache)
                        {
                            GuildCache[member.GuildId].MemberCount++;
                        }

                        Task.Run(() => OnUserJoinedGuild?.Invoke(this, new GuildMemberEventArgs(member)));
                    }
                    break;

                case "GUILD_MEMBER_REMOVE":
                    if (Config.Cache || OnUserLeftGuild != null)
                    {
                        var member = message.Data.ToObject <PartialGuildMember>().SetClient(this);

                        if (Config.Cache)
                        {
                            GuildCache[member.GuildId].MemberCount--;
                        }

                        Task.Run(() => OnUserLeftGuild?.Invoke(this, new MemberRemovedEventArgs(member)));
                    }
                    break;

                case "GUILD_MEMBER_UPDATE":
                    if (Config.Cache || OnGuildMemberUpdated != null)
                    {
                        GuildMember member = message.Data.ToObject <GuildMember>().SetClient(this);

                        if (Config.Cache && member.User.Id == User.Id)
                        {
                            SocketGuild guild = this.GetCachedGuild(member.GuildId);

                            // Discord doesn't send us the user's JoinedAt on updates
                            member.JoinedAt         = guild.ClientMember.JoinedAt;
                            ClientMembers[guild.Id] = member;

                            break;
                        }

                        Task.Run(() => OnGuildMemberUpdated.Invoke(this, new GuildMemberEventArgs(member)));
                    }
                    break;

                case "GUILD_MEMBERS_CHUNK":
                    Task.Run(() => OnGuildMembersReceived?.Invoke(this, new GuildMembersEventArgs(message.Data.ToObject <GuildMemberList>().SetClient(this))));
                    break;

                case "GIFT_CODE_CREATE":
                    if (OnGiftCodeCreated != null)
                    {
                        Task.Run(() => OnGiftCodeCreated.Invoke(this, message.Data.ToObject <GiftCodeCreatedEventArgs>()));
                    }
                    break;

                case "GIFT_CODE_UPDATE":
                    if (OnGiftUpdated != null)
                    {
                        var gift = message.Data.ToObject <GiftCodeUpdatedEventArgs>().SetClient(this);
                        gift.Json = (JObject)message.Data;

                        Task.Run(() => OnGiftUpdated.Invoke(this, gift));
                    }
                    break;

                case "PRESENCE_UPDATE":
                    if (Config.Cache || OnUserPresenceUpdated != null)
                    {
                        var presence = message.Data.ToObject <DiscordPresence>().SetClient(this);

                        if (Config.Cache)
                        {
                            if (Presences.TryGetValue(presence.UserId, out DiscordPresence existingPresence))
                            {
                                existingPresence.Update(presence);
                                presence = existingPresence;
                            }
                            else
                            {
                                Presences[presence.UserId] = presence;
                            }
                        }

                        if (OnUserPresenceUpdated != null)
                        {
                            Task.Run(() => OnUserPresenceUpdated.Invoke(this, new PresenceUpdatedEventArgs(presence)));
                        }
                    }
                    break;

                case "VOICE_STATE_UPDATE":
                    DiscordVoiceState newState = message.Data.ToObject <DiscordVoiceState>().SetClient(this);

                    if (Config.Cache)
                    {
                        if (newState.Guild == null)
                        {
                            VoiceStates[newState.UserId].PrivateChannelVoiceState = newState;
                        }
                        else
                        {
                            VoiceStates[newState.UserId].GuildStates[newState.Guild.Id] = newState;
                        }

                        // we also store voice states within SocketGuilds, so make sure to update those.
                        foreach (var guild in this.GetCachedGuilds())
                        {
                            if (!guild.Unavailable)
                            {
                                if (newState.Guild == null || guild.Id != newState.Guild.Id)
                                {
                                    guild._voiceStates.RemoveFirst(s => s.UserId == newState.UserId);
                                }
                                else
                                {
                                    int i = guild._voiceStates.FindIndex(s => s.UserId == newState.UserId);

                                    if (i > -1)
                                    {
                                        guild._voiceStates[i] = newState;
                                    }
                                    else
                                    {
                                        guild._voiceStates.Add(newState);
                                    }
                                }
                            }
                        }
                    }

                    if (newState.UserId == User.Id)
                    {
                        if (newState.Guild == null)
                        {
                            VoiceClients.Private.SetSessionId(newState.SessionId);
                        }
                        else
                        {
                            VoiceClients[newState.Guild.Id].SetSessionId(newState.SessionId);
                        }
                    }

                    if (OnVoiceStateUpdated != null)
                    {
                        Task.Run(() => OnVoiceStateUpdated.Invoke(this, new VoiceStateEventArgs(newState)));
                    }
                    break;

                case "VOICE_SERVER_UPDATE":
                    OnMediaServer?.Invoke(this, message.Data.ToObject <DiscordMediaServer>().SetClient(this));
                    break;

                case "GUILD_ROLE_CREATE":
                    if (Config.Cache || OnRoleCreated != null)
                    {
                        DiscordRole role = message.Data.ToObject <RoleUpdate>().Role.SetClient(this);

                        if (Config.Cache)
                        {
                            GuildCache[role.GuildId]._roles.Add(role);
                        }

                        if (OnRoleCreated != null)
                        {
                            Task.Run(() => OnRoleCreated.Invoke(this, new RoleEventArgs(role)));
                        }
                    }
                    break;

                case "GUILD_ROLE_UPDATE":
                    if (Config.Cache || OnRoleUpdated != null)
                    {
                        DiscordRole role = message.Data.ToObject <RoleUpdate>().Role.SetClient(this);

                        if (Config.Cache)
                        {
                            GuildCache[role.GuildId]._roles.ReplaceFirst(r => r.Id == role.Id, role);
                        }

                        if (OnRoleUpdated != null)
                        {
                            Task.Run(() => OnRoleUpdated.Invoke(this, new RoleEventArgs(role)));
                        }
                    }
                    break;

                case "GUILD_ROLE_DELETE":
                    if (Config.Cache || OnRoleDeleted != null)
                    {
                        DeletedRole role = message.Data.ToObject <DeletedRole>().SetClient(this);

                        if (Config.Cache)
                        {
                            GuildCache[role.Guild]._roles.RemoveFirst(r => r.Id == role.Id);
                        }

                        if (OnRoleDeleted != null)
                        {
                            Task.Run(() => OnRoleDeleted.Invoke(this, new RoleDeletedEventArgs(role)));
                        }
                    }
                    break;

                case "GUILD_EMOJIS_UPDATE":
                    if (Config.Cache || OnEmojisUpdated != null)
                    {
                        var emojis = message.Data.ToObject <EmojiContainer>().SetClient(this);

                        if (Config.Cache)
                        {
                            GuildCache[emojis.GuildId]._emojis = emojis.Emojis.ToList();
                        }

                        if (OnEmojisUpdated != null)
                        {
                            Task.Run(() => OnEmojisUpdated.Invoke(this, new EmojisUpdatedEventArgs(emojis)));
                        }
                    }
                    break;

                case "CHANNEL_CREATE":
                    if (Config.Cache || OnChannelCreated != null)
                    {
                        var channel = ((JObject)message.Data).ParseDeterministic <DiscordChannel>();

                        if (Config.Cache)
                        {
                            if (channel.Type == ChannelType.DM || channel.Type == ChannelType.Group)
                            {
                                PrivateChannels.Add((PrivateChannel)channel);
                            }
                            else
                            {
                                GuildChannel guildChannel = (GuildChannel)channel;

                                GuildCache[guildChannel.GuildId].ChannelsConcurrent.Add(guildChannel);
                            }
                        }

                        if (OnChannelCreated != null)
                        {
                            Task.Run(() => OnChannelCreated.Invoke(this, new ChannelEventArgs(channel)));
                        }
                    }
                    break;

                case "CHANNEL_UPDATE":
                    if (Config.Cache || OnChannelUpdated != null)
                    {
                        var channel = ((JObject)message.Data).ParseDeterministic <DiscordChannel>();

                        if (Config.Cache)
                        {
                            if (channel.Type == ChannelType.DM || channel.Type == ChannelType.Group)
                            {
                                PrivateChannels.ReplaceFirst(c => c.Id == channel.Id, (PrivateChannel)channel);
                            }
                            else
                            {
                                GuildChannel guildChannel = (GuildChannel)channel;
                                GuildCache[guildChannel.GuildId].ChannelsConcurrent.ReplaceFirst(c => c.Id == guildChannel.Id, guildChannel);
                            }
                        }

                        if (OnChannelUpdated != null)
                        {
                            Task.Run(() => OnChannelUpdated.Invoke(this, new ChannelEventArgs(channel)));
                        }
                    }
                    break;

                case "CHANNEL_DELETE":
                    if (Config.Cache || OnChannelDeleted != null)
                    {
                        var channel = ((JObject)message.Data).ParseDeterministic <DiscordChannel>();

                        if (Config.Cache)
                        {
                            if (channel.Type == ChannelType.DM || channel.Type == ChannelType.Group)
                            {
                                PrivateChannels.RemoveFirst(c => c.Id == channel.Id);
                            }
                            else
                            {
                                GuildCache[((GuildChannel)channel).GuildId].ChannelsConcurrent.RemoveFirst(c => c.Id == channel.Id);
                            }
                        }

                        if (OnChannelDeleted != null)
                        {
                            Task.Run(() => OnChannelDeleted.Invoke(this, new ChannelEventArgs(channel)));
                        }
                    }
                    break;

                case "TYPING_START":
                    if (OnUserTyping != null)
                    {
                        Task.Run(() => OnUserTyping.Invoke(this, new UserTypingEventArgs(message.Data.ToObject <UserTyping>().SetClient(this))));
                    }
                    break;

                case "MESSAGE_CREATE":
                    if (Config.Cache || OnMessageReceived != null)
                    {
                        var newMessage = message.Data.ToObject <DiscordMessage>().SetClient(this);

                        if (Config.Cache)
                        {
                            try
                            {
                                this.GetChannel(newMessage.Channel.Id).SetLastMessageId(newMessage.Id);
                            }
                            catch (DiscordHttpException) { }
                        }

                        if (OnMessageReceived != null)
                        {
                            Task.Run(() => OnMessageReceived.Invoke(this, new MessageEventArgs(newMessage)));
                        }
                    }
                    break;

                case "MESSAGE_UPDATE":
                    if (OnMessageEdited != null)
                    {
                        Task.Run(() => OnMessageEdited.Invoke(this, new MessageEventArgs(message.Data.ToObject <DiscordMessage>().SetClient(this))));
                    }
                    break;

                case "MESSAGE_DELETE":
                    if (OnMessageDeleted != null)
                    {
                        Task.Run(() => OnMessageDeleted.Invoke(this, new MessageDeletedEventArgs(message.Data.ToObject <DeletedMessage>().SetClient(this))));
                    }
                    break;

                case "MESSAGE_REACTION_ADD":
                    if (OnMessageReactionAdded != null)
                    {
                        Task.Run(() => OnMessageReactionAdded.Invoke(this, new ReactionEventArgs(message.Data.ToObject <MessageReactionUpdate>().SetClient(this))));
                    }
                    break;

                case "MESSAGE_REACTION_REMOVE":
                    if (OnMessageReactionRemoved != null)
                    {
                        Task.Run(() => OnMessageReactionRemoved.Invoke(this, new ReactionEventArgs(message.Data.ToObject <MessageReactionUpdate>().SetClient(this))));
                    }
                    break;

                case "GUILD_BAN_ADD":
                    if (OnUserBanned != null)
                    {
                        Task.Run(() => OnUserBanned.Invoke(this, message.Data.ToObject <BanUpdateEventArgs>().SetClient(this)));
                    }
                    break;

                case "GUILD_BAN_REMOVE":
                    if (OnUserUnbanned != null)
                    {
                        Task.Run(() => OnUserUnbanned.Invoke(this, message.Data.ToObject <BanUpdateEventArgs>().SetClient(this)));
                    }
                    break;

                case "INVITE_CREATE":
                    if (OnInviteCreated != null)
                    {
                        Task.Run(() => OnInviteCreated.Invoke(this, message.Data.ToObject <InviteCreatedEventArgs>().SetClient(this)));
                    }
                    break;

                case "INVITE_DELETE":
                    if (OnInviteDeleted != null)
                    {
                        Task.Run(() => OnInviteDeleted.Invoke(this, message.Data.ToObject <InviteDeletedEventArgs>().SetClient(this)));
                    }
                    break;

                case "RELATIONSHIP_ADD":
                    if (OnRelationshipAdded != null)
                    {
                        Task.Run(() => OnRelationshipAdded.Invoke(this, new RelationshipEventArgs(message.Data.ToObject <DiscordRelationship>().SetClient(this))));
                    }
                    break;

                case "RELATIONSHIP_REMOVE":
                    if (OnRelationshipRemoved != null)
                    {
                        Task.Run(() => OnRelationshipRemoved.Invoke(this, message.Data.ToObject <RemovedRelationshipEventArgs>()));
                    }
                    break;

                case "CHANNEL_RECIPIENT_ADD":
                    if (Config.Cache || OnChannelRecipientAdded != null)
                    {
                        var recipUpdate = message.Data.ToObject <ChannelRecipientEventArgs>().SetClient(this);

                        if (Config.Cache)
                        {
                            ((PrivateChannel)this.GetChannel(recipUpdate.Channel.Id))._recipients.Add(recipUpdate.User);
                        }

                        if (OnChannelRecipientAdded != null)
                        {
                            Task.Run(() => OnChannelRecipientAdded.Invoke(this, recipUpdate));
                        }
                    }
                    break;

                case "CHANNEL_RECIPIENT_REMOVE":
                    if (Config.Cache || OnChannelRecipientAdded != null)
                    {
                        var recipUpdate = message.Data.ToObject <ChannelRecipientEventArgs>().SetClient(this);

                        if (Config.Cache)
                        {
                            ((PrivateChannel)this.GetChannel(recipUpdate.Channel.Id))._recipients.RemoveFirst(u => u.Id == recipUpdate.User.Id);
                        }

                        if (OnChannelRecipientRemoved != null)
                        {
                            Task.Run(() => OnChannelRecipientRemoved.Invoke(this, recipUpdate));
                        }
                    }
                    break;

                case "MESSAGE_ACK":         // triggered whenever another person logged into the account acknowledges a message
                    break;

                case "SESSIONS_REPLACE":
                    if (OnSessionsUpdated != null)
                    {
                        Task.Run(() => OnSessionsUpdated.Invoke(this, new DiscordSessionsEventArgs(message.Data.ToObject <List <DiscordSession> >())));
                    }
                    break;

                case "CALL_CREATE":
                    if (Config.Cache || OnRinging != null)
                    {
                        var call        = message.Data.ToObject <DiscordCall>().SetClient(this);
                        var voiceStates = message.Data.Value <JToken>("voice_states").ToObject <IReadOnlyList <DiscordVoiceState> >().SetClientsInList(this);

                        if (Config.Cache)
                        {
                            foreach (var state in voiceStates)
                            {
                                VoiceStates[state.UserId].PrivateChannelVoiceState = state;
                            }
                        }

                        if (OnRinging != null)
                        {
                            Task.Run(() => OnRinging.Invoke(this, new RingingEventArgs(call, voiceStates)));
                        }
                    }
                    break;

                case "CALL_UPDATE":
                    if (OnCallUpdated != null)
                    {
                        Task.Run(() => OnCallUpdated.Invoke(this, new CallUpdateEventArgs(message.Data.ToObject <DiscordCall>().SetClient(this))));
                    }
                    break;

                case "CALL_DELETE":
                    if (Config.Cache || OnCallEnded != null)
                    {
                        ulong channelId = message.Data.Value <ulong>("channel_id");

                        if (Config.Cache)
                        {
                            foreach (var state in VoiceStates.CreateCopy().Values)
                            {
                                var privState = state.PrivateChannelVoiceState;

                                if (privState != null && privState.Channel != null && privState.Channel.Id == channelId)
                                {
                                    state.PrivateChannelVoiceState = null;
                                }
                            }
                        }

                        if (OnCallEnded != null)
                        {
                            Task.Run(() => OnCallEnded.Invoke(this, new MinimalTextChannel(channelId).SetClient(this)));
                        }
                    }
                    break;

                case "ENTITLEMENT_CREATE":
                    if (OnEntitlementCreated != null)
                    {
                        Task.Run(() => OnEntitlementCreated.Invoke(this, new EntitlementEventArgs(message.Data.ToObject <DiscordEntitlement>())));
                    }
                    break;

                case "ENTITLEMENT_UPDATE":
                    if (OnEntitlementUpdated != null)
                    {
                        Task.Run(() => OnEntitlementUpdated.Invoke(this, new EntitlementEventArgs(message.Data.ToObject <DiscordEntitlement>())));
                    }
                    break;

                case "USER_PREMIUM_GUILD_SUBSCRIPTION_SLOT_CREATE":
                    if (OnBoostSlotCreated != null)
                    {
                        Task.Run(() => OnBoostSlotCreated.Invoke(this, new NitroBoostEventArgs(message.Data.ToObject <DiscordBoostSlot>().SetClient(this))));
                    }
                    break;

                case "USER_PREMIUM_GUILD_SUBSCRIPTION_SLOT_UPDATE":
                    if (OnBoostSlotUpdated != null)
                    {
                        Task.Run(() => OnBoostSlotUpdated.Invoke(this, new NitroBoostEventArgs(message.Data.ToObject <DiscordBoostSlot>().SetClient(this))));
                    }
                    break;

                case "STREAM_SERVER_UPDATE":
                    OnMediaServer?.Invoke(this, message.Data.ToObject <DiscordMediaServer>().SetClient(this));
                    break;

                case "STREAM_CREATE":
                    var create = message.Data.ToObject <GoLiveCreate>();
                    GetVoiceClient(new StreamKey(create.StreamKey).GuildId).Livestream.CreateSession(create);
                    break;

                case "STREAM_UPDATE":
                    var update = message.Data.ToObject <GoLiveUpdate>();
                    GetVoiceClient(new StreamKey(update.StreamKey).GuildId).Livestream.UpdateSession(update);
                    break;

                case "STREAM_DELETE":
                    var delete = message.Data.ToObject <GoLiveDelete>();
                    GetVoiceClient(new StreamKey(delete.StreamKey).GuildId).Livestream.KillSession(delete);
                    break;

                case "CHANNEL_UNREAD_UPDATE":
                    if (Config.Cache || OnGuildUnreadMessagesUpdated != null)
                    {
                        var unread = message.Data.ToObject <GuildUnreadMessages>().SetClient(this);

                        if (Config.Cache)
                        {
                            foreach (var unreadChannel in unread.Channels)
                            {
                                this.GetChannel(unreadChannel.Channel.Id).SetLastMessageId(unreadChannel.LastMessageId);
                            }
                        }

                        if (OnGuildUnreadMessagesUpdated != null)
                        {
                            Task.Run(() => OnGuildUnreadMessagesUpdated.Invoke(this, new UnreadMessagesEventArgs(unread)));
                        }
                    }
                    break;

                case "INTERACTION_CREATE":
                    if (OnInteraction != null)
                    {
                        Task.Run(() => OnInteraction.Invoke(this, new DiscordInteractionEventArgs(message.Data.ToObject <DiscordInteraction>().SetClient(this))));
                    }
                    break;

                case "USER_REQUIRED_ACTION_UPDATE":
                    if (OnRequiredUserAction != null)
                    {
                        Task.Run(() => OnRequiredUserAction.Invoke(this, message.Data.ToObject <RequiredActionEventArgs>()));
                    }
                    break;

                default:
                    break;
                }
                break;

            case GatewayOpcode.InvalidSession:
                LoggedIn = false;

                this.LoginToGateway();
                break;

            case GatewayOpcode.Connected:
                this.LoginToGateway();

                Task.Run(() =>
                {
                    int interval = message.Data.ToObject <JObject>().GetValue("heartbeat_interval").ToObject <int>() - 1000;

                    try
                    {
                        while (true)
                        {
                            this.Send(GatewayOpcode.Heartbeat, this.Sequence);
                            Thread.Sleep(interval);
                        }
                    }
                    catch { }
                });

                break;
            }
        }
Exemple #8
0
        private void SocketDataReceived(object sender, WebSocketSharp.MessageEventArgs result)
        {
            GatewayResponse payload = result.Data.Deserialize <GatewayResponse>();

            Sequence = payload.Sequence;

            System.Console.WriteLine(payload.ToString());

            switch (payload.Opcode)
            {
            case GatewayOpcode.Event:
                switch (payload.Title)
                {
                case "READY":
                    LoggedIn = true;
                    Login login = payload.Deserialize <Login>().SetClient(this);
                    this.User = login.User;
                    OnLoggedIn?.Invoke(this, new LoginEventArgs(payload.Deserialize <Login>().SetClient(this)));
                    break;

                case "GUILD_CREATE":
                    OnJoinedGuild?.Invoke(this, new GuildEventArgs(payload.Deserialize <Guild>().SetClient(this)));
                    break;

                case "GUILD_UPDATE":
                    OnGuildUpdated?.Invoke(this, new GuildEventArgs(payload.Deserialize <Guild>().SetClient(this)));
                    break;

                case "GUILD_DELETE":
                    OnLeftGuild?.Invoke(this, new GuildEventArgs(payload.Deserialize <Guild>().SetClient(this)));
                    break;

                case "GUILD_MEMBERS_CHUNK":
                    GuildMemberList list = payload.Deserialize <GuildMemberList>().SetClient(this);
                    foreach (var member in list.Members)
                    {
                        member.GuildId = list.GuildId;
                    }

                    OnGuildMembersReceived?.Invoke(this, new GuildMembersEventArgs(list.Members));
                    break;

                case "PRESENCE_UPDATE":
                    OnUserPresenceUpdated?.Invoke(this, new PresenceUpdatedEventArgs(payload.Deserialize <PresenceUpdate>()));
                    break;

                case "CHANNEL_CREATE":
                    OnChannelCreated?.Invoke(this, new ChannelEventArgs(payload.Deserialize <GuildChannel>().SetClient(this)));
                    break;

                case "CHANNEL_UPDATE":
                    OnChannelUpdated?.Invoke(this, new ChannelEventArgs(payload.Deserialize <GuildChannel>().SetClient(this)));
                    break;

                case "CHANNEL_DELETE":
                    OnChannelDeleted?.Invoke(this, new ChannelEventArgs(payload.Deserialize <GuildChannel>().SetClient(this)));
                    break;

                case "GUILD_ROLE_CREATE":
                    OnRoleCreated?.Invoke(this, new RoleEventArgs(payload.Deserialize <GatewayRole>().Role.SetClient(this)));
                    break;

                case "GUILD_ROLE_UPDATE":
                    OnRoleUpdated?.Invoke(this, new RoleEventArgs(payload.Deserialize <GatewayRole>().Role.SetClient(this)));
                    break;

                case "GUILD_EMOJIS_UPDATE":
                    OnEmojisUpdated?.Invoke(this, new EmojisUpdatedEventArgs(payload.Deserialize <EmojiContainer>().SetClient(this)));
                    break;

                case "MESSAGE_CREATE":
                    OnMessageReceived?.Invoke(this, new MessageEventArgs(payload.Deserialize <Message>().SetClient(this)));
                    break;

                case "MESSAGE_UPDATE":
                    OnMessageEdited?.Invoke(this, new MessageEventArgs(payload.Deserialize <Message>().SetClient(this)));
                    break;

                case "MESSAGE_DELETE":
                    OnMessageDeleted?.Invoke(this, new MessageDeletedEventArgs(payload.Deserialize <DeletedMessage>()));
                    break;

                case "MESSAGE_REACTION_ADD":
                    OnMessageReactionAdded?.Invoke(this, new ReactionEventArgs(payload.Deserialize <MessageReactionUpdate>().SetClient(this)));
                    break;

                case "MESSAGE_REACTION_REMOVE":
                    OnMessageReactionRemoved?.Invoke(this, new ReactionEventArgs(payload.Deserialize <MessageReactionUpdate>().SetClient(this)));
                    break;

                case "GUILD_BAN_ADD":
                    OnUserBanned?.Invoke(this, new BanUpdateEventArgs(payload.Deserialize <BanContainer>().SetClient(this)));
                    break;

                case "GUILD_BAN_REMOVE":
                    OnUserUnbanned?.Invoke(this, new BanUpdateEventArgs(payload.Deserialize <BanContainer>().SetClient(this)));
                    break;
                }
                break;

            case GatewayOpcode.InvalidSession:
                Logout();
                break;

            case GatewayOpcode.Connected:
                this.StartHeartbeatHandlersAsync(payload.Deserialize <GatewayHeartbeat>().Interval);
                this.LoginToGateway();
                break;
            }
        }
        private void SocketDataReceived(object sender, WebSocketSharp.MessageEventArgs result)
        {
            GatewayResponse payload = result.Data.Deserialize <GatewayResponse>();

            Sequence = payload.Sequence;

            Task.Run(() =>
            {
                switch (payload.Opcode)
                {
                case GatewayOpcode.Event:
                    switch (payload.Title)
                    {
                    case "READY":
                        LoggedIn    = true;
                        Login login = payload.Deserialize <Login>().SetJson(payload.Deserialize <JObject>()).SetClient(this);

                        this.User      = login.User;
                        this.SessionId = login.SessionId;
                        OnLoggedIn?.Invoke(this, new LoginEventArgs(login));
                        break;

                    case "USER_SETTINGS_UPDATE":
                        OnSettingsUpdated?.Invoke(this, new SettingsUpdatedEventArgs(payload.Deserialize <Settings>()));
                        break;

                    case "USER_UPDATE":
                        User user = payload.Deserialize <User>().SetClient(this);

                        if (user.Id == User.Id)
                        {
                            User.Update(user);
                        }

                        OnUserUpdated?.Invoke(this, new UserEventArgs(user));
                        break;

                    case "GUILD_MEMBER_LIST_UPDATE":
                        /*
                         * var args = new GuildMembersEventArgs(payload.Deserialize<GatewayUserMemberQueryResponse>());
                         *
                         * foreach (var member in args.Members)
                         * {
                         *  member.SetClient(this);
                         *  member.GuildId = args.GuildId;
                         * }
                         *
                         * OnGuildMembersReceived?.Invoke(this, args);*/
                        break;

                    case "GUILD_CREATE":
                        OnJoinedGuild?.Invoke(this, new SocketGuildEventArgs(payload.Deserialize <SocketGuild>().SetClient(this)));
                        break;

                    case "GUILD_UPDATE":
                        OnGuildUpdated?.Invoke(this, new GuildEventArgs(payload.Deserialize <Guild>().SetClient(this)));
                        break;

                    case "GUILD_DELETE":
                        OnLeftGuild?.Invoke(this, new GuildEventArgs(payload.Deserialize <Guild>().SetClient(this)));
                        break;

                    case "GUILD_MEMBER_ADD":
                        OnUserJoinedGuild?.Invoke(this, new GuildMemberEventArgs(payload.Deserialize <GuildMemberUpdate>().SetClient(this).Member));
                        break;

                    case "GUILD_MEMBER_REMOVE":
                        OnUserLeftGuild?.Invoke(this, new GuildMemberEventArgs(payload.Deserialize <GuildMemberUpdate>().SetClient(this).Member));
                        break;

                    case "GUILD_MEMBER_UPDATE":
                        OnGuildMemberUpdated?.Invoke(this, new GuildMemberEventArgs(payload.Deserialize <GuildMember>().SetClient(this)));
                        break;

                    case "GUILD_MEMBERS_CHUNK":
                        OnGuildMembersReceived?.Invoke(this, new GuildMembersEventArgs(payload.Deserialize <GuildMemberList>().SetClient(this)));
                        break;

                    case "PRESENCE_UPDATE":
                        OnUserPresenceUpdated?.Invoke(this, new PresenceUpdatedEventArgs(payload.Deserialize <PresenceUpdate>()));
                        break;

                    case "VOICE_STATE_UPDATE":
                        OnVoiceStateUpdated?.Invoke(this, new VoiceStateEventArgs(payload.Deserialize <DiscordVoiceState>().SetClient(this)));
                        break;

                    case "VOICE_SERVER_UPDATE":
                        OnVoiceServer?.Invoke(this, payload.Deserialize <DiscordVoiceServer>());
                        break;

                    case "GUILD_ROLE_CREATE":
                        OnRoleCreated?.Invoke(this, new RoleEventArgs(payload.Deserialize <RoleContainer>().Role.SetClient(this)));
                        break;

                    case "GUILD_ROLE_UPDATE":
                        OnRoleUpdated?.Invoke(this, new RoleEventArgs(payload.Deserialize <RoleContainer>().Role.SetClient(this)));
                        break;

                    case "GUILD_EMOJIS_UPDATE":
                        OnEmojisUpdated?.Invoke(this, new EmojisUpdatedEventArgs(payload.Deserialize <EmojiContainer>().SetClient(this)));
                        break;

                    case "CHANNEL_CREATE":
                        OnChannelCreated?.Invoke(this, new ChannelEventArgs(payload.Deserialize <GuildChannel>().SetClient(this)));
                        break;

                    case "CHANNEL_UPDATE":
                        OnChannelUpdated?.Invoke(this, new ChannelEventArgs(payload.Deserialize <GuildChannel>().SetClient(this)));
                        break;

                    case "CHANNEL_DELETE":
                        OnChannelDeleted?.Invoke(this, new ChannelEventArgs(payload.Deserialize <GuildChannel>().SetClient(this)));
                        break;

                    case "TYPING_START":
                        OnUserTyping?.Invoke(this, new UserTypingEventArgs(payload.Deserialize <UserTyping>()));
                        break;

                    case "MESSAGE_CREATE":
                        OnMessageReceived?.Invoke(this, new MessageEventArgs(payload.Deserialize <Message>().SetClient(this)));
                        break;

                    case "MESSAGE_UPDATE":
                        OnMessageEdited?.Invoke(this, new MessageEventArgs(payload.Deserialize <Message>().SetClient(this)));
                        break;

                    case "MESSAGE_DELETE":
                        OnMessageDeleted?.Invoke(this, new MessageDeletedEventArgs(payload.Deserialize <DeletedMessage>()));
                        break;

                    case "MESSAGE_REACTION_ADD":
                        OnMessageReactionAdded?.Invoke(this, new ReactionEventArgs(payload.Deserialize <MessageReactionUpdate>().SetClient(this)));
                        break;

                    case "MESSAGE_REACTION_REMOVE":
                        OnMessageReactionRemoved?.Invoke(this, new ReactionEventArgs(payload.Deserialize <MessageReactionUpdate>().SetClient(this)));
                        break;

                    case "GUILD_BAN_ADD":
                        OnUserBanned?.Invoke(this, new BanUpdateEventArgs(payload.Deserialize <BanContainer>().SetClient(this)));
                        break;

                    case "GUILD_BAN_REMOVE":
                        OnUserUnbanned?.Invoke(this, new BanUpdateEventArgs(payload.Deserialize <BanContainer>().SetClient(this)));
                        break;

                    case "RELATIONSHIP_ADD":
                        OnRelationshipAdded?.Invoke(this, new RelationshipEventArgs(payload.Deserialize <Relationship>().SetClient(this)));
                        break;

                    case "RELATIONSHIP_REMOVE":
                        OnRelationshipRemoved?.Invoke(this, new RelationshipEventArgs(payload.Deserialize <Relationship>().SetClient(this)));
                        break;

                    case "USER_CONNECTIONS_UPDATE":
                        try
                        {
                            DiscordProfile profile = this.User.GetProfile();
                            OnProfileUpdated?.Invoke(this, new ProfileUpdatedEventArgs(profile));
                        }
                        catch { }
                        break;

                    case "MESSAGE_ACK":         // triggered whenever another person logged into the account acknowledges a message
                        break;

                    case "SESSIONS_REPLACE":
                        OnSessionsUpdated?.Invoke(this, new DiscordSessionsEventArgs(payload.Deserialize <List <DiscordSession> >()));
                        break;
                    }
                    break;

                case GatewayOpcode.InvalidSession:
                    this.LoginToGateway();
                    break;

                case GatewayOpcode.Connected:
                    if (!LoggedIn)
                    {
                        this.LoginToGateway();
                    }
                    else
                    {
                        this.Resume();
                    }

                    int interval = payload.Deserialize <JObject>().GetValue("heartbeat_interval").ToObject <int>();

                    try
                    {
                        while (true)
                        {
                            Socket.Send(GatewayOpcode.Heartbeat, this.Sequence);
                            Thread.Sleep(interval);
                        }
                    }
                    catch { }
                    break;
                }
            });
        }
        private void InvokeEvent(LazyNotification lazyNotification)
        {
            var ntf = lazyNotification.Notifications;

            switch (lazyNotification.NotifyType)
            {
            case NotificationType.ChannelChanged: {
                var ntfc = (ChannelChanged[])ntf;
                OnChannelChanged?.Invoke(this, ntfc);
                var ev = OnEachChannelChanged;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                }
                break;
            }

            case NotificationType.ChannelCreated: {
                var ntfc = (ChannelCreated[])ntf;
                OnChannelCreated?.Invoke(this, ntfc);
                var ev = OnEachChannelCreated;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                }
                break;
            }

            case NotificationType.ChannelDeleted: {
                var ntfc = (ChannelDeleted[])ntf;
                OnChannelDeleted?.Invoke(this, ntfc);
                var ev = OnEachChannelDeleted;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                }
                break;
            }

            case NotificationType.ChannelEdited: {
                var ntfc = (ChannelEdited[])ntf;
                OnChannelEdited?.Invoke(this, ntfc);
                var ev = OnEachChannelEdited;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                }
                break;
            }

            case NotificationType.ChannelMoved: {
                var ntfc = (ChannelMoved[])ntf;
                OnChannelMoved?.Invoke(this, ntfc);
                var ev = OnEachChannelMoved;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                }
                break;
            }

            case NotificationType.ChannelPasswordChanged: {
                var ntfc = (ChannelPasswordChanged[])ntf;
                OnChannelPasswordChanged?.Invoke(this, ntfc);
                var ev = OnEachChannelPasswordChanged;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                }
                break;
            }

            case NotificationType.ClientEnterView: {
                var ntfc = (ClientEnterView[])ntf;
                OnClientEnterView?.Invoke(this, ntfc);
                var ev = OnEachClientEnterView;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                }
                break;
            }

            case NotificationType.ClientLeftView: {
                var ntfc = (ClientLeftView[])ntf;
                OnClientLeftView?.Invoke(this, ntfc);
                var ev = OnEachClientLeftView;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                }
                break;
            }

            case NotificationType.ClientMoved: {
                var ntfc = (ClientMoved[])ntf;
                OnClientMoved?.Invoke(this, ntfc);
                var ev = OnEachClientMoved;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                }
                break;
            }

            case NotificationType.ServerEdited: {
                var ntfc = (ServerEdited[])ntf;
                OnServerEdited?.Invoke(this, ntfc);
                var ev = OnEachServerEdited;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                }
                break;
            }

            case NotificationType.TextMessage: {
                var ntfc = (TextMessage[])ntf;
                OnTextMessage?.Invoke(this, ntfc);
                var ev = OnEachTextMessage;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                }
                break;
            }

            case NotificationType.TokenUsed: {
                var ntfc = (TokenUsed[])ntf;
                OnTokenUsed?.Invoke(this, ntfc);
                var ev = OnEachTokenUsed;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                }
                break;
            }

            case NotificationType.CommandError: break;

            case NotificationType.Unknown:
            default:
                throw Tools.UnhandledDefault(lazyNotification.NotifyType);
            }
        }
Exemple #11
0
        private void InvokeEvent(LazyNotification lazyNotification)
        {
            var ntf = lazyNotification.Notifications;

            switch (lazyNotification.NotifyType)
            {
            case NotificationType.ChannelChanged: {
                var ntfc = (ChannelChanged[])ntf;
                ProcessChannelChanged(ntfc);
                OnChannelChanged?.Invoke(this, ntfc);
                var ev   = OnEachChannelChanged;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachChannelChanged(that);
                }
                break;
            }

            case NotificationType.ChannelCreated: {
                var ntfc = (ChannelCreated[])ntf;
                ProcessChannelCreated(ntfc);
                OnChannelCreated?.Invoke(this, ntfc);
                var ev   = OnEachChannelCreated;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachChannelCreated(that);
                    book?.UpdateChannelCreated(that);
                }
                break;
            }

            case NotificationType.ChannelDeleted: {
                var ntfc = (ChannelDeleted[])ntf;
                ProcessChannelDeleted(ntfc);
                OnChannelDeleted?.Invoke(this, ntfc);
                var ev   = OnEachChannelDeleted;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachChannelDeleted(that);
                    book?.UpdateChannelDeleted(that);
                }
                break;
            }

            case NotificationType.ChannelEdited: {
                var ntfc = (ChannelEdited[])ntf;
                ProcessChannelEdited(ntfc);
                OnChannelEdited?.Invoke(this, ntfc);
                var ev   = OnEachChannelEdited;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachChannelEdited(that);
                    book?.UpdateChannelEdited(that);
                }
                break;
            }

            case NotificationType.ChannelGroupList: {
                var ntfc = (ChannelGroupList[])ntf;
                ProcessChannelGroupList(ntfc);
                OnChannelGroupList?.Invoke(this, ntfc);
                var ev   = OnEachChannelGroupList;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachChannelGroupList(that);
                }
                break;
            }

            case NotificationType.ChannelList: {
                var ntfc = (ChannelList[])ntf;
                ProcessChannelList(ntfc);
                OnChannelList?.Invoke(this, ntfc);
                var ev   = OnEachChannelList;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachChannelList(that);
                    book?.UpdateChannelList(that);
                }
                break;
            }

            case NotificationType.ChannelListFinished: {
                var ntfc = (ChannelListFinished[])ntf;
                ProcessChannelListFinished(ntfc);
                OnChannelListFinished?.Invoke(this, ntfc);
                var ev   = OnEachChannelListFinished;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachChannelListFinished(that);
                }
                break;
            }

            case NotificationType.ChannelMoved: {
                var ntfc = (ChannelMoved[])ntf;
                ProcessChannelMoved(ntfc);
                OnChannelMoved?.Invoke(this, ntfc);
                var ev   = OnEachChannelMoved;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachChannelMoved(that);
                    book?.UpdateChannelMoved(that);
                }
                break;
            }

            case NotificationType.ChannelPasswordChanged: {
                var ntfc = (ChannelPasswordChanged[])ntf;
                ProcessChannelPasswordChanged(ntfc);
                OnChannelPasswordChanged?.Invoke(this, ntfc);
                var ev   = OnEachChannelPasswordChanged;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachChannelPasswordChanged(that);
                }
                break;
            }

            case NotificationType.ChannelSubscribed: {
                var ntfc = (ChannelSubscribed[])ntf;
                ProcessChannelSubscribed(ntfc);
                OnChannelSubscribed?.Invoke(this, ntfc);
                var ev   = OnEachChannelSubscribed;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachChannelSubscribed(that);
                }
                break;
            }

            case NotificationType.ChannelUnsubscribed: {
                var ntfc = (ChannelUnsubscribed[])ntf;
                ProcessChannelUnsubscribed(ntfc);
                OnChannelUnsubscribed?.Invoke(this, ntfc);
                var ev   = OnEachChannelUnsubscribed;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachChannelUnsubscribed(that);
                }
                break;
            }

            case NotificationType.ClientChannelGroupChanged: {
                var ntfc = (ClientChannelGroupChanged[])ntf;
                ProcessClientChannelGroupChanged(ntfc);
                OnClientChannelGroupChanged?.Invoke(this, ntfc);
                var ev   = OnEachClientChannelGroupChanged;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachClientChannelGroupChanged(that);
                    book?.UpdateClientChannelGroupChanged(that);
                }
                break;
            }

            case NotificationType.ClientChatComposing: {
                var ntfc = (ClientChatComposing[])ntf;
                ProcessClientChatComposing(ntfc);
                OnClientChatComposing?.Invoke(this, ntfc);
                var ev   = OnEachClientChatComposing;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachClientChatComposing(that);
                }
                break;
            }

            case NotificationType.ClientDbIdFromUid: {
                var ntfc = (ClientDbIdFromUid[])ntf;
                ProcessClientDbIdFromUid(ntfc);
                OnClientDbIdFromUid?.Invoke(this, ntfc);
                var ev   = OnEachClientDbIdFromUid;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachClientDbIdFromUid(that);
                }
                break;
            }

            case NotificationType.ClientEnterView: {
                var ntfc = (ClientEnterView[])ntf;
                ProcessClientEnterView(ntfc);
                OnClientEnterView?.Invoke(this, ntfc);
                var ev   = OnEachClientEnterView;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachClientEnterView(that);
                    book?.UpdateClientEnterView(that);
                }
                break;
            }

            case NotificationType.ClientIds: {
                var ntfc = (ClientIds[])ntf;
                ProcessClientIds(ntfc);
                OnClientIds?.Invoke(this, ntfc);
                var ev   = OnEachClientIds;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachClientIds(that);
                }
                break;
            }

            case NotificationType.ClientLeftView: {
                var ntfc = (ClientLeftView[])ntf;
                ProcessClientLeftView(ntfc);
                OnClientLeftView?.Invoke(this, ntfc);
                var ev   = OnEachClientLeftView;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachClientLeftView(that);
                    book?.UpdateClientLeftView(that);
                }
                break;
            }

            case NotificationType.ClientMoved: {
                var ntfc = (ClientMoved[])ntf;
                ProcessClientMoved(ntfc);
                OnClientMoved?.Invoke(this, ntfc);
                var ev   = OnEachClientMoved;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachClientMoved(that);
                    book?.UpdateClientMoved(that);
                }
                break;
            }

            case NotificationType.ClientNeededPermissions: {
                var ntfc = (ClientNeededPermissions[])ntf;
                ProcessClientNeededPermissions(ntfc);
                OnClientNeededPermissions?.Invoke(this, ntfc);
                var ev   = OnEachClientNeededPermissions;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachClientNeededPermissions(that);
                }
                break;
            }

            case NotificationType.ClientPoke: {
                var ntfc = (ClientPoke[])ntf;
                ProcessClientPoke(ntfc);
                OnClientPoke?.Invoke(this, ntfc);
                var ev   = OnEachClientPoke;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachClientPoke(that);
                }
                break;
            }

            case NotificationType.ClientServerGroup: {
                var ntfc = (ClientServerGroup[])ntf;
                ProcessClientServerGroup(ntfc);
                OnClientServerGroup?.Invoke(this, ntfc);
                var ev   = OnEachClientServerGroup;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachClientServerGroup(that);
                }
                break;
            }

            case NotificationType.ClientServerGroupAdded: {
                var ntfc = (ClientServerGroupAdded[])ntf;
                ProcessClientServerGroupAdded(ntfc);
                OnClientServerGroupAdded?.Invoke(this, ntfc);
                var ev   = OnEachClientServerGroupAdded;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachClientServerGroupAdded(that);
                    book?.UpdateClientServerGroupAdded(that);
                }
                break;
            }

            case NotificationType.CommandError: {
                var ntfc = (CommandError[])ntf;
                ProcessCommandError(ntfc);
                OnCommandError?.Invoke(this, ntfc);
                var ev   = OnEachCommandError;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachCommandError(that);
                }
                break;
            }

            case NotificationType.ConnectionInfo: {
                var ntfc = (ConnectionInfo[])ntf;
                ProcessConnectionInfo(ntfc);
                OnConnectionInfo?.Invoke(this, ntfc);
                var ev   = OnEachConnectionInfo;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachConnectionInfo(that);
                    book?.UpdateConnectionInfo(that);
                }
                break;
            }

            case NotificationType.ConnectionInfoRequest: {
                var ntfc = (ConnectionInfoRequest[])ntf;
                ProcessConnectionInfoRequest(ntfc);
                OnConnectionInfoRequest?.Invoke(this, ntfc);
                var ev   = OnEachConnectionInfoRequest;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachConnectionInfoRequest(that);
                }
                break;
            }

            case NotificationType.FileDownload: {
                var ntfc = (FileDownload[])ntf;
                ProcessFileDownload(ntfc);
                OnFileDownload?.Invoke(this, ntfc);
                var ev   = OnEachFileDownload;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachFileDownload(that);
                }
                break;
            }

            case NotificationType.FileInfoTs: {
                var ntfc = (FileInfoTs[])ntf;
                ProcessFileInfoTs(ntfc);
                OnFileInfoTs?.Invoke(this, ntfc);
                var ev   = OnEachFileInfoTs;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachFileInfoTs(that);
                }
                break;
            }

            case NotificationType.FileList: {
                var ntfc = (FileList[])ntf;
                ProcessFileList(ntfc);
                OnFileList?.Invoke(this, ntfc);
                var ev   = OnEachFileList;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachFileList(that);
                }
                break;
            }

            case NotificationType.FileListFinished: {
                var ntfc = (FileListFinished[])ntf;
                ProcessFileListFinished(ntfc);
                OnFileListFinished?.Invoke(this, ntfc);
                var ev   = OnEachFileListFinished;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachFileListFinished(that);
                }
                break;
            }

            case NotificationType.FileTransfer: {
                var ntfc = (FileTransfer[])ntf;
                ProcessFileTransfer(ntfc);
                OnFileTransfer?.Invoke(this, ntfc);
                var ev   = OnEachFileTransfer;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachFileTransfer(that);
                }
                break;
            }

            case NotificationType.FileTransferStatus: {
                var ntfc = (FileTransferStatus[])ntf;
                ProcessFileTransferStatus(ntfc);
                OnFileTransferStatus?.Invoke(this, ntfc);
                var ev   = OnEachFileTransferStatus;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachFileTransferStatus(that);
                }
                break;
            }

            case NotificationType.FileUpload: {
                var ntfc = (FileUpload[])ntf;
                ProcessFileUpload(ntfc);
                OnFileUpload?.Invoke(this, ntfc);
                var ev   = OnEachFileUpload;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachFileUpload(that);
                }
                break;
            }

            case NotificationType.InitIvExpand: {
                var ntfc = (InitIvExpand[])ntf;
                ProcessInitIvExpand(ntfc);
                OnInitIvExpand?.Invoke(this, ntfc);
                var ev   = OnEachInitIvExpand;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachInitIvExpand(that);
                }
                break;
            }

            case NotificationType.InitIvExpand2: {
                var ntfc = (InitIvExpand2[])ntf;
                ProcessInitIvExpand2(ntfc);
                OnInitIvExpand2?.Invoke(this, ntfc);
                var ev   = OnEachInitIvExpand2;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachInitIvExpand2(that);
                }
                break;
            }

            case NotificationType.InitServer: {
                var ntfc = (InitServer[])ntf;
                ProcessInitServer(ntfc);
                OnInitServer?.Invoke(this, ntfc);
                var ev   = OnEachInitServer;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachInitServer(that);
                    book?.UpdateInitServer(that);
                }
                break;
            }

            case NotificationType.PluginCommand: {
                var ntfc = (PluginCommand[])ntf;
                ProcessPluginCommand(ntfc);
                OnPluginCommand?.Invoke(this, ntfc);
                var ev   = OnEachPluginCommand;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachPluginCommand(that);
                }
                break;
            }

            case NotificationType.ServerEdited: {
                var ntfc = (ServerEdited[])ntf;
                ProcessServerEdited(ntfc);
                OnServerEdited?.Invoke(this, ntfc);
                var ev   = OnEachServerEdited;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachServerEdited(that);
                    book?.UpdateServerEdited(that);
                }
                break;
            }

            case NotificationType.ServerGroupList: {
                var ntfc = (ServerGroupList[])ntf;
                ProcessServerGroupList(ntfc);
                OnServerGroupList?.Invoke(this, ntfc);
                var ev   = OnEachServerGroupList;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachServerGroupList(that);
                    book?.UpdateServerGroupList(that);
                }
                break;
            }

            case NotificationType.TextMessage: {
                var ntfc = (TextMessage[])ntf;
                ProcessTextMessage(ntfc);
                OnTextMessage?.Invoke(this, ntfc);
                var ev   = OnEachTextMessage;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachTextMessage(that);
                }
                break;
            }

            case NotificationType.TokenUsed: {
                var ntfc = (TokenUsed[])ntf;
                ProcessTokenUsed(ntfc);
                OnTokenUsed?.Invoke(this, ntfc);
                var ev   = OnEachTokenUsed;
                var book = Book;
                foreach (var that in ntfc)
                {
                    ev?.Invoke(this, that);
                    ProcessEachTokenUsed(that);
                }
                break;
            }

            case NotificationType.Unknown:
            default:
                throw Util.UnhandledDefault(lazyNotification.NotifyType);
            }
        }
Exemple #12
0
        private void SocketDataReceived(object sender, WebSocketSharp.MessageEventArgs result)
        {
            GatewayResponse payload = result.Data.Deserialize <GatewayResponse>();

            Sequence = payload.Sequence;

            try
            {
                switch (payload.Opcode)
                {
                case GatewayOpcode.Event:
                    /*
                     * Console.WriteLine(payload.Title);
                     *
                     * File.AppendAllText("Debug.log", $"{payload.Title}: {payload.Data}\n");
                     */
                    switch (payload.Title)
                    {
                    case "READY":
                        Login login = payload.DeserializeEx <Login>().SetClient(this);

                        this.User         = login.User;
                        this.UserSettings = login.Settings;
                        this.SessionId    = login.SessionId;

                        if (Config.Cache)
                        {
                            if (this.User.Type == DiscordUserType.User)
                            {
                                PrivateChannels = login.PrivateChannels;

                                foreach (var guild in login.Guilds)
                                {
                                    GuildCache[guild.Id] = guild.ToSocketGuild();

                                    foreach (var state in GuildCache[guild.Id].VoiceStates)
                                    {
                                        VoiceStates[state.UserId] = state;
                                    }
                                }

                                foreach (var settings in login.ClientGuildSettings)
                                {
                                    if (settings.GuildId.HasValue)
                                    {
                                        GuildSettings.Add(settings.Guild.Id, settings);
                                    }
                                    else
                                    {
                                        PrivateChannelSettings = settings.ChannelOverrides.ToList();
                                    }
                                }
                            }
                        }

                        LoggedIn = true;

                        Task.Run(() => OnLoggedIn?.Invoke(this, new LoginEventArgs(login)));
                        break;

                    case "USER_SETTINGS_UPDATE":
                        if (UserSettings != null)         // for some reason this is null sometimes :thinking:
                        {
                            var update = payload.Deserialize <JObject>();

                            foreach (var field in UserSettings.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance))
                            {
                                foreach (var attr in field.CustomAttributes)
                                {
                                    if (attr.AttributeType == typeof(JsonPropertyAttribute))
                                    {
                                        string propertyName = attr.ConstructorArguments[0].Value.ToString();

                                        if (update.ContainsKey(propertyName))
                                        {
                                            field.SetValue(UserSettings, update.GetValue(propertyName).ToObject(field.FieldType));
                                        }

                                        break;
                                    }
                                }
                            }

                            foreach (var property in UserSettings.GetType().GetProperties())
                            {
                                foreach (var attr in property.CustomAttributes)
                                {
                                    if (attr.AttributeType == typeof(JsonPropertyAttribute))
                                    {
                                        string propertyName = attr.ConstructorArguments[0].Value.ToString();

                                        if (update.ContainsKey(propertyName))
                                        {
                                            property.SetValue(UserSettings, update.GetValue(propertyName).ToObject(property.PropertyType));
                                        }

                                        break;
                                    }
                                }
                            }

                            Task.Run(() => OnSettingsUpdated?.Invoke(this, new DiscordSettingsEventArgs(UserSettings)));
                        }
                        break;

                    case "USER_GUILD_SETTINGS_UPDATE":
                        if (Config.Cache)
                        {
                            ClientGuildSettings settings = payload.Deserialize <ClientGuildSettings>();

                            if (settings.GuildId.HasValue)
                            {
                                GuildSettings[settings.Guild.Id] = settings;
                            }
                            else
                            {
                                PrivateChannelSettings = settings.ChannelOverrides.ToList();
                            }
                        }
                        break;

                    case "USER_UPDATE":
                        DiscordUser user = payload.Deserialize <DiscordUser>().SetClient(this);

                        if (user.Id == User.Id)
                        {
                            User.Update(user);
                        }

                        if (Config.Cache)
                        {
                            foreach (var dm in PrivateChannels)
                            {
                                bool updated = false;

                                foreach (var recipient in dm.Recipients)
                                {
                                    if (recipient.Id == user.Id)
                                    {
                                        recipient.Update(user);

                                        updated = true;

                                        break;
                                    }
                                }

                                if (updated)         // this is somewhat resource intensive, so let's reduce the uses as much as possible
                                {
                                    dm.UpdateSelfJson();
                                }
                            }
                        }

                        Task.Run(() => OnUserUpdated?.Invoke(this, new UserEventArgs(user)));
                        break;

                    case "GUILD_MEMBER_LIST_UPDATE":
                        OnMemberListUpdate?.Invoke(this, payload.Deserialize <GuildMemberListEventArgs>());
                        break;

                    case "GUILD_CREATE":
                    {
                        SocketGuild guild = payload.DeserializeEx <SocketGuild>().SetClient(this);

                        if (Config.Cache)
                        {
                            GuildCache.Remove(guild.Id);

                            GuildCache.Add(guild.Id, guild);
                        }

                        Task.Run(() => OnJoinedGuild?.Invoke(this, new SocketGuildEventArgs(guild, Lurking.HasValue && Lurking.Value == guild.Id)));
                    }
                    break;

                    case "GUILD_UPDATE":
                    {
                        DiscordGuild guild = payload.Deserialize <DiscordGuild>().SetClient(this);

                        if (Config.Cache)
                        {
                            GuildCache[guild].Update(guild);
                        }

                        Task.Run(() => OnGuildUpdated?.Invoke(this, new GuildEventArgs(guild)));
                    }
                    break;

                    case "GUILD_DELETE":
                    {
                        UnavailableGuild guild = payload.Deserialize <UnavailableGuild>();

                        if (Lurking.HasValue && Lurking.Value == guild.Id)
                        {
                            Lurking = null;
                        }

                        if (Config.Cache)
                        {
                            if (guild.Unavailable)
                            {
                                GuildCache[guild.Id].Unavailable = true;
                            }
                            else
                            {
                                GuildCache.Remove(guild.Id);
                            }

                            GuildSettings.Remove(guild.Id);
                        }

                        Task.Run(() => OnLeftGuild?.Invoke(this, new GuildUnavailableEventArgs(guild)));
                    }
                    break;

                    case "GUILD_MEMBER_ADD":
                        Task.Run(() => OnUserJoinedGuild?.Invoke(this, new GuildMemberEventArgs(payload.Deserialize <GuildMember>().SetClient(this))));
                        break;

                    case "GUILD_MEMBER_REMOVE":
                        Task.Run(() => OnUserLeftGuild?.Invoke(this, new MemberRemovedEventArgs(payload.Deserialize <PartialGuildMember>().SetClient(this))));
                        break;

                    case "GUILD_MEMBER_UPDATE":
                        GuildMember member = payload.Deserialize <GuildMember>().SetClient(this);

                        if (Config.Cache && member.User.Id == User.Id)
                        {
                            SocketGuild guild = this.GetCachedGuild(member.GuildId);

                            // Discord doesn't send us the user's JoinedAt on updates
                            member.JoinedAt = guild.Member.JoinedAt;
                            guild.Member    = member;

                            break;
                        }

                        Task.Run(() => OnGuildMemberUpdated?.Invoke(this, new GuildMemberEventArgs(member)));
                        break;

                    case "GUILD_MEMBERS_CHUNK":
                        Task.Run(() => OnGuildMembersReceived?.Invoke(this, new GuildMembersEventArgs(payload.Deserialize <GuildMemberList>().SetClient(this))));
                        break;

                    case "GIFT_CODE_CREATE":
                        Task.Run(() => OnGiftCodeCreated?.Invoke(this, payload.Deserialize <GiftCodeCreatedEventArgs>()));
                        break;

                    case "PRESENCE_UPDATE":
                        Task.Run(() => OnUserPresenceUpdated?.Invoke(this, new PresenceUpdatedEventArgs(payload.DeserializeEx <DiscordPresence>().SetClient(this))));
                        break;

                    case "VOICE_STATE_UPDATE":
                        DiscordVoiceState newState = payload.Deserialize <DiscordVoiceState>().SetClient(this);

                        if (Config.Cache)
                        {
                            // this doesn't work very well for bot accounts since those can be connected to a channel in multiple guilds at once.
                            VoiceStates[newState.UserId] = newState;

                            // we also store voice states within SocketGuilds, so make sure to update those.
                            foreach (var guild in this.GetCachedGuilds())
                            {
                                if (newState.Guild == null || guild.Id != newState.Guild.Id)
                                {
                                    guild._voiceStates.RemoveAll(s => s.UserId == newState.UserId);
                                }
                                else
                                {
                                    int i = guild._voiceStates.FindIndex(s => s.UserId == newState.UserId);

                                    if (i > -1)
                                    {
                                        guild._voiceStates[i] = newState;
                                    }
                                    else
                                    {
                                        guild._voiceStates.Add(newState);
                                    }
                                }
                            }
                        }

                        Task.Run(() => OnVoiceStateUpdated?.Invoke(this, new VoiceStateEventArgs(newState)));
                        break;

                    case "VOICE_SERVER_UPDATE":
                        Task.Run(() => OnVoiceServer?.Invoke(this, payload.Deserialize <DiscordVoiceServer>().SetClient(this)));
                        break;

                    case "GUILD_ROLE_CREATE":
                    {
                        DiscordRole role = payload.Deserialize <RoleUpdate>().Role.SetClient(this);

                        if (Config.Cache)
                        {
                            GuildCache[role.GuildId]._roles.Add(role);
                        }

                        Task.Run(() => OnRoleCreated?.Invoke(this, new RoleEventArgs(role)));
                    }
                    break;

                    case "GUILD_ROLE_UPDATE":
                    {
                        DiscordRole role = payload.Deserialize <RoleUpdate>().Role.SetClient(this);

                        if (Config.Cache)
                        {
                            var roles = GuildCache[role.GuildId]._roles;
                            roles[roles.FindIndex(r => r.Id == role.Id)] = role;
                        }

                        Task.Run(() => OnRoleUpdated?.Invoke(this, new RoleEventArgs(role)));
                    }
                    break;

                    case "GUILD_ROLE_DELETE":
                    {
                        DeletedRole role = payload.Deserialize <DeletedRole>().SetClient(this);

                        if (Config.Cache)
                        {
                            GuildCache[role.Guild]._roles.RemoveAll(r => r.Id == role.Id);
                        }

                        Task.Run(() => OnRoleDeleted?.Invoke(this, new RoleDeletedEventArgs(role)));
                    }
                    break;

                    case "GUILD_EMOJIS_UPDATE":
                        var emojis = payload.Deserialize <EmojiContainer>().SetClient(this);

                        if (Config.Cache)
                        {
                            GuildCache[emojis.GuildId]._emojis = emojis.Emojis.ToList();
                        }

                        Task.Run(() => OnEmojisUpdated?.Invoke(this, new EmojisUpdatedEventArgs(emojis)));
                        break;

                    case "CHANNEL_CREATE":
                    {
                        var channel = payload.DeserializeEx <DiscordChannel>().SetClient(this);

                        if (Config.Cache)
                        {
                            if (channel.Type == ChannelType.DM || channel.Type == ChannelType.Group)
                            {
                                PrivateChannels.Add(channel.ToDMChannel());
                            }
                            else
                            {
                                GuildChannel guildChannel = channel.ToGuildChannel();

                                GuildCache[guildChannel.GuildId]._channels.Add(guildChannel);
                            }
                        }

                        Task.Run(() => OnChannelCreated?.Invoke(this, new ChannelEventArgs(channel)));
                    }
                    break;

                    case "CHANNEL_UPDATE":
                    {
                        var channel = payload.DeserializeEx <DiscordChannel>().SetClient(this);

                        if (Config.Cache)
                        {
                            if (channel.Type == ChannelType.DM || channel.Type == ChannelType.Group)
                            {
                                PrivateChannels[PrivateChannels.FindIndex(c => c.Id == channel.Id)] = channel.ToDMChannel();
                            }
                            else
                            {
                                GuildChannel guildChannel = channel.ToGuildChannel();

                                var channels = GuildCache[guildChannel.GuildId]._channels;

                                channels[channels.FindIndex(c => c.Id == guildChannel.Id)] = guildChannel;
                            }
                        }

                        Task.Run(() => OnChannelUpdated?.Invoke(this, new ChannelEventArgs(channel)));
                    }
                    break;

                    case "CHANNEL_DELETE":
                    {
                        var channel = payload.DeserializeEx <DiscordChannel>().SetClient(this);

                        if (Config.Cache)
                        {
                            if (channel.Type == ChannelType.DM || channel.Type == ChannelType.Group)
                            {
                                PrivateChannels.RemoveAll(c => c.Id == channel.Id);
                            }
                            else
                            {
                                GuildCache[channel.ToGuildChannel().GuildId]._channels.RemoveAll(c => c.Id == channel.Id);
                            }
                        }

                        Task.Run(() => OnChannelDeleted?.Invoke(this, new ChannelEventArgs(channel)));
                    }
                    break;

                    case "TYPING_START":
                        Task.Run(() => OnUserTyping?.Invoke(this, new UserTypingEventArgs(payload.Deserialize <UserTyping>().SetClient(this))));
                        break;

                    case "MESSAGE_CREATE":
                        var message = payload.Deserialize <DiscordMessage>().SetClient(this);

                        if (Config.Cache)
                        {
                            var channel = this.GetChannel(message.Channel.Id);

                            channel.Json["last_message_id"] = JToken.FromObject(message.Id);
                        }

                        Task.Run(() => OnMessageReceived?.Invoke(this, new MessageEventArgs(message)));
                        break;

                    case "MESSAGE_UPDATE":
                        Task.Run(() => OnMessageEdited?.Invoke(this, new MessageEventArgs(payload.Deserialize <DiscordMessage>().SetClient(this))));
                        break;

                    case "MESSAGE_DELETE":
                        Task.Run(() => OnMessageDeleted?.Invoke(this, new MessageDeletedEventArgs(payload.Deserialize <DeletedMessage>().SetClient(this))));
                        break;

                    case "MESSAGE_REACTION_ADD":
                        Task.Run(() => OnMessageReactionAdded?.Invoke(this, new ReactionEventArgs(payload.Deserialize <MessageReactionUpdate>().SetClient(this))));
                        break;

                    case "MESSAGE_REACTION_REMOVE":
                        Task.Run(() => OnMessageReactionRemoved?.Invoke(this, new ReactionEventArgs(payload.Deserialize <MessageReactionUpdate>().SetClient(this))));
                        break;

                    case "GUILD_BAN_ADD":
                        Task.Run(() => OnUserBanned?.Invoke(this, payload.Deserialize <BanUpdateEventArgs>().SetClient(this)));
                        break;

                    case "GUILD_BAN_REMOVE":
                        Task.Run(() => OnUserUnbanned?.Invoke(this, payload.Deserialize <BanUpdateEventArgs>().SetClient(this)));
                        break;

                    case "INVITE_CREATE":
                        Task.Run(() => OnInviteCreated?.Invoke(this, payload.Deserialize <InviteCreatedEventArgs>().SetClient(this)));
                        break;

                    case "INVITE_DELETE":
                        Task.Run(() => OnInviteDeleted?.Invoke(this, payload.Deserialize <InviteDeletedEventArgs>().SetClient(this)));
                        break;

                    case "RELATIONSHIP_ADD":
                        Task.Run(() => OnRelationshipAdded?.Invoke(this, new RelationshipEventArgs(payload.Deserialize <Relationship>().SetClient(this))));
                        break;

                    case "RELATIONSHIP_REMOVE":
                        Task.Run(() => OnRelationshipRemoved?.Invoke(this, new RelationshipEventArgs(payload.Deserialize <Relationship>().SetClient(this))));
                        break;

                    case "CHANNEL_RECIPIENT_ADD":
                    {
                        var recipUpdate = payload.Deserialize <ChannelRecipientUpdate>().SetClient(this);

                        if (Config.Cache)
                        {
                            foreach (var channel in PrivateChannels)
                            {
                                if (channel.Id == recipUpdate.Channel.Id)
                                {
                                    channel._recipients.Add(recipUpdate.User);

                                    channel.UpdateSelfJson();

                                    break;
                                }
                            }
                        }
                    }
                    break;

                    case "CHANNEL_RECIPIENT_REMOVE":
                    {
                        var recipUpdate = payload.Deserialize <ChannelRecipientUpdate>().SetClient(this);

                        if (Config.Cache)
                        {
                            foreach (var channel in PrivateChannels)
                            {
                                if (channel.Id == recipUpdate.Channel.Id)
                                {
                                    channel._recipients.RemoveAll(u => u.Id == recipUpdate.User.Id);

                                    channel.UpdateSelfJson();

                                    break;
                                }
                            }
                        }
                    }
                    break;

                    case "MESSAGE_ACK":         // triggered whenever another person logged into the account acknowledges a message
                        break;

                    case "SESSIONS_REPLACE":
                        Task.Run(() => OnSessionsUpdated?.Invoke(this, new DiscordSessionsEventArgs(payload.Deserialize <List <DiscordSession> >())));
                        break;

                    case "CALL_CREATE":
                    {
                        JObject obj = payload.Deserialize <JObject>();

                        var call        = obj.ToObject <DiscordCall>().SetClient(this);
                        var voiceStates = obj.Value <JToken>("voice_states").ToObject <IReadOnlyList <DiscordVoiceState> >().SetClientsInList(this);

                        foreach (var state in voiceStates)
                        {
                            VoiceStates[state.UserId] = state;
                        }

                        Task.Run(() => OnRinging?.Invoke(this, new RingingEventArgs(call, voiceStates)));
                    }
                    break;

                    case "CALL_UPDATE":
                        Task.Run(() => OnCallUpdated?.Invoke(this, new CallUpdateEventArgs(payload.Deserialize <DiscordCall>().SetClient(this))));
                        break;

                    case "CALL_DELETE":
                        ulong channelId = payload.Deserialize <JObject>().Value <ulong>("channel_id");

                        foreach (var state in new Dictionary <ulong, DiscordVoiceState> .ValueCollection(VoiceStates))
                        {
                            if (state.Channel != null && state.Channel.Id == channelId)
                            {
                                VoiceStates.Remove(state.UserId);
                            }
                        }

                        Task.Run(() => OnCallEnded?.Invoke(this, channelId));
                        break;

                    case "USER_PREMIUM_GUILD_SUBSCRIPTION_SLOT_UPDATE":
                        Task.Run(() => OnBoostUpdated?.Invoke(this, new NitroBoostUpdatedEventArgs(payload.Deserialize <DiscordNitroBoost>().SetClient(this))));
                        break;
                    }
                    break;

                case GatewayOpcode.InvalidSession:
                    LoggedIn = false;

                    this.LoginToGateway();
                    break;

                case GatewayOpcode.Connected:
                    this.LoginToGateway();

                    Task.Run(() =>
                    {
                        int interval = payload.Deserialize <JObject>().GetValue("heartbeat_interval").ToObject <int>();

                        try
                        {
                            while (true)
                            {
                                this.Send(GatewayOpcode.Heartbeat, this.Sequence);
                                Thread.Sleep(interval);
                            }
                        }
                        catch { }
                    });

                    break;
                }
            }
            catch
            {
            }
        }
Exemple #13
0
        static void SetClientEvents()
        {
            client.Log             += Client_Log;
            client.Ready           += Client_Ready;
            client.MessageReceived += MessageReceived;
            client.ReactionAdded   += Client_ReactionAdded;
            client.ReactionRemoved += Client_ReactionRemoved;
            client.JoinedGuild     += Client_JoinedGuild;

            client.ChannelCreated += (SocketChannel arg) =>
            {
                OnChannelCreated?.InvokeParallel(arg);
                return(Task.FromResult(default(object)));
            };
            client.ChannelDestroyed += (SocketChannel arg) =>
            {
                OnChannelDestroyed?.InvokeParallel(arg);
                return(Task.FromResult(default(object)));
            };
            client.ChannelUpdated += (SocketChannel arg1, SocketChannel arg2) =>
            {
                OnChannelUpdated?.InvokeParallel(arg1, arg2);
                return(Task.FromResult(default(object)));
            };
            client.CurrentUserUpdated += (SocketSelfUser arg1, SocketSelfUser arg2) =>
            {
                OnCurrentUserUpdated?.InvokeParallel(arg1, arg2);
                return(Task.FromResult(default(object)));
            };
            client.GuildAvailable += (SocketGuild arg) =>
            {
                OnGuildAvailable?.InvokeParallel(arg);
                return(Task.FromResult(default(object)));
            };
            client.GuildMembersDownloaded += (SocketGuild arg) =>
            {
                OnGuildMembersDownloaded?.InvokeParallel(arg);
                return(Task.FromResult(default(object)));
            };
            client.GuildMemberUpdated += (Cacheable <SocketGuildUser, ulong> arg1, SocketGuildUser arg2) =>
            {
                OnGuildMemberUpdated?.InvokeParallel(arg1, arg2);
                return(Task.FromResult(default(object)));
            };
            client.GuildUnavailable += (SocketGuild arg) =>
            {
                OnGuildUnavailable?.InvokeParallel(arg);
                return(Task.FromResult(default(object)));
            };
            client.GuildUpdated += (SocketGuild arg1, SocketGuild arg2) =>
            {
                OnGuildUpdated?.InvokeParallel(arg1, arg2);
                return(Task.FromResult(default(object)));
            };
            client.LatencyUpdated += (int arg1, int arg2) =>
            {
                OnLatencyUpdated?.InvokeParallel(arg1, arg2);
                return(Task.FromResult(default(object)));
            };
            client.LeftGuild += (SocketGuild arg) =>
            {
                OnLeftGuild?.InvokeParallel(arg);
                return(Task.FromResult(default(object)));
            };
            client.LoggedIn += () =>
            {
                OnLoggedIn?.InvokeParallel();
                return(Task.FromResult(default(object)));
            };
            client.LoggedOut += () =>
            {
                OnLoggedOut?.InvokeParallel();
                return(Task.FromResult(default(object)));
            };
            client.MessageDeleted += (Cacheable <IMessage, ulong> arg1, Cacheable <IMessageChannel, ulong> arg2) =>
            {
                OnMessageDeleted?.InvokeParallel(arg1, arg2);
                return(Task.FromResult(default(object)));
            };
            client.MessagesBulkDeleted += (IReadOnlyCollection <Cacheable <IMessage, ulong> > arg1, Cacheable <IMessageChannel, ulong> arg2) =>
            {
                OnMessagesBulkDeleted?.InvokeParallel(arg1, arg2);
                return(Task.FromResult(default(object)));
            };
            client.MessageUpdated += (Cacheable <IMessage, ulong> arg1, SocketMessage arg2, ISocketMessageChannel arg3) =>
            {
                OnMessageUpdated?.InvokeParallel(arg1, arg2, arg3);
                return(Task.FromResult(default(object)));
            };
            client.ReactionsCleared += (Cacheable <IUserMessage, ulong> arg1, Cacheable <IMessageChannel, ulong> arg2) =>
            {
                OnReactionsCleared?.InvokeParallel(arg1, arg2);
                return(Task.FromResult(default(object)));
            };
            client.RecipientAdded += (SocketGroupUser arg) =>
            {
                OnRecipientAdded?.InvokeParallel(arg);
                return(Task.FromResult(default(object)));
            };
            client.RecipientRemoved += (SocketGroupUser arg) =>
            {
                OnRecipientRemoved?.InvokeParallel(arg);
                return(Task.FromResult(default(object)));
            };
            client.RoleCreated += (SocketRole arg) =>
            {
                OnRoleCreated?.InvokeParallel(arg);
                return(Task.FromResult(default(object)));
            };
            client.RoleDeleted += (SocketRole arg) =>
            {
                OnRoleDeleted?.InvokeParallel(arg);
                return(Task.FromResult(default(object)));
            };
            client.RoleUpdated += (SocketRole arg1, SocketRole arg2) =>
            {
                OnRoleUpdated?.InvokeParallel(arg1, arg2);
                return(Task.FromResult(default(object)));
            };
            client.UserBanned += (SocketUser arg1, SocketGuild arg2) =>
            {
                OnUserBanned?.InvokeParallel(arg1, arg2);
                return(Task.FromResult(default(object)));
            };
            client.UserIsTyping += (Cacheable <IUser, ulong> arg1, Cacheable <IMessageChannel, ulong> arg2) =>
            {
                OnUserIsTyping?.InvokeParallel(arg1, arg2);
                return(Task.FromResult(default(object)));
            };
            client.UserJoined += (SocketGuildUser arg) =>
            {
                OnUserJoined?.InvokeParallel(arg);
                return(Task.FromResult(default(object)));
            };
            client.UserLeft += (SocketGuild arg1, SocketUser arg2) =>
            {
                OnUserLeft?.InvokeParallel(arg1, arg2);
                return(Task.FromResult(default(object)));
            };
            client.UserUnbanned += (SocketUser arg1, SocketGuild arg2) =>
            {
                OnUserUnbanned?.InvokeParallel(arg1, arg2);
                return(Task.FromResult(default(object)));
            };
            client.UserUpdated += (SocketUser arg1, SocketUser arg2) =>
            {
                OnUserUpdated?.InvokeParallel(arg1, arg2);
                return(Task.FromResult(default(object)));
            };
            client.UserVoiceStateUpdated += (SocketUser arg1, SocketVoiceState arg2, SocketVoiceState arg3) =>
            {
                OnUserVoiceStateUpdated?.InvokeParallel(arg1, arg2, arg3);
                return(Task.FromResult(default(object)));
            };
            client.VoiceServerUpdated += (SocketVoiceServer arg) =>
            {
                OnVoiceServerUpdated?.InvokeParallel(arg);
                return(Task.FromResult(default(object)));
            };
        }