Esempio n. 1
0
        void HandleMessageDeleteEvent(DiscordApiData data)
        {
            Snowflake messageId = data.GetSnowflake("id").Value;
            Snowflake channelId = data.GetSnowflake("channel_id").Value;

            OnMessageDeleted?.Invoke(this, new MessageDeleteEventArgs(shard, messageId, channelId));
        }
Esempio n. 2
0
        internal void FireOnMessageDeleted(ChatDeleted chatDelete)
        {
            if (chatDelete == null)
            {
                throw new ArgumentNullException(nameof(chatDelete));
            }

            OnMessageDeleted?.Invoke(chatDelete);
        }
Esempio n. 3
0
        void HandleMessageDeleteBulkEvent(DiscordApiData data)
        {
            Snowflake channelId = data.GetSnowflake("channel_id").Value;

            IList <DiscordApiData> idArray = data.GetArray("ids");

            for (int i = 0; i < idArray.Count; i++)
            {
                Snowflake messageId = idArray[i].ToSnowflake().Value;
                OnMessageDeleted?.Invoke(this, new MessageDeleteEventArgs(shard, messageId, channelId));
            }
        }
Esempio n. 4
0
        private void PubSubService_OnMessageDeleted(object sender, OnMessageDeletedArgs e)
        {
            if (!UserIdChannelName.TryGetValue(e.ChannelId, out var channelName))
            {
                return;
            }

            OnMessageDeleted?.Invoke(this, new MessageDeletedEvent
            {
                TwitchMessageId = e.MessageId,
                Channel         = channelName,
                DeletedBy       = e.DeletedBy,
                Message         = e.Message,
                Username        = e.TargetUser,
            });
        }
        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;
            }
        }
Esempio n. 6
0
 private void NewConnection_OnMessageDeleted(object _, MessageDeletedEvent e)
 {
     logger.LogInformation("Received deleted message from channel {arg}, on user {arg2}, issued by {arg3} regarding message: {arg4}", e.Channel, e.Username, e.DeletedBy, e.Message);
     OnMessageDeleted?.Invoke(this, e);
 }
Esempio n. 7
0
        /// <summary>
        /// Parses the message.
        /// </summary>
        /// <param name="message">The message.</param>
        private void ParseMessage(string message)
        {
            var type = JObject.Parse(message).SelectToken("type")?.ToString();

            switch (type?.ToLower())
            {
            case "response":
                var resp = new Models.Responses.Response(message);
                if (_previousRequests.Count != 0)
                {
                    bool handled = false;
                    foreach (var request in _previousRequests)
                    {
                        if (string.Equals(request.Nonce, resp.Nonce, StringComparison.CurrentCulture))
                        {
                            OnListenResponse?.Invoke(this, new OnListenResponseArgs {
                                Response = resp, Topic = request.Topic, Successful = resp.Successful
                            });
                            handled = true;
                        }
                    }
                    if (handled)
                    {
                        return;
                    }
                }
                break;

            case "message":
                var msg = new Models.Responses.Message(message);
                _topicToChannelId.TryGetValue(msg.Topic, out var channelId);
                channelId = channelId ?? "";
                switch (msg.Topic.Split('.')[0])
                {
                case "channel-subscribe-events-v1":
                    var subscription = msg.MessageData as ChannelSubscription;
                    OnChannelSubscription?.Invoke(this, new OnChannelSubscriptionArgs {
                        Subscription = subscription, ChannelId = channelId
                    });
                    return;

                case "whispers":
                    var whisper = (Whisper)msg.MessageData;
                    OnWhisper?.Invoke(this, new OnWhisperArgs {
                        Whisper = whisper, ChannelId = channelId
                    });
                    return;

                case "chat_moderator_actions":
                    var cma             = msg.MessageData as ChatModeratorActions;
                    var reason          = "";
                    var targetChannelId = msg.Topic.Split('.')[2];
                    switch (cma?.ModerationAction.ToLower())
                    {
                    case "timeout":
                        if (cma.Args.Count > 2)
                        {
                            reason = cma.Args[2];
                        }
                        OnTimeout?.Invoke(this, new OnTimeoutArgs
                        {
                            TimedoutBy      = cma.CreatedBy,
                            TimedoutById    = cma.CreatedByUserId,
                            TimedoutUserId  = cma.TargetUserId,
                            TimeoutDuration = TimeSpan.FromSeconds(int.Parse(cma.Args[1])),
                            TimeoutReason   = reason,
                            TimedoutUser    = cma.Args[0],
                            ChannelId       = channelId
                        });
                        return;

                    case "ban":
                        if (cma.Args.Count > 1)
                        {
                            reason = cma.Args[1];
                        }
                        OnBan?.Invoke(this, new OnBanArgs {
                            BannedBy = cma.CreatedBy, BannedByUserId = cma.CreatedByUserId, BannedUserId = cma.TargetUserId, BanReason = reason, BannedUser = cma.Args[0], ChannelId = channelId
                        });
                        return;

                    case "delete":
                        OnMessageDeleted?.Invoke(this, new OnMessageDeletedArgs {
                            DeletedBy = cma.CreatedBy, DeletedByUserId = cma.CreatedByUserId, TargetUserId = cma.TargetUserId, TargetUser = cma.Args[0], Message = cma.Args[1], MessageId = cma.Args[2], ChannelId = channelId
                        });
                        return;

                    case "unban":
                        OnUnban?.Invoke(this, new OnUnbanArgs {
                            UnbannedBy = cma.CreatedBy, UnbannedByUserId = cma.CreatedByUserId, UnbannedUserId = cma.TargetUserId, UnbannedUser = cma.Args[0], ChannelId = channelId
                        });
                        return;

                    case "untimeout":
                        OnUntimeout?.Invoke(this, new OnUntimeoutArgs {
                            UntimeoutedBy = cma.CreatedBy, UntimeoutedByUserId = cma.CreatedByUserId, UntimeoutedUserId = cma.TargetUserId, UntimeoutedUser = cma.Args[0], ChannelId = channelId
                        });
                        return;

                    case "host":
                        OnHost?.Invoke(this, new OnHostArgs {
                            HostedChannel = cma.Args[0], Moderator = cma.CreatedBy, ChannelId = channelId
                        });
                        return;

                    case "subscribers":
                        OnSubscribersOnly?.Invoke(this, new OnSubscribersOnlyArgs {
                            Moderator = cma.CreatedBy, ChannelId = channelId
                        });
                        return;

                    case "subscribersoff":
                        OnSubscribersOnlyOff?.Invoke(this, new OnSubscribersOnlyOffArgs {
                            Moderator = cma.CreatedBy, ChannelId = channelId
                        });
                        return;

                    case "clear":
                        OnClear?.Invoke(this, new OnClearArgs {
                            Moderator = cma.CreatedBy, ChannelId = channelId
                        });
                        return;

                    case "emoteonly":
                        OnEmoteOnly?.Invoke(this, new OnEmoteOnlyArgs {
                            Moderator = cma.CreatedBy, ChannelId = channelId
                        });
                        return;

                    case "emoteonlyoff":
                        OnEmoteOnlyOff?.Invoke(this, new OnEmoteOnlyOffArgs {
                            Moderator = cma.CreatedBy, ChannelId = channelId
                        });
                        return;

                    case "r9kbeta":
                        OnR9kBeta?.Invoke(this, new OnR9kBetaArgs {
                            Moderator = cma.CreatedBy, ChannelId = channelId
                        });
                        return;

                    case "r9kbetaoff":
                        OnR9kBetaOff?.Invoke(this, new OnR9kBetaOffArgs {
                            Moderator = cma.CreatedBy, ChannelId = channelId
                        });
                        return;
                    }
                    break;

                case "channel-bits-events-v1":
                    if (msg.MessageData is ChannelBitsEvents cbe)
                    {
                        OnBitsReceived?.Invoke(this, new OnBitsReceivedArgs
                        {
                            BitsUsed      = cbe.BitsUsed,
                            ChannelId     = cbe.ChannelId,
                            ChannelName   = cbe.ChannelName,
                            ChatMessage   = cbe.ChatMessage,
                            Context       = cbe.Context,
                            Time          = cbe.Time,
                            TotalBitsUsed = cbe.TotalBitsUsed,
                            UserId        = cbe.UserId,
                            Username      = cbe.Username
                        });
                        return;
                    }
                    break;

                case "channel-commerce-events-v1":
                    if (msg.MessageData is ChannelCommerceEvents cce)
                    {
                        OnChannelCommerceReceived?.Invoke(this, new OnChannelCommerceReceivedArgs
                        {
                            Username        = cce.Username,
                            DisplayName     = cce.DisplayName,
                            ChannelName     = cce.ChannelName,
                            UserId          = cce.UserId,
                            ChannelId       = cce.ChannelId,
                            Time            = cce.Time,
                            ItemImageURL    = cce.ItemImageURL,
                            ItemDescription = cce.ItemDescription,
                            SupportsChannel = cce.SupportsChannel,
                            PurchaseMessage = cce.PurchaseMessage
                        });
                        return;
                    }
                    break;

                case "channel-ext-v1":
                    var cEB = msg.MessageData as ChannelExtensionBroadcast;
                    OnChannelExtensionBroadcast?.Invoke(this, new OnChannelExtensionBroadcastArgs {
                        Messages = cEB.Messages, ChannelId = channelId
                    });
                    return;

                case "video-playback":
                case "video-playback-by-id":
                    var vP = msg.MessageData as VideoPlayback;
                    switch (vP?.Type)
                    {
                    case VideoPlaybackType.StreamDown:
                        OnStreamDown?.Invoke(this, new OnStreamDownArgs {
                            ChannelId = channelId, ServerTime = vP.ServerTime
                        });
                        return;

                    case VideoPlaybackType.StreamUp:
                        OnStreamUp?.Invoke(this, new OnStreamUpArgs {
                            ChannelId = channelId, PlayDelay = vP.PlayDelay, ServerTime = vP.ServerTime
                        });
                        return;

                    case VideoPlaybackType.ViewCount:
                        OnViewCount?.Invoke(this, new OnViewCountArgs {
                            ChannelId = channelId, ServerTime = vP.ServerTime, Viewers = vP.Viewers
                        });
                        return;

                    case VideoPlaybackType.Commercial:
                        OnCommercial?.Invoke(this, new OnCommercialArgs {
                            ChannelId = channelId, ServerTime = vP.ServerTime, Length = vP.Length
                        });
                        return;

                    case VideoPlaybackType.WatchPartyVod:
                        OnWatchPartyVod?.Invoke(this, new OnWatchPartyVodArgs {
                            ChannelId = channelId, WpId = vP.WpId, WpType = vP.WpType, IncrementUrl = vP.IncrementUrl, VodId = vP.VodId, Title = vP.Title, BroadcastType = vP.BroadcastType, Viewable = vP.Viewable
                        });
                        return;
                    }
                    break;

                case "broadcast-settings-update":
                    var bsu = msg.MessageData as BroadcastSettingsUpdate;
                    switch (bsu?.Type)
                    {
                    case BroadcastSettingsUpdateType.BroadcastSettingsUpdate:
                        OnBroadcastSettingsUpdate?.Invoke(this, new OnBroadcastSettingsUpdateArgs {
                            ChannelId = channelId, Channel = bsu.Channel, Game = bsu.Game, GameId = bsu.GameId, OldGame = bsu.OldGame, OldGameId = bsu.OldGameId, OldStatus = bsu.OldStatus, Status = bsu.Status
                        });
                        return;
                    }
                    break;

                case "following":
                    var f = (Following)msg.MessageData;
                    f.FollowedChannelId = msg.Topic.Split('.')[1];
                    OnFollow?.Invoke(this, new OnFollowArgs {
                        FollowedChannelId = f.FollowedChannelId, DisplayName = f.DisplayName, UserId = f.UserId, Username = f.Username
                    });
                    return;

                case "community-points-channel-v1":
                    var cpc = msg.MessageData as CommunityPointsChannel;
                    switch (cpc?.Type)
                    {
                    case CommunityPointsChannelType.RewardRedeemed:
                        OnRewardRedeemed?.Invoke(this, new OnRewardRedeemedArgs {
                            TimeStamp = cpc.TimeStamp, ChannelId = cpc.ChannelId, Login = cpc.Login, DisplayName = cpc.DisplayName, Message = cpc.Message, RewardId = cpc.RewardId, RewardTitle = cpc.RewardTitle, RewardPrompt = cpc.RewardPrompt, RewardCost = cpc.RewardCost, Status = cpc.Status
                        });
                        return;

                    case CommunityPointsChannelType.CustomRewardUpdated:
                        OnCustomRewardUpdated?.Invoke(this, new OnCustomRewardUpdatedArgs {
                            TimeStamp = cpc.TimeStamp, ChannelId = cpc.ChannelId, RewardId = cpc.RewardId, RewardTitle = cpc.RewardTitle, RewardPrompt = cpc.RewardPrompt, RewardCost = cpc.RewardCost
                        });
                        return;

                    case CommunityPointsChannelType.CustomRewardCreated:
                        OnCustomRewardCreated?.Invoke(this, new OnCustomRewardCreatedArgs {
                            TimeStamp = cpc.TimeStamp, ChannelId = cpc.ChannelId, RewardId = cpc.RewardId, RewardTitle = cpc.RewardTitle, RewardPrompt = cpc.RewardPrompt, RewardCost = cpc.RewardCost
                        });
                        return;

                    case CommunityPointsChannelType.CustomRewardDeleted:
                        OnCustomRewardDeleted?.Invoke(this, new OnCustomRewardDeletedArgs {
                            TimeStamp = cpc.TimeStamp, ChannelId = cpc.ChannelId, RewardId = cpc.RewardId, RewardTitle = cpc.RewardTitle, RewardPrompt = cpc.RewardPrompt
                        });
                        return;
                    }
                    return;

                case "leaderboard-events-v1":
                    var lbe = msg.MessageData as LeaderboardEvents;
                    switch (lbe?.Type)
                    {
                    case LeaderBoardType.BitsUsageByChannel:
                        OnLeaderboardBits?.Invoke(this, new OnLeaderboardEventArgs {
                            ChannelId = lbe.ChannelId, TopList = lbe.Top
                        });
                        return;

                    case LeaderBoardType.SubGiftSent:
                        OnLeaderboardSubs?.Invoke(this, new OnLeaderboardEventArgs {
                            ChannelId = lbe.ChannelId, TopList = lbe.Top
                        });
                        return;
                    }
                    return;

                case "raid":
                    var r = msg.MessageData as RaidEvents;
                    switch (r?.Type)
                    {
                    case RaidType.RaidUpdate:
                        OnRaidUpdate?.Invoke(this, new OnRaidUpdateArgs {
                            Id = r.Id, ChannelId = r.ChannelId, TargetChannelId = r.TargetChannelId, AnnounceTime = r.AnnounceTime, RaidTime = r.RaidTime, RemainingDurationSeconds = r.RemainigDurationSeconds, ViewerCount = r.ViewerCount
                        });
                        return;

                    case RaidType.RaidUpdateV2:
                        OnRaidUpdateV2?.Invoke(this, new OnRaidUpdateV2Args {
                            Id = r.Id, ChannelId = r.ChannelId, TargetChannelId = r.TargetChannelId, TargetLogin = r.TargetLogin, TargetDisplayName = r.TargetDisplayName, TargetProfileImage = r.TargetProfileImage, ViewerCount = r.ViewerCount
                        });
                        return;

                    case RaidType.RaidGo:
                        OnRaidGo?.Invoke(this, new OnRaidGoArgs {
                            Id = r.Id, ChannelId = r.ChannelId, TargetChannelId = r.TargetChannelId, TargetLogin = r.TargetLogin, TargetDisplayName = r.TargetDisplayName, TargetProfileImage = r.TargetProfileImage, ViewerCount = r.ViewerCount
                        });
                        return;
                    }
                    return;
                }
                break;
            }
            UnaccountedFor(message);
        }
Esempio n. 8
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;
            }
        }
Esempio n. 9
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;
            }
        }
 /// <summary>
 /// Passes <see cref="OnMessageDeleted"/> events down to subscribed plugins.
 /// </summary>
 /// <param name="sender">The source of the event.</param>
 /// <param name="e">An <see cref="OnMessageDeletedArgs"/> object.</param>
 private void TwitchPubSub_OnMessageDeleted(object sender, OnMessageDeletedArgs e) => OnMessageDeleted?.Invoke(this, e);
Esempio n. 11
0
        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;
                }
            });
        }
Esempio n. 12
0
        /// <summary>
        /// Parses the message.
        /// </summary>
        /// <param name="message">The message.</param>
        private void ParseMessage(string message)
        {
            var type = JObject.Parse(message).SelectToken("type")?.ToString();

            switch (type?.ToLower())
            {
            case "response":
                var resp = new Models.Responses.Response(message);
                if (_previousRequests.Count != 0)
                {
                    bool handled = false;
                    foreach (var request in _previousRequests)
                    {
                        if (string.Equals(request.Nonce, resp.Nonce, StringComparison.CurrentCulture))
                        {
                            OnListenResponse?.Invoke(this, new OnListenResponseArgs {
                                Response = resp, Topic = request.Topic, Successful = resp.Successful
                            });
                            handled = true;
                        }
                    }
                    if (handled)
                    {
                        return;
                    }
                }
                break;

            case "message":
                var msg = new Models.Responses.Message(message);
                _topicToChannelId.TryGetValue(msg.Topic, out var channelId);
                channelId = channelId ?? "";
                switch (msg.Topic.Split('.')[0])
                {
                case "channel-subscribe-events-v1":
                    var subscription = msg.MessageData as ChannelSubscription;
                    OnChannelSubscription?.Invoke(this, new OnChannelSubscriptionArgs {
                        Subscription = subscription, ChannelId = channelId
                    });
                    return;

                case "whispers":
                    var whisper = (Whisper)msg.MessageData;
                    OnWhisper?.Invoke(this, new OnWhisperArgs {
                        Whisper = whisper, ChannelId = channelId
                    });
                    return;

                case "chat_moderator_actions":
                    var cma             = msg.MessageData as ChatModeratorActions;
                    var reason          = "";
                    var targetChannelId = msg.Topic.Split('.')[2];
                    switch (cma?.ModerationAction.ToLower())
                    {
                    case "timeout":
                        if (cma.Args.Count > 2)
                        {
                            reason = cma.Args[2];
                        }
                        OnTimeout?.Invoke(this, new OnTimeoutArgs
                        {
                            TimedoutBy      = cma.CreatedBy,
                            TimedoutById    = cma.CreatedByUserId,
                            TimedoutUserId  = cma.TargetUserId,
                            TimeoutDuration = TimeSpan.FromSeconds(int.Parse(cma.Args[1])),
                            TimeoutReason   = reason,
                            TimedoutUser    = cma.Args[0],
                            ChannelId       = channelId
                        });
                        return;

                    case "ban":
                        if (cma.Args.Count > 1)
                        {
                            reason = cma.Args[1];
                        }
                        OnBan?.Invoke(this, new OnBanArgs {
                            BannedBy = cma.CreatedBy, BannedByUserId = cma.CreatedByUserId, BannedUserId = cma.TargetUserId, BanReason = reason, BannedUser = cma.Args[0], ChannelId = channelId
                        });
                        return;

                    case "delete":
                        OnMessageDeleted?.Invoke(this, new OnMessageDeletedArgs {
                            DeletedBy = cma.CreatedBy, DeletedByUserId = cma.CreatedByUserId, TargetUserId = cma.TargetUserId, TargetUser = cma.Args[0], Message = cma.Args[1], MessageId = cma.Args[2], ChannelId = channelId
                        });
                        return;

                    case "unban":
                        OnUnban?.Invoke(this, new OnUnbanArgs {
                            UnbannedBy = cma.CreatedBy, UnbannedByUserId = cma.CreatedByUserId, UnbannedUserId = cma.TargetUserId, UnbannedUser = cma.Args[0], ChannelId = channelId
                        });
                        return;

                    case "untimeout":
                        OnUntimeout?.Invoke(this, new OnUntimeoutArgs {
                            UntimeoutedBy = cma.CreatedBy, UntimeoutedByUserId = cma.CreatedByUserId, UntimeoutedUserId = cma.TargetUserId, UntimeoutedUser = cma.Args[0], ChannelId = channelId
                        });
                        return;

                    case "host":
                        OnHost?.Invoke(this, new OnHostArgs {
                            HostedChannel = cma.Args[0], Moderator = cma.CreatedBy, ChannelId = channelId
                        });
                        return;

                    case "subscribers":
                        OnSubscribersOnly?.Invoke(this, new OnSubscribersOnlyArgs {
                            Moderator = cma.CreatedBy, ChannelId = channelId
                        });
                        return;

                    case "subscribersoff":
                        OnSubscribersOnlyOff?.Invoke(this, new OnSubscribersOnlyOffArgs {
                            Moderator = cma.CreatedBy, ChannelId = channelId
                        });
                        return;

                    case "clear":
                        OnClear?.Invoke(this, new OnClearArgs {
                            Moderator = cma.CreatedBy, ChannelId = channelId
                        });
                        return;

                    case "emoteonly":
                        OnEmoteOnly?.Invoke(this, new OnEmoteOnlyArgs {
                            Moderator = cma.CreatedBy, ChannelId = channelId
                        });
                        return;

                    case "emoteonlyoff":
                        OnEmoteOnlyOff?.Invoke(this, new OnEmoteOnlyOffArgs {
                            Moderator = cma.CreatedBy, ChannelId = channelId
                        });
                        return;

                    case "r9kbeta":
                        OnR9kBeta?.Invoke(this, new OnR9kBetaArgs {
                            Moderator = cma.CreatedBy, ChannelId = channelId
                        });
                        return;

                    case "r9kbetaoff":
                        OnR9kBetaOff?.Invoke(this, new OnR9kBetaOffArgs {
                            Moderator = cma.CreatedBy, ChannelId = channelId
                        });
                        return;
                    }
                    break;

                case "channel-bits-events-v1":
                    if (msg.MessageData is ChannelBitsEvents cbe)
                    {
                        OnBitsReceived?.Invoke(this, new OnBitsReceivedArgs
                        {
                            BitsUsed      = cbe.BitsUsed,
                            ChannelId     = cbe.ChannelId,
                            ChannelName   = cbe.ChannelName,
                            ChatMessage   = cbe.ChatMessage,
                            Context       = cbe.Context,
                            Time          = cbe.Time,
                            TotalBitsUsed = cbe.TotalBitsUsed,
                            UserId        = cbe.UserId,
                            Username      = cbe.Username
                        });
                        return;
                    }
                    break;

                case "channel-commerce-events-v1":
                    if (msg.MessageData is ChannelCommerceEvents cce)
                    {
                        OnChannelCommerceReceived?.Invoke(this, new OnChannelCommerceReceivedArgs
                        {
                            Username        = cce.Username,
                            DisplayName     = cce.DisplayName,
                            ChannelName     = cce.ChannelName,
                            UserId          = cce.UserId,
                            ChannelId       = cce.ChannelId,
                            Time            = cce.Time,
                            ItemImageURL    = cce.ItemImageURL,
                            ItemDescription = cce.ItemDescription,
                            SupportsChannel = cce.SupportsChannel,
                            PurchaseMessage = cce.PurchaseMessage
                        });
                        return;
                    }
                    break;

                case "channel-ext-v1":
                    var cEB = msg.MessageData as ChannelExtensionBroadcast;
                    OnChannelExtensionBroadcast?.Invoke(this, new OnChannelExtensionBroadcastArgs {
                        Messages = cEB.Messages, ChannelId = channelId
                    });
                    return;

                case "video-playback":
                    var vP = msg.MessageData as VideoPlayback;
                    switch (vP?.Type)
                    {
                    case VideoPlaybackType.StreamDown:
                        OnStreamDown?.Invoke(this, new OnStreamDownArgs {
                            ServerTime = vP.ServerTime
                        });
                        return;

                    case VideoPlaybackType.StreamUp:
                        OnStreamUp?.Invoke(this, new OnStreamUpArgs {
                            PlayDelay = vP.PlayDelay, ServerTime = vP.ServerTime
                        });
                        return;

                    case VideoPlaybackType.ViewCount:
                        OnViewCount?.Invoke(this, new OnViewCountArgs {
                            ServerTime = vP.ServerTime, Viewers = vP.Viewers
                        });
                        return;

                    case VideoPlaybackType.Commercial:
                        OnCommercial?.Invoke(this, new OnCommercialArgs {
                            ServerTime = vP.ServerTime, Length = vP.Length
                        });
                        return;
                    }
                    break;

                case "following":
                    var f = (Following)msg.MessageData;
                    f.FollowedChannelId = msg.Topic.Split('.')[1];
                    OnFollow?.Invoke(this, new OnFollowArgs {
                        FollowedChannelId = f.FollowedChannelId, DisplayName = f.DisplayName, UserId = f.UserId, Username = f.Username
                    });
                    return;
                }
                break;
            }
            UnaccountedFor(message);
        }
Esempio n. 13
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
            {
            }
        }
        private void OnMessage(object sender, byte[] messagePayload)
        {
            try
            {
                string           payload = Encoding.UTF8.GetString(messagePayload);
                FizzTopicMessage message = new FizzTopicMessage(payload);

                FizzLogger.D("OnMessage with id: " + message.Id);

                switch (message.Type)
                {
                case "CMSGP":
                    if (OnMessagePublished != null)
                    {
                        OnMessagePublished.Invoke(AdaptTo(message));
                    }
                    break;

                case "CMSGU":
                    if (OnMessageUpdated != null)
                    {
                        OnMessageUpdated.Invoke(AdaptTo(message));
                    }
                    break;

                case "CMSGD":
                    if (OnMessageDeleted != null)
                    {
                        OnMessageDeleted.Invoke(AdaptTo(message));
                    }
                    break;

                case "GRPMA":
                    if (OnGroupMemberAdded != null)
                    {
                        OnGroupMemberAdded.Invoke(ParseMemberEventData(message));
                    }
                    break;

                case "GRPMU":
                    if (OnGroupMemberUpdated != null)
                    {
                        OnGroupMemberUpdated.Invoke(ParseMemberEventData(message));
                    }
                    break;

                case "GRPMR":
                    if (OnGroupMemberRemoved != null)
                    {
                        OnGroupMemberRemoved.Invoke(ParseMemberEventData(message));
                    }
                    break;

                case "GRPU":
                    if (OnGroupUpdated != null)
                    {
                        OnGroupUpdated.Invoke(ParseGroupUpdateEventData(message));
                    }
                    break;

                case "USRPU":
                    if (OnUserUpdated != null)
                    {
                        OnUserUpdated.Invoke(ParsePresenceUpdateEventData(message));
                    }
                    break;

                case "USRU":
                    if (OnUserUpdated != null)
                    {
                        OnUserUpdated.Invoke(ParseUserUpdateEventData(message));
                    }
                    break;

                default:
                    FizzLogger.W("unrecognized packet received: " + payload);
                    break;
                }
            }
            catch
            {
                FizzLogger.W("received invalid message: " + messagePayload);
            }
        }
Esempio n. 15
0
        public PubSub(EndPoint proxy = null) : base(null)
        {
            ThreadDispatcher.EnsureCreated();

            base.OnPubSubServiceConnected += ((object sender, EventArgs e) => { ThreadDispatcher.Enqueue(() => OnPubSubServiceConnected?.Invoke(sender, e)); });
            base.OnPubSubServiceError     += ((object sender, OnPubSubServiceErrorArgs e) => { ThreadDispatcher.Enqueue(() => OnPubSubServiceError?.Invoke(sender, e)); });
            base.OnPubSubServiceClosed    += ((object sender, EventArgs e) => { ThreadDispatcher.Enqueue(() => OnPubSubServiceClosed?.Invoke(sender, e)); });
            base.OnListenResponse         += ((object sender, OnListenResponseArgs e) => { ThreadDispatcher.Enqueue(() => OnListenResponse?.Invoke(sender, e)); });
            base.OnTimeout                   += ((object sender, OnTimeoutArgs e) => { ThreadDispatcher.Enqueue(() => OnTimeout?.Invoke(sender, e)); });
            base.OnBan                       += ((object sender, OnBanArgs e) => { ThreadDispatcher.Enqueue(() => OnBan?.Invoke(sender, e)); });
            base.OnUnban                     += ((object sender, OnUnbanArgs e) => { ThreadDispatcher.Enqueue(() => OnUnban?.Invoke(sender, e)); });
            base.OnUntimeout                 += ((object sender, OnUntimeoutArgs e) => { ThreadDispatcher.Enqueue(() => OnUntimeout?.Invoke(sender, e)); });
            base.OnHost                      += ((object sender, OnHostArgs e) => { ThreadDispatcher.Enqueue(() => OnHost?.Invoke(sender, e)); });
            base.OnSubscribersOnly           += ((object sender, OnSubscribersOnlyArgs e) => { ThreadDispatcher.Enqueue(() => OnSubscribersOnly?.Invoke(sender, e)); });
            base.OnSubscribersOnlyOff        += ((object sender, OnSubscribersOnlyOffArgs e) => { ThreadDispatcher.Enqueue(() => OnSubscribersOnlyOff?.Invoke(sender, e)); });
            base.OnClear                     += ((object sender, OnClearArgs e) => { ThreadDispatcher.Enqueue(() => OnClear?.Invoke(sender, e)); });
            base.OnEmoteOnly                 += ((object sender, OnEmoteOnlyArgs e) => { ThreadDispatcher.Enqueue(() => OnEmoteOnly?.Invoke(sender, e)); });
            base.OnEmoteOnlyOff              += ((object sender, OnEmoteOnlyOffArgs e) => { ThreadDispatcher.Enqueue(() => OnEmoteOnlyOff?.Invoke(sender, e)); });
            base.OnR9kBeta                   += ((object sender, OnR9kBetaArgs e) => { ThreadDispatcher.Enqueue(() => OnR9kBeta?.Invoke(sender, e)); });
            base.OnR9kBetaOff                += ((object sender, OnR9kBetaOffArgs e) => { ThreadDispatcher.Enqueue(() => OnR9kBetaOff?.Invoke(sender, e)); });
            base.OnBitsReceived              += ((object sender, OnBitsReceivedArgs e) => { ThreadDispatcher.Enqueue(() => OnBitsReceived?.Invoke(sender, e)); });
            base.OnStreamUp                  += ((object sender, OnStreamUpArgs arg) => { ThreadDispatcher.Enqueue(() => OnStreamUp(sender, arg)); });
            base.OnStreamDown                += ((object sender, OnStreamDownArgs e) => { ThreadDispatcher.Enqueue(() => OnStreamDown?.Invoke(sender, e)); });
            base.OnViewCount                 += ((object sender, OnViewCountArgs e) => { ThreadDispatcher.Enqueue(() => OnViewCount?.Invoke(sender, e)); });
            base.OnWhisper                   += ((object sender, OnWhisperArgs e) => { ThreadDispatcher.Enqueue(() => OnWhisper?.Invoke(sender, e)); });
            base.OnChannelSubscription       += ((object sender, OnChannelSubscriptionArgs e) => { ThreadDispatcher.Enqueue(() => OnChannelSubscription?.Invoke(sender, e)); });
            base.OnChannelCommerceReceived   += ((object sender, OnChannelCommerceReceivedArgs e) => { ThreadDispatcher.Enqueue(() => OnChannelCommerceReceived?.Invoke(sender, e)); });
            base.OnChannelExtensionBroadcast += ((object sender, OnChannelExtensionBroadcastArgs e) => { ThreadDispatcher.Enqueue(() => OnChannelExtensionBroadcast?.Invoke(sender, e)); });
            base.OnFollow                    += ((object sender, OnFollowArgs e) => { ThreadDispatcher.Enqueue(() => OnFollow?.Invoke(sender, e)); });
            base.OnCustomRewardCreated       += ((object sender, OnCustomRewardCreatedArgs e) => { ThreadDispatcher.Enqueue(() => OnCustomRewardCreated?.Invoke(sender, e)); });
            base.OnCustomRewardUpdated       += ((object sender, OnCustomRewardUpdatedArgs e) => { ThreadDispatcher.Enqueue(() => OnCustomRewardUpdated?.Invoke(sender, e)); });
            base.OnCustomRewardDeleted       += ((object sender, OnCustomRewardDeletedArgs e) => { ThreadDispatcher.Enqueue(() => OnCustomRewardDeleted?.Invoke(sender, e)); });
            base.OnRewardRedeemed            += ((object sender, OnRewardRedeemedArgs e) => { ThreadDispatcher.Enqueue(() => OnRewardRedeemed?.Invoke(sender, e)); });
            base.OnBitsReceivedV2            += ((object sender, OnBitsReceivedV2Args e) => { ThreadDispatcher.Enqueue(() => OnBitsReceivedV2?.Invoke(sender, e)); });
            base.OnLeaderboardSubs           += ((object sender, OnLeaderboardEventArgs e) => { ThreadDispatcher.Enqueue(() => OnLeaderboardSubs?.Invoke(sender, e)); });
            base.OnLeaderboardBits           += ((object sender, OnLeaderboardEventArgs e) => { ThreadDispatcher.Enqueue(() => OnLeaderboardBits?.Invoke(sender, e)); });
            base.OnRaidUpdate                += ((object sender, OnRaidUpdateArgs e) => { ThreadDispatcher.Enqueue(() => OnRaidUpdate?.Invoke(sender, e)); });
            base.OnRaidUpdateV2              += ((object sender, OnRaidUpdateV2Args e) => { ThreadDispatcher.Enqueue(() => OnRaidUpdateV2?.Invoke(sender, e)); });
            base.OnRaidGo                    += ((object sender, OnRaidGoArgs e) => { ThreadDispatcher.Enqueue(() => OnRaidGo?.Invoke(sender, e)); });
            base.OnMessageDeleted            += ((object sender, OnMessageDeletedArgs e) => { ThreadDispatcher.Enqueue(() => OnMessageDeleted?.Invoke(sender, e)); });
            base.OnLog                       += ((object sender, OnLogArgs e) => { ThreadDispatcher.Enqueue(() => OnLog?.Invoke(sender, e)); });
            base.OnCommercial                += ((object sender, OnCommercialArgs e) => { ThreadDispatcher.Enqueue(() => OnCommercial?.Invoke(sender, e)); });
            base.OnPrediction                += ((object sender, OnPredictionArgs e) => { ThreadDispatcher.Enqueue(() => OnPrediction?.Invoke(sender, e)); });
        }
Esempio n. 16
0
        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;
            }
        }
Esempio n. 17
0
        /// <summary>
        /// Parses the message.
        /// </summary>
        /// <param name="message">The message.</param>
        private void ParseMessage(string message)
        {
            var type = JObject.Parse(message).SelectToken("type")?.ToString();

            switch (type?.ToLower())
            {
            case "response":
                var resp = new Models.Responses.Response(message);
                if (_previousRequests.Count != 0)
                {
                    bool handled = false;
                    _previousRequestsSemaphore.WaitOne();
                    try
                    {
                        for (int i = 0; i < _previousRequests.Count;)
                        {
                            var request = _previousRequests[i];
                            if (string.Equals(request.Nonce, resp.Nonce, StringComparison.CurrentCulture))
                            {
                                //Remove the request.
                                _previousRequests.RemoveAt(i);
                                _topicToChannelId.TryGetValue(request.Topic, out var requestChannelId);
                                OnListenResponse?.Invoke(this, new OnListenResponseArgs {
                                    Response = resp, Topic = request.Topic, Successful = resp.Successful, ChannelId = requestChannelId
                                });
                                handled = true;
                            }
                            else
                            {
                                i++;
                            }
                        }
                    }
                    finally
                    {
                        _previousRequestsSemaphore.Release();
                    }
                    if (handled)
                    {
                        return;
                    }
                }
                break;

            case "message":
                var msg = new Models.Responses.Message(message);
                _topicToChannelId.TryGetValue(msg.Topic, out var channelId);
                channelId = channelId ?? "";
                switch (msg.Topic.Split('.')[0])
                {
                case "user-moderation-notifications":
                    var userModerationNotifications = msg.MessageData as UserModerationNotifications;
                    switch (userModerationNotifications.Type)
                    {
                    case UserModerationNotificationsType.AutomodCaughtMessage:
                        var automodCaughtMessage = userModerationNotifications.Data as Models.Responses.Messages.UserModerationNotificationsTypes.AutomodCaughtMessage;
                        OnAutomodCaughtUserMessage?.Invoke(this, new OnAutomodCaughtUserMessage {
                            ChannelId = channelId, UserId = msg.Topic.Split('.')[2], AutomodCaughtMessage = automodCaughtMessage
                        });
                        break;

                    case UserModerationNotificationsType.Unknown:
                        break;
                    }
                    return;

                case "automod-queue":
                    var automodQueue = msg.MessageData as AutomodQueue;
                    switch (automodQueue.Type)
                    {
                    case AutomodQueueType.CaughtMessage:
                        var caughtMessage = automodQueue.Data as AutomodCaughtMessage;
                        OnAutomodCaughtMessage?.Invoke(this, new OnAutomodCaughtMessageArgs {
                            ChannelId = channelId, AutomodCaughtMessage = caughtMessage
                        });
                        break;

                    case AutomodQueueType.Unknown:
                        UnaccountedFor($"Unknown automod queue type. Msg: {automodQueue.RawData}");
                        break;
                    }
                    return;

                case "channel-subscribe-events-v1":
                    var subscription = msg.MessageData as ChannelSubscription;
                    OnChannelSubscription?.Invoke(this, new OnChannelSubscriptionArgs {
                        Subscription = subscription, ChannelId = channelId
                    });
                    return;

                case "whispers":
                    var whisper = (Whisper)msg.MessageData;
                    OnWhisper?.Invoke(this, new OnWhisperArgs {
                        Whisper = whisper, ChannelId = channelId
                    });
                    return;

                case "chat_moderator_actions":
                    var cma    = msg.MessageData as ChatModeratorActions;
                    var reason = "";
                    switch (cma?.ModerationAction.ToLower())
                    {
                    case "timeout":
                        if (cma.Args.Count > 2)
                        {
                            reason = cma.Args[2];
                        }
                        OnTimeout?.Invoke(this, new OnTimeoutArgs
                        {
                            TimedoutBy      = cma.CreatedBy,
                            TimedoutById    = cma.CreatedByUserId,
                            TimedoutUserId  = cma.TargetUserId,
                            TimeoutDuration = TimeSpan.FromSeconds(int.Parse(cma.Args[1])),
                            TimeoutReason   = reason,
                            TimedoutUser    = cma.Args[0],
                            ChannelId       = channelId
                        });
                        return;

                    case "ban":
                        if (cma.Args.Count > 1)
                        {
                            reason = cma.Args[1];
                        }
                        OnBan?.Invoke(this, new OnBanArgs {
                            BannedBy = cma.CreatedBy, BannedByUserId = cma.CreatedByUserId, BannedUserId = cma.TargetUserId, BanReason = reason, BannedUser = cma.Args[0], ChannelId = channelId
                        });
                        return;

                    case "delete":
                        OnMessageDeleted?.Invoke(this, new OnMessageDeletedArgs {
                            DeletedBy = cma.CreatedBy, DeletedByUserId = cma.CreatedByUserId, TargetUserId = cma.TargetUserId, TargetUser = cma.Args[0], Message = cma.Args[1], MessageId = cma.Args[2], ChannelId = channelId
                        });
                        return;

                    case "unban":
                        OnUnban?.Invoke(this, new OnUnbanArgs {
                            UnbannedBy = cma.CreatedBy, UnbannedByUserId = cma.CreatedByUserId, UnbannedUserId = cma.TargetUserId, UnbannedUser = cma.Args[0], ChannelId = channelId
                        });
                        return;

                    case "untimeout":
                        OnUntimeout?.Invoke(this, new OnUntimeoutArgs {
                            UntimeoutedBy = cma.CreatedBy, UntimeoutedByUserId = cma.CreatedByUserId, UntimeoutedUserId = cma.TargetUserId, UntimeoutedUser = cma.Args[0], ChannelId = channelId
                        });
                        return;

                    case "host":
                        OnHost?.Invoke(this, new OnHostArgs {
                            HostedChannel = cma.Args[0], Moderator = cma.CreatedBy, ChannelId = channelId
                        });
                        return;

                    case "subscribers":
                        OnSubscribersOnly?.Invoke(this, new OnSubscribersOnlyArgs {
                            Moderator = cma.CreatedBy, ChannelId = channelId
                        });
                        return;

                    case "subscribersoff":
                        OnSubscribersOnlyOff?.Invoke(this, new OnSubscribersOnlyOffArgs {
                            Moderator = cma.CreatedBy, ChannelId = channelId
                        });
                        return;

                    case "clear":
                        OnClear?.Invoke(this, new OnClearArgs {
                            Moderator = cma.CreatedBy, ChannelId = channelId
                        });
                        return;

                    case "emoteonly":
                        OnEmoteOnly?.Invoke(this, new OnEmoteOnlyArgs {
                            Moderator = cma.CreatedBy, ChannelId = channelId
                        });
                        return;

                    case "emoteonlyoff":
                        OnEmoteOnlyOff?.Invoke(this, new OnEmoteOnlyOffArgs {
                            Moderator = cma.CreatedBy, ChannelId = channelId
                        });
                        return;

                    case "r9kbeta":
                        OnR9kBeta?.Invoke(this, new OnR9kBetaArgs {
                            Moderator = cma.CreatedBy, ChannelId = channelId
                        });
                        return;

                    case "r9kbetaoff":
                        OnR9kBetaOff?.Invoke(this, new OnR9kBetaOffArgs {
                            Moderator = cma.CreatedBy, ChannelId = channelId
                        });
                        return;
                    }
                    break;

                case "channel-bits-events-v1":
                    if (msg.MessageData is ChannelBitsEvents cbe)
                    {
                        OnBitsReceived?.Invoke(this, new OnBitsReceivedArgs
                        {
                            BitsUsed      = cbe.BitsUsed,
                            ChannelId     = cbe.ChannelId,
                            ChannelName   = cbe.ChannelName,
                            ChatMessage   = cbe.ChatMessage,
                            Context       = cbe.Context,
                            Time          = cbe.Time,
                            TotalBitsUsed = cbe.TotalBitsUsed,
                            UserId        = cbe.UserId,
                            Username      = cbe.Username
                        });
                        return;
                    }
                    break;

                case "channel-bits-events-v2":
                    if (msg.MessageData is ChannelBitsEventsV2 cbev2)
                    {
                        OnBitsReceivedV2?.Invoke(this, new OnBitsReceivedV2Args
                        {
                            IsAnonymous   = cbev2.IsAnonymous,
                            BitsUsed      = cbev2.BitsUsed,
                            ChannelId     = cbev2.ChannelId,
                            ChannelName   = cbev2.ChannelName,
                            ChatMessage   = cbev2.ChatMessage,
                            Context       = cbev2.Context,
                            Time          = cbev2.Time,
                            TotalBitsUsed = cbev2.TotalBitsUsed,
                            UserId        = cbev2.UserId,
                            UserName      = cbev2.UserName
                        });
                        return;
                    }
                    break;

                case "channel-commerce-events-v1":
                    if (msg.MessageData is ChannelCommerceEvents cce)
                    {
                        OnChannelCommerceReceived?.Invoke(this, new OnChannelCommerceReceivedArgs
                        {
                            Username        = cce.Username,
                            DisplayName     = cce.DisplayName,
                            ChannelName     = cce.ChannelName,
                            UserId          = cce.UserId,
                            ChannelId       = cce.ChannelId,
                            Time            = cce.Time,
                            ItemImageURL    = cce.ItemImageURL,
                            ItemDescription = cce.ItemDescription,
                            SupportsChannel = cce.SupportsChannel,
                            PurchaseMessage = cce.PurchaseMessage
                        });
                        return;
                    }
                    break;

                case "channel-ext-v1":
                    var cEB = msg.MessageData as ChannelExtensionBroadcast;
                    OnChannelExtensionBroadcast?.Invoke(this, new OnChannelExtensionBroadcastArgs {
                        Messages = cEB.Messages, ChannelId = channelId
                    });
                    return;

                case "video-playback-by-id":
                    var vP = msg.MessageData as VideoPlayback;
                    switch (vP?.Type)
                    {
                    case VideoPlaybackType.StreamDown:
                        OnStreamDown?.Invoke(this, new OnStreamDownArgs {
                            ServerTime = vP.ServerTime, ChannelId = channelId
                        });
                        return;

                    case VideoPlaybackType.StreamUp:
                        OnStreamUp?.Invoke(this, new OnStreamUpArgs {
                            PlayDelay = vP.PlayDelay, ServerTime = vP.ServerTime, ChannelId = channelId
                        });
                        return;

                    case VideoPlaybackType.ViewCount:
                        OnViewCount?.Invoke(this, new OnViewCountArgs {
                            ServerTime = vP.ServerTime, Viewers = vP.Viewers, ChannelId = channelId
                        });
                        return;

                    case VideoPlaybackType.Commercial:
                        OnCommercial?.Invoke(this, new OnCommercialArgs {
                            ServerTime = vP.ServerTime, Length = vP.Length, ChannelId = channelId
                        });
                        return;
                    }
                    break;

                case "following":
                    var f = (Following)msg.MessageData;
                    f.FollowedChannelId = msg.Topic.Split('.')[1];
                    OnFollow?.Invoke(this, new OnFollowArgs {
                        FollowedChannelId = f.FollowedChannelId, DisplayName = f.DisplayName, UserId = f.UserId, Username = f.Username
                    });
                    return;

                case "community-points-channel-v1":
                    var cpc = msg.MessageData as CommunityPointsChannel;
                    switch (cpc?.Type)
                    {
                    case CommunityPointsChannelType.RewardRedeemed:
                        OnRewardRedeemed?.Invoke(this, new OnRewardRedeemedArgs {
                            TimeStamp = cpc.TimeStamp, ChannelId = cpc.ChannelId, Login = cpc.Login, DisplayName = cpc.DisplayName, Message = cpc.Message, RewardId = cpc.RewardId, RewardTitle = cpc.RewardTitle, RewardPrompt = cpc.RewardPrompt, RewardCost = cpc.RewardCost, Status = cpc.Status, RedemptionId = cpc.RedemptionId
                        });
                        return;

                    case CommunityPointsChannelType.CustomRewardUpdated:
                        OnCustomRewardUpdated?.Invoke(this, new OnCustomRewardUpdatedArgs {
                            TimeStamp = cpc.TimeStamp, ChannelId = cpc.ChannelId, RewardId = cpc.RewardId, RewardTitle = cpc.RewardTitle, RewardPrompt = cpc.RewardPrompt, RewardCost = cpc.RewardCost
                        });
                        return;

                    case CommunityPointsChannelType.CustomRewardCreated:
                        OnCustomRewardCreated?.Invoke(this, new OnCustomRewardCreatedArgs {
                            TimeStamp = cpc.TimeStamp, ChannelId = cpc.ChannelId, RewardId = cpc.RewardId, RewardTitle = cpc.RewardTitle, RewardPrompt = cpc.RewardPrompt, RewardCost = cpc.RewardCost
                        });
                        return;

                    case CommunityPointsChannelType.CustomRewardDeleted:
                        OnCustomRewardDeleted?.Invoke(this, new OnCustomRewardDeletedArgs {
                            TimeStamp = cpc.TimeStamp, ChannelId = cpc.ChannelId, RewardId = cpc.RewardId, RewardTitle = cpc.RewardTitle, RewardPrompt = cpc.RewardPrompt
                        });
                        return;
                    }
                    return;

                case "channel-points-channel-v1":
                    var channelPointsChannel = msg.MessageData as ChannelPointsChannel;
                    switch (channelPointsChannel.Type)
                    {
                    case ChannelPointsChannelType.RewardRedeemed:
                        var rewardRedeemed = channelPointsChannel.Data as RewardRedeemed;
                        OnChannelPointsRewardRedeemed?.Invoke(this, new OnChannelPointsRewardRedeemedArgs {
                            ChannelId = rewardRedeemed.Redemption.ChannelId, RewardRedeemed = rewardRedeemed
                        });
                        break;

                    case ChannelPointsChannelType.Unknown:
                        UnaccountedFor($"Unknown channel points type. Msg: {channelPointsChannel.RawData}");
                        break;
                    }
                    return;

                case "leaderboard-events-v1":
                    var lbe = msg.MessageData as LeaderboardEvents;
                    switch (lbe?.Type)
                    {
                    case LeaderBoardType.BitsUsageByChannel:
                        OnLeaderboardBits?.Invoke(this, new OnLeaderboardEventArgs {
                            ChannelId = lbe.ChannelId, TopList = lbe.Top
                        });
                        return;

                    case LeaderBoardType.SubGiftSent:
                        OnLeaderboardSubs?.Invoke(this, new OnLeaderboardEventArgs {
                            ChannelId = lbe.ChannelId, TopList = lbe.Top
                        });
                        return;
                    }
                    return;

                case "raid":
                    var r = msg.MessageData as RaidEvents;
                    switch (r?.Type)
                    {
                    case RaidType.RaidUpdate:
                        OnRaidUpdate?.Invoke(this, new OnRaidUpdateArgs {
                            Id = r.Id, ChannelId = r.ChannelId, TargetChannelId = r.TargetChannelId, AnnounceTime = r.AnnounceTime, RaidTime = r.RaidTime, RemainingDurationSeconds = r.RemainigDurationSeconds, ViewerCount = r.ViewerCount
                        });
                        return;

                    case RaidType.RaidUpdateV2:
                        OnRaidUpdateV2?.Invoke(this, new OnRaidUpdateV2Args {
                            Id = r.Id, ChannelId = r.ChannelId, TargetChannelId = r.TargetChannelId, TargetLogin = r.TargetLogin, TargetDisplayName = r.TargetDisplayName, TargetProfileImage = r.TargetProfileImage, ViewerCount = r.ViewerCount
                        });
                        return;

                    case RaidType.RaidGo:
                        OnRaidGo?.Invoke(this, new OnRaidGoArgs {
                            Id = r.Id, ChannelId = r.ChannelId, TargetChannelId = r.TargetChannelId, TargetLogin = r.TargetLogin, TargetDisplayName = r.TargetDisplayName, TargetProfileImage = r.TargetProfileImage, ViewerCount = r.ViewerCount
                        });
                        return;
                    }
                    return;

                case "predictions-channel-v1":
                    var pred = msg.MessageData as PredictionEvents;
                    switch (pred?.Type)
                    {
                    case PredictionType.EventCreated:
                        OnPrediction?.Invoke(this, new OnPredictionArgs {
                            CreatedAt = pred.CreatedAt, Title = pred.Title, ChannelId = pred.ChannelId, EndedAt = pred.EndedAt, Id = pred.Id, Outcomes = pred.Outcomes, LockedAt = pred.LockedAt, PredictionTime = pred.PredictionTime, Status = pred.Status, WinningOutcomeId = pred.WinningOutcomeId, Type = pred.Type
                        });
                        return;

                    case PredictionType.EventUpdated:
                        OnPrediction?.Invoke(this, new OnPredictionArgs {
                            CreatedAt = pred.CreatedAt, Title = pred.Title, ChannelId = pred.ChannelId, EndedAt = pred.EndedAt, Id = pred.Id, Outcomes = pred.Outcomes, LockedAt = pred.LockedAt, PredictionTime = pred.PredictionTime, Status = pred.Status, WinningOutcomeId = pred.WinningOutcomeId, Type = pred.Type
                        });
                        return;

                    case null:
                        UnaccountedFor("Prediction Type: null");
                        break;

                    default:
                        UnaccountedFor($"Prediction Type: {pred.Type}");
                        break;
                    }
                    return;
                }
                break;

            case "pong":
                _pongReceived = true;
                return;

            case "reconnect": _socket.Close(); break;
            }
            UnaccountedFor(message);
        }
Esempio n. 18
0
 public static void RemoveMessage(TextMessage message)
 {
     Messages.Remove(message);
     OnMessageDeleted?.Invoke();
 }