Exemple #1
0
        /// <summary>
        /// Disconnect user
        /// </summary>
        /// <param name="user">User</param>
        /// <param name="disconnectReason">Disconnect reason</param>
        /// <returns>"true" if disconnected, otherwise "false"</returns>
        public bool DisconnectUser(IUser user, EDisconnectReason disconnectReason)
        {
            bool ret = false;

            if (user != null)
            {
                lock (users)
                {
                    if (IsRealUser(user))
                    {
                        IUser real_user = GetRealUser(user);
                        if (real_user != null)
                        {
                            if (real_user is ServerUser)
                            {
                                ServerUser server_user = (ServerUser)real_user;
                                ret = (disconnectReason == (EDisconnectReason.Banned) ? Bans.AddPattern(Regex.Escape(server_user.ServerConnection.IPAddress.ToString())) : true);
                                serverListener.Disconnect(server_user.ServerConnection);
                            }
                            else if (real_user is BotUser)
                            {
                                ret = true;
                            }
                            if (ret)
                            {
                                users.Remove(real_user.ID);
                                switch (disconnectReason)
                                {
                                case EDisconnectReason.Left:
                                    OnUserLeft?.Invoke(real_user);
                                    break;

                                case EDisconnectReason.Kicked:
                                    OnUserKicked?.Invoke(real_user);
                                    break;

                                case EDisconnectReason.Banned:
                                    OnUserBanned?.Invoke(real_user);
                                    break;

                                case EDisconnectReason.TimedOut:
                                    OnUserTimedOut?.Invoke(real_user);
                                    break;
                                }
                                foreach (IUser u in users)
                                {
                                    ServerUser server_user = u as ServerUser;
                                    if (server_user != null)
                                    {
                                        server_user.ServerConnection.SendUserLeftMessageAsync(real_user);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return(ret);
        }
    private void Awake()
    {
        client = new Twitch.Client();

        // Transfert events
        client.OnDisconnected       += (s, e) => OnDisconnected?.Invoke(this, e);
        client.OnConnectionError    += (s, e) => OnConnectionError?.Invoke(this, e);
        client.OnChatCleared        += (s, e) => OnChatCleared?.Invoke(this, e);
        client.OnUserTimedout       += (s, e) => OnUserTimedout?.Invoke(this, e);
        client.OnLeftChannel        += (s, e) => OnLeftChannel?.Invoke(this, e);
        client.OnUserBanned         += (s, e) => OnUserBanned?.Invoke(this, e);
        client.OnModeratorsReceived += (s, e) => OnModeratorsReceived?.Invoke(this, e);
        client.OnChatColorChanged   += (s, e) => OnChatColorChanged?.Invoke(this, e);
        client.OnSendReceiveData    += (s, e) => OnSendReceiveData?.Invoke(this, e);
        client.OnNowHosting         += (s, e) => OnNowHosting?.Invoke(this, e);
        //client.OnBeingHosted                        += (s, e) => OnBeingHosted                      ?.Invoke(this, e);
        client.OnRaidNotification              += (s, e) => OnRaidNotification?.Invoke(this, e);
        client.OnGiftedSubscription            += (s, e) => OnGiftedSubscription?.Invoke(this, e);
        client.OnSelfRaidError                 += (s, e) => OnSelfRaidError?.Invoke(this, e);
        client.OnNoPermissionError             += (s, e) => OnNoPermissionError?.Invoke(this, e);
        client.OnRaidedChannelIsMatureAudience += (s, e) => OnRaidedChannelIsMatureAudience?.Invoke(this, e);
        client.OnRitualNewChatter              += (s, e) => OnRitualNewChatter?.Invoke(this, e);
        client.OnHostingStopped                += (s, e) => OnHostingStopped?.Invoke(this, e);
        client.OnHostingStarted                += (s, e) => OnHostingStarted?.Invoke(this, e);
        client.OnUserLeft += (s, e) => OnUserLeft?.Invoke(this, e);
        client.OnExistingUsersDetected += (s, e) => OnExistingUsersDetected?.Invoke(this, e);
        client.OnLog                 += (s, e) => OnLog?.Invoke(this, e);
        client.OnConnected           += (s, e) => OnConnected?.Invoke(this, e);
        client.OnJoinedChannel       += (s, e) => OnJoinedChannel?.Invoke(this, e);
        client.OnIncorrectLogin      += (s, e) => OnIncorrectLogin?.Invoke(this, e);
        client.OnChannelStateChanged += (s, e) => OnChannelStateChanged?.Invoke(this, e);
        client.OnUserStateChanged    += (s, e) => OnUserStateChanged?.Invoke(this, e);
        client.OnMessageReceived     += (s, e) => OnMessageReceived?.Invoke(this, e);
        client.OnWhisperReceived     += (s, e) => OnWhisperReceived?.Invoke(this, e);
        client.OnFailureToReceiveJoinConfirmation += (s, e) => OnFailureToReceiveJoinConfirmation?.Invoke(this, e);
        client.OnMessageSent            += (s, e) => OnMessageSent?.Invoke(this, e);
        client.OnChatCommandReceived    += (s, e) => OnChatCommandReceived?.Invoke(this, e);
        client.OnWhisperCommandReceived += (s, e) => OnWhisperCommandReceived?.Invoke(this, e);
        client.OnUserJoined             += (s, e) => OnUserJoined?.Invoke(this, e);
        client.OnModeratorJoined        += (s, e) => OnModeratorJoined?.Invoke(this, e);
        client.OnModeratorLeft          += (s, e) => OnModeratorLeft?.Invoke(this, e);
        client.OnNewSubscriber          += (s, e) => OnNewSubscriber?.Invoke(this, e);
        client.OnReSubscriber           += (s, e) => OnReSubscriber?.Invoke(this, e);
        client.OnHostLeft       += (s, e) => OnHostLeft?.Invoke(this, e);
        client.OnWhisperSent    += (s, e) => OnWhisperSent?.Invoke(this, e);
        client.OnUnaccountedFor += (s, e) => OnUnaccountedFor?.Invoke(this, e);

        // Log client activity
        client.OnLog           += (s, e) => Debug.Log(e.Data);
        client.OnConnected     += (s, e) => NotificationManager.Instance.PushNotification("Connected to Twitch servers", Color.white, Color.green);
        client.OnJoinedChannel += (s, e) => NotificationManager.Instance.PushNotification($"Joined {e.Channel} channel", Color.white, Color.cyan);
        client.OnLeftChannel   += (s, e) => NotificationManager.Instance.PushNotification($"Left {e.Channel} channel", Color.white, Color.yellow);
        client.OnDisconnected  += (s, e) => NotificationManager.Instance.PushNotification("Disconnected from Twitch servers", Color.white, Color.red);
        client.OnFailureToReceiveJoinConfirmation += (s, e) => NotificationManager.Instance.PushNotification("Failed to join channel", Color.white, Color.magenta);
    }
Exemple #3
0
        private void PubSubService_OnBan(object sender, OnBanArgs e)
        {
            if (!UserIdChannelName.TryGetValue(e.ChannelId, out var channelName))
            {
                return;
            }

            OnUserBanned?.Invoke(this, new UserBannedEvent
            {
                BanReason = e.BanReason,
                Channel   = channelName,
                Username  = e.BannedUser,
                BannedBy  = e.BannedBy
            });
        }
        private void WebSocket_OnMessageReceived(object sender, DiscordWebSocketMessage <GatewayOpcode> message)
        {
            Sequence = message.Sequence;

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

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

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

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

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

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

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

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

                    LoggedIn = true;
                    State    = GatewayConnectionState.Connected;

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

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

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

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

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

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

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

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

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

                                        break;
                                    }
                                }
                            }
                        }
                    }

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

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

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

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

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

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

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

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

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

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

                    VoiceClients.Remove(guild.Id);

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

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

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

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

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

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

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

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

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

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

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

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

                            break;
                        }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                default:
                    break;
                }
                break;

            case GatewayOpcode.InvalidSession:
                LoggedIn = false;

                this.LoginToGateway();
                break;

            case GatewayOpcode.Connected:
                this.LoginToGateway();

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

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

                break;
            }
        }
Exemple #5
0
        internal void PushCommand(Command cmd)
        {
            if (cmd.Source == CommandSource.Client)
            {
                return;
            }

            switch (cmd.Token)
            {
            case "JCH":
            {
                var jch = cmd as Server_JCH_ChannelJoin;

                var character = Connection.GetOrCreateCharacter(jch.Character.Identity);

                if (!_Characters.Contains(character))
                {
                    _Characters.Add(character);
                }

                if (!string.IsNullOrEmpty(jch.Title))
                {
                    _Title = jch.Title;
                    Joined = true;
                }
                else
                {
                    OnUserJoin?.Invoke(this, new ChannelUserEntryEventArgs(this, character, jch));
                }
            }
                return;

            case "LCH":
            {
                var lch = cmd as Server_LCH_ChannelLeave;

                var character = GetCharacter(lch.Character);
                _Characters.Remove(character);

                if (character.Name == Connection.LocalCharacter.Name)
                {
                    Dispose();
                }
                else
                {
                    OnUserLeave?.Invoke(this, new ChannelUserEntryEventArgs(this, character, lch));
                }
            }
                return;

            case "ICH":
            {
                var ich = cmd as Server_ICH_ChannelInitialData;

                _ChannelMode = ich.Mode;
                Joined       = true;

                foreach (var user in ich.Users)
                {
                    var ch = GetCharacter(user.Identity);
                    if (!_Characters.Contains(ch))
                    {
                        _Characters.Add(ch);
                    }
                }
            }
                return;

            case "COL":
            {
                var col = cmd as Server_COL_ChannelGetOPs;

                foreach (var op in col.OPs)
                {
                    if (!string.IsNullOrWhiteSpace(op))
                    {
                        _OPs.Add(GetCharacter(op));
                    }
                }
            }
                return;

            case "CDS":
            {
                var cds = cmd as Server_CDS_ChannelChangeDescription;

                OnDescriptionChange?.Invoke(this, new ChannelEntryEventArgs <string>(this, cds.Description, cds));
                _Description = cds.Description;
            }
                return;

            case "RMO":
            {
                var rmo = cmd as Server_RMO_ChannelSetMode;

                OnModeChange?.Invoke(this, new ChannelEntryEventArgs <ChannelMode>(this, rmo.Mode, rmo));
                _ChannelMode = rmo.Mode;
            }
                return;

            case "CSO":
            {
                var cso = cmd as Server_CSO_ChannelSetOwner;

                OnOwnerChange?.Invoke(this, new ChannelEntryEventArgs <Character>(this, GetCharacter(cso.Character), cso));
                _OwnerName = cso.Character;
            }
                return;

            case "RST":
            {
                var rst = cmd as Server_RST_ChannelSetStatus;

                OnStatusChange?.Invoke(this, new ChannelEntryEventArgs <ChannelStatus>(this, rst.Status, rst));
                _Status = rst.Status;
            }
                return;

            case "COA":
            {
                var coa = cmd as Server_COA_ChannelMakeOP;

                var character = GetCharacter(coa.Character);
                _OPs.Add(character);

                OnOPAdded?.Invoke(this, new ChannelUserEntryEventArgs(this, character, coa));
            }
                return;

            case "COR":
            {
                var cor = cmd as Server_COR_ChannelRemoveOP;

                var character = GetCharacter(cor.Character);
                _OPs.Remove(character);

                OnOPRemoved?.Invoke(this, new ChannelUserEntryEventArgs(this, character, cor));
            }
                return;

            case "CKU":
            {
                var cku = cmd as Server_CKU_ChannelKickCharacter;

                var character = GetCharacter(cku.Character);
                _Characters.Remove(character);

                OnUserKicked?.Invoke(this, new ChannelAdminActionEventArgs(this, character, GetCharacter(cku.OP), cku));
            }
                return;

            case "CBU":
            {
                var cbu = cmd as Server_CBU_ChannelBanCharacter;

                var character = GetCharacter(cbu.Character);
                _Characters.Remove(character);

                _Banlist.Add(character);

                OnUserBanned?.Invoke(this, new ChannelAdminActionEventArgs(this, character, GetCharacter(cbu.OP), cbu));
            }
                return;

            case "CUB":
            {
                var cub = cmd as Server_CUB_ChannelUnbanCharacter;

                var character = GetCharacter(cub.Character);

                _Banlist.Remove(character);

                OnUserUnbanned?.Invoke(this, new ChannelAdminActionEventArgs(this, character, GetCharacter(cub.OP), cub));
            }
                return;

            case "CTU":
            {
                var ctu = cmd as Server_CTU_ChannelTimeoutCharacter;

                var character = GetCharacter(ctu.Character);
                _Characters.Remove(character);

                OnUserTimedout?.Invoke(this, new ChannelAdminActionEventArgs(this, character, GetCharacter(ctu.OP), ctu));
            }
                return;

            case "MSG":
            {
                var msg = cmd as Server_MSG_ChannelChatMessage;
                OnChatMessage?.Invoke(this, new ChannelUserMessageEventArgs(this, GetCharacter(msg.Character), msg.Message, msg));
            } return;

            case "LRP":
            {
                var lrp = cmd as Server_LRP_ChannelLFRPMessage;
                OnLFRPMessage?.Invoke(this, new ChannelUserMessageEventArgs(this, GetCharacter(lrp.Character), lrp.AD, lrp));
            } return;

            case "RLL":
            {
                var rll = cmd as Server_RLL_ChannelRollMessage;
                OnRollMessage?.Invoke(this, new ChannelUserMessageEventArgs(this, GetCharacter(rll.Character), rll.Message, rll));
            } return;

            case "SYS":
            {
                var sys = cmd as Server_SYS_ChatSYSMessage;
                OnSYSMessage?.Invoke(this, new ChannelEntryEventArgs <string>(this, sys.Message, sys));
            } return;
            }
        }
Exemple #6
0
        public Client() : base(null)
        {
            ThreadDispatcher.EnsureCreated();

            base.OverrideBeingHostedCheck = true;

            base.OnLog       += (object sender, OnLogArgs e) => { ThreadDispatcher.Enqueue(() => OnLog?.Invoke(sender, e)); };
            base.OnConnected += ((object sender, OnConnectedArgs e) => { ThreadDispatcher.Enqueue(() => OnConnected?.Invoke(sender, e)); });

            base.OnJoinedChannel += ((object sender, OnJoinedChannelArgs e) => {
                ThreadDispatcher.Enqueue(() => OnJoinedChannel?.Invoke(sender, e));

                if (OnBeingHosted == null)
                {
                    return;
                }
                if (e.Channel.ToLower() != TwitchUsername && !OverrideBeingHostedCheck)
                {
                    ThreadDispatcher.Enqueue(() => throw new BadListenException("BeingHosted", "You cannot listen to OnBeingHosted unless you are connected to the broadcaster's channel as the broadcaster. You may override this by setting the TwitchClient property OverrideBeingHostedCheck to true."));
                }
            });

            base.OnIncorrectLogin         += ((object sender, OnIncorrectLoginArgs e) => { ThreadDispatcher.Enqueue(() => OnIncorrectLogin?.Invoke(sender, e)); });
            base.OnChannelStateChanged    += ((object sender, OnChannelStateChangedArgs e) => { ThreadDispatcher.Enqueue(() => OnChannelStateChanged?.Invoke(sender, e)); });
            base.OnUserStateChanged       += ((object sender, OnUserStateChangedArgs e) => { ThreadDispatcher.Enqueue(() => OnUserStateChanged?.Invoke(sender, e)); });
            base.OnMessageReceived        += ((object sender, OnMessageReceivedArgs e) => { ThreadDispatcher.Enqueue(() => OnMessageReceived?.Invoke(sender, e)); });
            base.OnWhisperReceived        += ((object sender, OnWhisperReceivedArgs e) => { ThreadDispatcher.Enqueue(() => OnWhisperReceived?.Invoke(sender, e)); });
            base.OnMessageSent            += ((object sender, OnMessageSentArgs e) => { ThreadDispatcher.Enqueue(() => OnMessageSent?.Invoke(sender, e)); });
            base.OnWhisperSent            += ((object sender, OnWhisperSentArgs e) => { ThreadDispatcher.Enqueue(() => OnWhisperSent?.Invoke(sender, e)); });
            base.OnChatCommandReceived    += ((object sender, OnChatCommandReceivedArgs e) => { ThreadDispatcher.Enqueue(() => OnChatCommandReceived?.Invoke(sender, e)); });
            base.OnWhisperCommandReceived += ((object sender, OnWhisperCommandReceivedArgs e) => { ThreadDispatcher.Enqueue(() => OnWhisperCommandReceived?.Invoke(sender, e)); });
            base.OnUserJoined             += ((object sender, OnUserJoinedArgs e) => { ThreadDispatcher.Enqueue(() => OnUserJoined?.Invoke(sender, e)); });
            base.OnModeratorJoined        += ((object sender, OnModeratorJoinedArgs e) => { ThreadDispatcher.Enqueue(() => OnModeratorJoined?.Invoke(sender, e)); });
            base.OnModeratorLeft          += ((object sender, OnModeratorLeftArgs e) => { ThreadDispatcher.Enqueue(() => OnModeratorLeft?.Invoke(sender, e)); });
            base.OnNewSubscriber          += ((object sender, OnNewSubscriberArgs e) => { ThreadDispatcher.Enqueue(() => OnNewSubscriber?.Invoke(sender, e)); });
            base.OnReSubscriber           += ((object sender, OnReSubscriberArgs e) => { ThreadDispatcher.Enqueue(() => OnReSubscriber?.Invoke(sender, e)); });
            base.OnHostLeft += ((object sender, EventArgs arg) => { ThreadDispatcher.Enqueue(() => OnHostLeft?.Invoke(sender, arg)); });
            base.OnExistingUsersDetected += ((object sender, OnExistingUsersDetectedArgs e) => { ThreadDispatcher.Enqueue(() => OnExistingUsersDetected?.Invoke(sender, e)); });
            base.OnUserLeft                         += ((object sender, OnUserLeftArgs e) => { ThreadDispatcher.Enqueue(() => OnUserLeft?.Invoke(sender, e)); });
            base.OnHostingStarted                   += ((object sender, OnHostingStartedArgs e) => { ThreadDispatcher.Enqueue(() => OnHostingStarted?.Invoke(sender, e)); });
            base.OnHostingStopped                   += ((object sender, OnHostingStoppedArgs e) => { ThreadDispatcher.Enqueue(() => OnHostingStopped?.Invoke(sender, e)); });
            base.OnDisconnected                     += ((object sender, OnDisconnectedEventArgs e) => { ThreadDispatcher.Enqueue(() => OnDisconnected?.Invoke(sender, e)); });
            base.OnConnectionError                  += ((object sender, OnConnectionErrorArgs e) => { ThreadDispatcher.Enqueue(() => OnConnectionError?.Invoke(sender, e)); });
            base.OnChatCleared                      += ((object sender, OnChatClearedArgs e) => { ThreadDispatcher.Enqueue(() => OnChatCleared?.Invoke(sender, e)); });
            base.OnUserTimedout                     += ((object sender, OnUserTimedoutArgs e) => { ThreadDispatcher.Enqueue(() => OnUserTimedout?.Invoke(sender, e)); });
            base.OnLeftChannel                      += ((object sender, OnLeftChannelArgs e) => { ThreadDispatcher.Enqueue(() => OnLeftChannel?.Invoke(sender, e)); });
            base.OnUserBanned                       += ((object sender, OnUserBannedArgs e) => { ThreadDispatcher.Enqueue(() => OnUserBanned?.Invoke(sender, e)); });
            base.OnModeratorsReceived               += ((object sender, OnModeratorsReceivedArgs e) => { ThreadDispatcher.Enqueue(() => OnModeratorsReceived?.Invoke(sender, e)); });
            base.OnChatColorChanged                 += ((object sender, OnChatColorChangedArgs e) => { ThreadDispatcher.Enqueue(() => OnChatColorChanged?.Invoke(sender, e)); });
            base.OnSendReceiveData                  += ((object sender, OnSendReceiveDataArgs e) => { ThreadDispatcher.Enqueue(() => OnSendReceiveData?.Invoke(sender, e)); });
            base.OnNowHosting                       += ((object sender, OnNowHostingArgs e) => { ThreadDispatcher.Enqueue(() => OnNowHosting?.Invoke(sender, e)); });
            base.OnBeingHosted                      += ((object sender, OnBeingHostedArgs e) => { ThreadDispatcher.Enqueue(() => OnBeingHosted?.Invoke(sender, e)); });
            base.OnRaidNotification                 += ((object sender, OnRaidNotificationArgs e) => { ThreadDispatcher.Enqueue(() => OnRaidNotification?.Invoke(sender, e)); });
            base.OnGiftedSubscription               += ((object sender, OnGiftedSubscriptionArgs e) => { ThreadDispatcher.Enqueue(() => OnGiftedSubscription?.Invoke(sender, e)); });
            base.OnRaidedChannelIsMatureAudience    += ((object sender, EventArgs arg) => { ThreadDispatcher.Enqueue(() => OnRaidedChannelIsMatureAudience?.Invoke(sender, arg)); });
            base.OnRitualNewChatter                 += ((object sender, OnRitualNewChatterArgs e) => { ThreadDispatcher.Enqueue(() => OnRitualNewChatter?.Invoke(sender, e)); });
            base.OnFailureToReceiveJoinConfirmation += ((object sender, OnFailureToReceiveJoinConfirmationArgs e) => { ThreadDispatcher.Enqueue(() => OnFailureToReceiveJoinConfirmation?.Invoke(sender, e)); });
            base.OnUnaccountedFor                   += ((object sender, OnUnaccountedForArgs e) => { ThreadDispatcher.Enqueue(() => OnUnaccountedFor?.Invoke(sender, e)); });
            base.OnSelfRaidError                    += ((object sender, EventArgs e) => { ThreadDispatcher.Enqueue(() => OnSelfRaidError?.Invoke(sender, e)); });
            base.OnNoPermissionError                += ((object sender, EventArgs e) => { ThreadDispatcher.Enqueue(() => OnNoPermissionError?.Invoke(sender, e)); });
            base.OnMessageCleared                   += ((object sender, OnMessageClearedArgs e) => { ThreadDispatcher.Enqueue(() => OnMessageCleared?.Invoke(sender, e)); });
            base.OnReconnected                      += ((object sender, OnReconnectedEventArgs e) => { ThreadDispatcher.Enqueue(() => OnReconnected?.Invoke(sender, e)); });
            base.OnWhisperThrottled                 += ((object sender, OnWhisperThrottledEventArgs e) => { ThreadDispatcher.Enqueue(() => OnWhisperThrottled?.Invoke(sender, e)); });
            base.OnMessageThrottled                 += ((object sender, OnMessageThrottledEventArgs e) => { ThreadDispatcher.Enqueue(() => OnMessageThrottled?.Invoke(sender, e)); });
            base.OnCommunitySubscription            += ((object sender, OnCommunitySubscriptionArgs e) => { ThreadDispatcher.Enqueue(() => OnCommunitySubscription?.Invoke(sender, e)); });
            base.OnError        += ((object sender, OnErrorEventArgs e) => { ThreadDispatcher.Enqueue(() => OnError?.Invoke(sender, e)); });
            base.OnVIPsReceived += ((object sender, OnVIPsReceivedArgs e) => { ThreadDispatcher.Enqueue(() => OnVIPsReceived?.Invoke(sender, e)); });
        }
Exemple #7
0
        private void ParseIrcMessage(string ircMessage)
        {
            #region Chat Parsing
            DetectionReturn response;

            // On Connected
            if (Internal.Parsing.Chat.detectConnected(ircMessage))
            {
                OnConnected?.Invoke(this, new OnConnectedArgs {
                    AutoJoinChannel = _autoJoinChannel != null ? _autoJoinChannel : "", Username = TwitchUsername
                });
                return;
            }

            // On New Subscriber
            response = Internal.Parsing.Chat.detectNewSubscriber(ircMessage, JoinedChannels);
            if (response.Successful)
            {
                OnNewSubscriber?.Invoke(this, new OnNewSubscriberArgs {
                    Subscriber = new Models.Client.Subscriber(ircMessage), Channel = response.Channel
                });
                return;
            }

            // On Message Received
            response = Internal.Parsing.Chat.detectMessageReceived(ircMessage, JoinedChannels);
            bool foundMessage = false;
            if (response.Successful)
            {
                foundMessage = true;
                var chatMessage = new ChatMessage(TwitchUsername, ircMessage, ref _channelEmotes, WillReplaceEmotes);
                foreach (var joinedChannel in JoinedChannels.Where(x => x.Channel.ToLower() == response.Channel.ToLower()))
                {
                    joinedChannel.HandleMessage(chatMessage);
                }
                OnMessageReceived?.Invoke(this, new OnMessageReceivedArgs {
                    ChatMessage = chatMessage
                });
                // purposely drop through without return
            }

            // On Command Received (PURPOSELY DROP THROUGH WITHOUT RETURN)
            response = Internal.Parsing.Chat.detectCommandReceived(TwitchUsername, ircMessage, JoinedChannels, ChannelEmotes, WillReplaceEmotes, _chatCommandIdentifiers);
            if (response.Successful)
            {
                var chatMessage = new ChatMessage(TwitchUsername, ircMessage, ref _channelEmotes, WillReplaceEmotes);
                OnChatCommandReceived?.Invoke(this, new OnChatCommandReceivedArgs {
                    Command = new ChatCommand(ircMessage, chatMessage)
                });
                return;
            }
            // We don't want to continue checking if we already found a chat message
            else if (foundMessage)
            {
                return;
            }

            // On Viewer Joined
            response = Internal.Parsing.Chat.detectUserJoined(ircMessage, JoinedChannels);
            if (response.Successful)
            {
                if (TwitchUsername.ToLower() == ircMessage.Split('!')[1].Split('@')[0].ToLower())
                {
                    OnJoinedChannel?.Invoke(this, new OnJoinedChannelArgs {
                        Channel = response.Channel, Username = ircMessage.Split('!')[1].Split('@')[0]
                    });
                    if (OnBeingHosted != null)
                    {
                        if (response.Channel.ToLower() != TwitchUsername && !OverrideBeingHostedCheck)
                        {
                            throw new BadListenException("BeingHosted", "You cannot listen to OnBeingHosted unless you are connected to the broadcaster's channel as the broadcaster. You may override this by setting the TwitchClient property OverrideBeingHostedCheck to true.");
                        }
                    }
                }
                else
                {
                    OnUserJoined?.Invoke(this, new OnUserJoinedArgs {
                        Username = ircMessage.Split('!')[1].Split('@')[0], Channel = response.Channel
                    });
                }
                return;
            }

            // On Viewer Left
            response = Internal.Parsing.Chat.detectedUserLeft(ircMessage, JoinedChannels);
            if (response.Successful)
            {
                string username = ircMessage.Split(':')[1].Split('!')[0];
                if (username.ToLower() == TwitchUsername)
                {
                    JoinedChannels.Remove(JoinedChannels.FirstOrDefault(x => x.Channel.ToLower() == response.Channel));
                    _hasSeenJoinedChannels.Remove(response.Channel.ToLower());
                    OnLeftChannel?.Invoke(this, new OnLeftChannelArgs {
                        BotUsername = username, Channel = response.Channel
                    });
                }
                else
                {
                    OnUserLeft?.Invoke(this, new OnUserLeftArgs {
                        Username = username, Channel = response.Channel
                    });
                }
                return;
            }

            // On Moderator Joined
            response = Internal.Parsing.Chat.detectedModeratorJoined(ircMessage, JoinedChannels);
            if (response.Successful)
            {
                OnModeratorJoined?.Invoke(this, new OnModeratorJoinedArgs {
                    Username = ircMessage.Split(' ')[4], Channel = response.Channel
                });
                return;
            }

            // On Moderator Left
            response = Internal.Parsing.Chat.detectedModeatorLeft(ircMessage, JoinedChannels);
            if (response.Successful)
            {
                OnModeratorLeft?.Invoke(this, new OnModeratorLeftArgs {
                    Username = ircMessage.Split(' ')[4], Channel = response.Channel
                });
                return;
            }

            // On Incorrect login
            response = Internal.Parsing.Chat.detectedIncorrectLogin(ircMessage);
            if (response.Successful)
            {
                Disconnect();
                OnIncorrectLogin?.Invoke(this, new OnIncorrectLoginArgs {
                    Exception = new ErrorLoggingInException(ircMessage, _credentials.TwitchUsername)
                });
                return;
            }

            // On Malformed OAuth
            response = Internal.Parsing.Chat.detectedMalformedOAuth(ircMessage, JoinedChannels);
            if (response.Successful)
            {
                Disconnect();
                OnIncorrectLogin?.Invoke(this, new OnIncorrectLoginArgs {
                    Exception = new ErrorLoggingInException("Invalid OAuth key. Remember to add 'oauth:' as a prefix. Example: oauth:19nds9sbnga9asd", _credentials.TwitchUsername)
                });
                return;
            }

            // On Host Left
            response = Internal.Parsing.Chat.detectedHostLeft(ircMessage, JoinedChannels);
            if (response.Successful)
            {
                OnHostLeft?.Invoke(this, null);
                return;
            }

            // On Channel State Changed
            response = Internal.Parsing.Chat.detectedChannelStateChanged(ircMessage, JoinedChannels);
            if (response.Successful)
            {
                OnChannelStateChanged?.Invoke(this, new OnChannelStateChangedArgs {
                    ChannelState = new ChannelState(ircMessage), Channel = response.Channel
                });
                return;
            }

            // On User State Changed
            response = Internal.Parsing.Chat.detectedUserStateChanged(ircMessage, JoinedChannels);
            if (response.Successful)
            {
                var userState = new UserState(ircMessage);
                if (!_hasSeenJoinedChannels.Contains(userState.Channel.ToLower()))
                {
                    // UserState fired from joining channel
                    _hasSeenJoinedChannels.Add(userState.Channel.ToLower());
                    OnUserStateChanged?.Invoke(this, new OnUserStateChangedArgs {
                        UserState = userState
                    });
                }
                else
                {
                    // UserState fired from sending a message
                    OnMessageSent?.Invoke(this, new OnMessageSentArgs {
                        SentMessage = new SentMessage(userState, _lastMessageSent)
                    });
                }
                return;
            }

            // On ReSubscriber
            response = Internal.Parsing.Chat.detectedReSubscriber(ircMessage, JoinedChannels);
            if (response.Successful)
            {
                var resub = new Models.Client.Subscriber(ircMessage);
                OnReSubscriber?.Invoke(this, new OnReSubscriberArgs {
                    ReSubscriber = resub
                });
                return;
            }

            // On PING received
            response = Internal.Parsing.Chat.detectedPing(ircMessage);
            if (response.Successful && !DisableAutoPong)
            {
                SendRaw("PONG");
                return;
            }

            // On PONG received (don't do anything)
            response = Internal.Parsing.Chat.detectedPong(ircMessage);
            if (response.Successful)
            {
                return;
            }

            // On Hosting Stopped
            if (Internal.Parsing.Chat.detectedHostingStopped(ircMessage))
            {
                int viewers;
                int.TryParse(ircMessage.Split(' ')[4], out viewers);
                OnHostingStopped?.Invoke(this, new OnHostingStoppedArgs()
                {
                    Viewers = viewers, HostingChannel = ircMessage.Split(' ')[2].Remove(0, 1)
                });
                return;
            }

            // On Hosting Started
            if (Internal.Parsing.Chat.detectedHostingStarted(ircMessage))
            {
                int viewers;
                int.TryParse(ircMessage.Split(' ')[4], out viewers);
                OnHostingStarted?.Invoke(this, new OnHostingStartedArgs()
                {
                    Viewers = viewers, HostingChannel = ircMessage.Split(' ')[2].Remove(0, 1), TargetChannel = ircMessage.Split(' ')[3].Remove(0, 1)
                });
                return;
            }

            // On Existing Users Detected
            response = Internal.Parsing.Chat.detectedExistingUsers(ircMessage, _credentials.TwitchUsername, JoinedChannels);
            if (response.Successful)
            {
                OnExistingUsersDetected?.Invoke(this, new OnExistingUsersDetectedArgs {
                    Channel = response.Channel,
                    Users   = ircMessage.Replace($":{_credentials.TwitchUsername}.tmi.twitch.tv 353 {_credentials.TwitchUsername} = #{response.Channel} :", "").Split(' ').ToList <string>()
                });
                return;
            }

            // On Now Hosting
            response = Internal.Parsing.Chat.detectedNowHosting(ircMessage, JoinedChannels);
            if (response.Successful)
            {
                OnNowHosting?.Invoke(this, new OnNowHostingArgs {
                    Channel       = response.Channel,
                    HostedChannel = ircMessage.Split(' ')[6].Replace(".", "")
                });
                return;
            }

            // On channel join completed with all existing names
            response = Internal.Parsing.Chat.detectedJoinChannelCompleted(ircMessage);
            if (response.Successful)
            {
                currentlyJoiningChannels = false;
                queueingJoinCheck();
                return;
            }

            // On another channel hosts this broadcaster's channel
            response = Internal.Parsing.Chat.detectedBeingHosted(ircMessage, JoinedChannels);
            if (response.Successful)
            {
                var hostedBy = ircMessage.Split(':')[2].Split(' ')[0];
                var viewers  = ((ircMessage.Contains("hosting you for") && ircMessage.Split(' ').Count() >= 9) ? int.Parse(ircMessage.Split(' ')[8]) : -1);
                var isAuto   = ircMessage.Contains("now autohosting");
                OnBeingHosted?.Invoke(this, new OnBeingHostedArgs {
                    Channel = response.Channel, BotUsername = TwitchUsername, HostedByChannel = hostedBy,
                    Viewers = viewers, IsAutoHosted = isAuto
                });
                return;
            }
            #endregion

            #region Clear Chat, Timeouts, and Bans
            // On clear chat detected
            response = Internal.Parsing.Chat.detectedClearedChat(ircMessage, JoinedChannels);
            if (response.Successful)
            {
                OnChatCleared?.Invoke(this, new OnChatClearedArgs {
                    Channel = response.Channel
                });
                return;
            }

            // On timeout detected
            response = Internal.Parsing.Chat.detectedUserTimedout(ircMessage, JoinedChannels);
            if (response.Successful)
            {
                OnUserTimedout?.Invoke(this, new OnUserTimedoutArgs
                {
                    Channel         = response.Channel,
                    TimeoutDuration = int.Parse(ircMessage.Split(';')[0].Split('=')[1]),
                    TimeoutReason   = ircMessage.Split(' ')[0].Split('=')[2].Replace("\\s", " "),
                    Username        = ircMessage.Split(':')[2]
                });
                return;
            }

            // On ban detected
            response = Internal.Parsing.Chat.detectedUserBanned(ircMessage, JoinedChannels);
            if (response.Successful)
            {
                OnUserBanned?.Invoke(this, new OnUserBannedArgs
                {
                    Channel   = response.Channel,
                    BanReason = ircMessage.Split(' ')[0].Split('=')[1].Replace("\\s", " "),
                    Username  = ircMessage.Split(':')[2]
                });
                return;
            }

            // On moderators received detected
            response = Internal.Parsing.Chat.detectedModeratorsReceived(ircMessage, JoinedChannels);
            if (response.Successful)
            {
                OnModeratorsReceived?.Invoke(this, new OnModeratorsReceivedArgs
                {
                    Channel    = ircMessage.Split('#')[1].Split(' ')[0],
                    Moderators = ircMessage.Replace(" ", "").Split(':')[3].Split(',').ToList <string>()
                });
                return;
            }
            #endregion

            #region Others
            // On chat color changed detected
            response = Internal.Parsing.Chat.detectedChatColorChanged(ircMessage, JoinedChannels);
            if (response.Successful)
            {
                OnChatColorChanged?.Invoke(this, new OnChatColorChangedArgs
                {
                    Channel = ircMessage.Split('#')[1].Split(' ')[0]
                });
                return;
            }
            #endregion

            #region Whisper Parsing
            if (ircMessage.Split(' ').Count() > 2 && (ircMessage.Split(' ')[1] == "WHISPER" || ircMessage.Split(' ')[2] == "WHISPER"))
            {
                // On Whisper Message Received
                WhisperMessage receivedMessage = null;
                if (Internal.Parsing.Whisper.detectedWhisperReceived(ircMessage, _credentials.TwitchUsername))
                {
                    receivedMessage = new WhisperMessage(ircMessage, _credentials.TwitchUsername);
                    PreviousWhisper = receivedMessage;
                    OnWhisperReceived?.Invoke(this, new OnWhisperReceivedArgs {
                        WhisperMessage = receivedMessage
                    });
                    // Fall through to detect command as well
                }

                // On Whisper Command Received
                if (Internal.Parsing.Whisper.detectedWhisperCommandReceived(ircMessage, _credentials.TwitchUsername, _whisperCommandIdentifiers))
                {
                    var    whisperMessage    = new WhisperMessage(ircMessage, _credentials.TwitchUsername);
                    string command           = whisperMessage.Message.Split(' ')?[0].Substring(1, whisperMessage.Message.Split(' ')[0].Length - 1) ?? whisperMessage.Message.Substring(1, whisperMessage.Message.Length - 1);
                    var    argumentsAsList   = whisperMessage.Message.Split(' ')?.Where(arg => arg != whisperMessage.Message[0] + command).ToList <string>() ?? new List <string>();
                    string argumentsAsString = whisperMessage.Message.Replace(whisperMessage.Message.Split(' ')?[0] +" ", "") ?? "";
                    OnWhisperCommandReceived?.Invoke(this, new OnWhisperCommandReceivedArgs {
                        Command = command, WhisperMessage = whisperMessage, ArgumentsAsList = argumentsAsList, ArgumentsAsString = argumentsAsString
                    });
                    return;
                }

                // Return if whisper message was parsed successfully
                if (receivedMessage != null)
                {
                    return;
                }
            }
            #endregion

            // Any other messages here
            log($"Unaccounted for: {ircMessage}");
        }
        private void SocketDataReceived(object sender, WebSocketSharp.MessageEventArgs result)
        {
            GatewayResponse payload = result.Data.Deserialize <GatewayResponse>();

            Sequence = payload.Sequence;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                this.StartHeartbeatHandlersAsync(payload.Deserialize <JObject>().GetValue("heartbeat_interval").ToObject <uint>());
                break;
            }
        }
Exemple #9
0
 private void PublishUserBannedEvent(UserBannedEvent e) => OnUserBanned?.Invoke(e);
Exemple #10
0
 private void NewConnection_OnUserBanned(object sender, UserBannedEvent e)
 {
     logger.LogInformation("Received Ban on {arg}, issued by {arg2} in channel {arg3}", e.Username, e.BannedBy, e.Channel);
     OnUserBanned?.Invoke(this, e);
 }
Exemple #11
0
 public TwitchClientUnity(ILogger <TwitchClientUnity> logger) : base(logger)
 {
     CoroutineHost.PrepareCrossThread();
     // client = new TwitchClient(credentials, channel, chatCommandIdentifier,whisperCommandIdentifier,logging,logger,autoReListenOnExceptions);
     base.OnLog                              += ((object sender, OnLogArgs e) => { CoroutineHost.Host(() => OnLog?.Invoke(sender, e)); });
     base.OnConnected                        += ((object sender, OnConnectedArgs e) => { CoroutineHost.Host(() => OnConnected?.Invoke(sender, e)); });
     base.OnJoinedChannel                    += ((object sender, OnJoinedChannelArgs e) => { CoroutineHost.Host(() => OnJoinedChannel?.Invoke(sender, e)); });
     base.OnIncorrectLogin                   += ((object sender, OnIncorrectLoginArgs e) => { CoroutineHost.Host(() => OnIncorrectLogin?.Invoke(sender, e)); });
     base.OnChannelStateChanged              += ((object sender, OnChannelStateChangedArgs e) => { CoroutineHost.Host(() => OnChannelStateChanged?.Invoke(sender, e)); });
     base.OnUserStateChanged                 += ((object sender, OnUserStateChangedArgs e) => { CoroutineHost.Host(() => OnUserStateChanged?.Invoke(sender, e)); });
     base.OnMessageReceived                  += ((object sender, OnMessageReceivedArgs e) => { CoroutineHost.Host(() => OnMessageReceived?.Invoke(sender, e)); });
     base.OnWhisperReceived                  += ((object sender, OnWhisperReceivedArgs e) => { CoroutineHost.Host(() => OnWhisperReceived?.Invoke(sender, e)); });
     base.OnMessageSent                      += ((object sender, OnMessageSentArgs e) => { CoroutineHost.Host(() => OnMessageSent?.Invoke(sender, e)); });
     base.OnWhisperSent                      += ((object sender, OnWhisperSentArgs e) => { CoroutineHost.Host(() => OnWhisperSent?.Invoke(sender, e)); });
     base.OnChatCommandReceived              += ((object sender, OnChatCommandReceivedArgs e) => { CoroutineHost.Host(() => OnChatCommandReceived?.Invoke(sender, e)); });
     base.OnWhisperCommandReceived           += ((object sender, OnWhisperCommandReceivedArgs e) => { CoroutineHost.Host(() => OnWhisperCommandReceived?.Invoke(sender, e)); });
     base.OnUserJoined                       += ((object sender, OnUserJoinedArgs e) => { CoroutineHost.Host(() => OnUserJoined?.Invoke(sender, e)); });
     base.OnModeratorJoined                  += ((object sender, OnModeratorJoinedArgs e) => { CoroutineHost.Host(() => OnModeratorJoined?.Invoke(sender, e)); });
     base.OnModeratorLeft                    += ((object sender, OnModeratorLeftArgs e) => { CoroutineHost.Host(() => OnModeratorLeft?.Invoke(sender, e)); });
     base.OnNewSubscriber                    += ((object sender, OnNewSubscriberArgs e) => { CoroutineHost.Host(() => OnNewSubscriber?.Invoke(sender, e)); });
     base.OnReSubscriber                     += ((object sender, OnReSubscriberArgs e) => { CoroutineHost.Host(() => OnReSubscriber?.Invoke(sender, e)); });
     base.OnHostLeft                         += ((object sender, EventArgs arg) => { CoroutineHost.Host(() => OnHostLeft(sender, arg)); });
     base.OnExistingUsersDetected            += ((object sender, OnExistingUsersDetectedArgs e) => { CoroutineHost.Host(() => OnExistingUsersDetected?.Invoke(sender, e)); });
     base.OnUserLeft                         += ((object sender, OnUserLeftArgs e) => { CoroutineHost.Host(() => OnUserLeft?.Invoke(sender, e)); });
     base.OnHostingStarted                   += ((object sender, OnHostingStartedArgs e) => { CoroutineHost.Host(() => OnHostingStarted?.Invoke(sender, e)); });
     base.OnHostingStopped                   += ((object sender, OnHostingStoppedArgs e) => { CoroutineHost.Host(() => OnHostingStopped?.Invoke(sender, e)); });
     base.OnDisconnected                     += ((object sender, OnDisconnectedArgs e) => { CoroutineHost.Host(() => OnDisconnected?.Invoke(sender, e)); });
     base.OnConnectionError                  += ((object sender, OnConnectionErrorArgs e) => { CoroutineHost.Host(() => OnConnectionError?.Invoke(sender, e)); });
     base.OnChatCleared                      += ((object sender, OnChatClearedArgs e) => { CoroutineHost.Host(() => OnChatCleared?.Invoke(sender, e)); });
     base.OnUserTimedout                     += ((object sender, OnUserTimedoutArgs e) => { CoroutineHost.Host(() => OnUserTimedout?.Invoke(sender, e)); });
     base.OnLeftChannel                      += ((object sender, OnLeftChannelArgs e) => { CoroutineHost.Host(() => OnLeftChannel?.Invoke(sender, e)); });
     base.OnUserBanned                       += ((object sender, OnUserBannedArgs e) => { CoroutineHost.Host(() => OnUserBanned?.Invoke(sender, e)); });
     base.OnModeratorsReceived               += ((object sender, OnModeratorsReceivedArgs e) => { CoroutineHost.Host(() => OnModeratorsReceived?.Invoke(sender, e)); });
     base.OnChatColorChanged                 += ((object sender, OnChatColorChangedArgs e) => { CoroutineHost.Host(() => OnChatColorChanged?.Invoke(sender, e)); });
     base.OnSendReceiveData                  += ((object sender, OnSendReceiveDataArgs e) => { CoroutineHost.Host(() => OnSendReceiveData?.Invoke(sender, e)); });
     base.OnNowHosting                       += ((object sender, OnNowHostingArgs e) => { CoroutineHost.Host(() => OnNowHosting?.Invoke(sender, e)); });
     base.OnBeingHosted                      += ((object sender, OnBeingHostedArgs e) => { CoroutineHost.Host(() => OnBeingHosted?.Invoke(sender, e)); });
     base.OnRaidNotification                 += ((object sender, OnRaidNotificationArgs e) => { CoroutineHost.Host(() => OnRaidNotification?.Invoke(sender, e)); });
     base.OnGiftedSubscription               += ((object sender, OnGiftedSubscriptionArgs e) => { CoroutineHost.Host(() => OnGiftedSubscription?.Invoke(sender, e)); });
     base.OnRaidedChannelIsMatureAudience    += ((object sender, EventArgs arg) => { CoroutineHost.Host(() => OnRaidedChannelIsMatureAudience(sender, arg)); });
     base.OnRitualNewChatter                 += ((object sender, OnRitualNewChatterArgs e) => { CoroutineHost.Host(() => OnRitualNewChatter?.Invoke(sender, e)); });
     base.OnFailureToReceiveJoinConfirmation += ((object sender, OnFailureToReceiveJoinConfirmationArgs e) => { CoroutineHost.Host(() => OnFailureToReceiveJoinConfirmation?.Invoke(sender, e)); });
     base.OnUnaccountedFor                   += ((object sender, OnUnaccountedForArgs e) => { CoroutineHost.Host(() => OnUnaccountedFor?.Invoke(sender, e)); });
 }
        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;
                }
            });
        }
Exemple #13
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;
            }
        }
Exemple #14
0
        private void ParseIrcMessage(string ircMessage)
        {
            // Hack to accomodate at least cyrillic characters, possibly more
            string decodedMessage = Encoding.UTF8.GetString(Encoding.Default.GetBytes(ircMessage));

            #region Chat Parsing
            DetectionReturn response;

            // On Connected
            if (ChatParsing.detectConnected(decodedMessage))
            {
                IsConnected = true;
                OnConnected?.Invoke(this, new OnConnectedArgs {
                    AutoJoinChannel = "", Username = TwitchUsername
                });
                return;
            }

            // On New Subscriber
            response = ChatParsing.detectNewSubscriber(decodedMessage, JoinedChannels);
            if (response.Successful)
            {
                OnNewSubscriber?.Invoke(this, new OnNewSubscriberArgs {
                    Subscriber = new NewSubscriber(decodedMessage), Channel = response.Channel
                });
                return;
            }

            // On Command Received (PURPOSELY DROP THROUGH WITHOUT RETURN)
            response = ChatParsing.detectCommandReceived(TwitchUsername, decodedMessage, JoinedChannels, ChannelEmotes, WillReplaceEmotes, _chatCommandIdentifiers);
            if (response.Successful)
            {
                var chatMessage = new ChatMessage(TwitchUsername, decodedMessage, ref _channelEmotes, WillReplaceEmotes);
                OnChatCommandReceived?.Invoke(this, new OnChatCommandReceivedArgs {
                    Command = new ChatCommand(decodedMessage, chatMessage)
                });
                // purposely drop through without return
            }

            // On Message Received
            response = ChatParsing.detectMessageReceived(decodedMessage, JoinedChannels);
            if (response.Successful)
            {
                var chatMessage = new ChatMessage(TwitchUsername, decodedMessage, ref _channelEmotes, WillReplaceEmotes);
                foreach (var joinedChannel in JoinedChannels.Where(x => x.Channel.ToLower() == response.Channel.ToLower()))
                {
                    joinedChannel.HandleMessage(chatMessage);
                }
                OnMessageReceived?.Invoke(this, new OnMessageReceivedArgs {
                    ChatMessage = chatMessage
                });
                return;
            }

            // On Viewer Joined
            response = ChatParsing.detectUserJoined(decodedMessage, JoinedChannels);
            if (response.Successful)
            {
                if (TwitchUsername.ToLower() == decodedMessage.Split('!')[1].Split('@')[0].ToLower())
                {
                    OnJoinedChannel?.Invoke(this, new OnJoinedChannelArgs {
                        Channel = response.Channel, Username = decodedMessage.Split('!')[1].Split('@')[0]
                    });
                }
                else
                {
                    OnUserJoined?.Invoke(this, new OnUserJoinedArgs {
                        Username = decodedMessage.Split('!')[1].Split('@')[0], Channel = response.Channel
                    });
                }
                return;
            }

            // On Viewer Left
            response = ChatParsing.detectedUserLeft(decodedMessage, JoinedChannels);
            if (response.Successful)
            {
                string username = decodedMessage.Split(':')[1].Split('!')[0];
                if (username.ToLower() == TwitchUsername)
                {
                    JoinedChannels.Remove(JoinedChannels.FirstOrDefault(x => x.Channel.ToLower() == response.Channel));
                    _hasSeenJoinedChannels.Remove(response.Channel.ToLower());
                    OnClientLeftChannel?.Invoke(this, new OnClientLeftChannelArgs {
                        BotUsername = username, Channel = response.Channel
                    });
                }
                else
                {
                    OnUserLeft?.Invoke(this, new OnUserLeftArgs {
                        Username = username, Channel = response.Channel
                    });
                }
                return;
            }

            // On Moderator Joined
            response = ChatParsing.detectedModeratorJoined(decodedMessage, JoinedChannels);
            if (response.Successful)
            {
                OnModeratorJoined?.Invoke(this, new OnModeratorJoinedArgs {
                    Username = decodedMessage.Split(' ')[4], Channel = response.Channel
                });
                return;
            }

            // On Moderator Left
            response = ChatParsing.detectedModeatorLeft(decodedMessage, JoinedChannels);
            if (response.Successful)
            {
                OnModeratorLeft?.Invoke(this, new OnModeratorLeftArgs {
                    Username = decodedMessage.Split(' ')[4], Channel = response.Channel
                });
                return;
            }

            // On Incorrect login
            response = ChatParsing.detectedIncorrectLogin(decodedMessage);
            if (response.Successful)
            {
                Disconnect();
                OnIncorrectLogin?.Invoke(this, new OnIncorrectLoginArgs {
                    Exception = new ErrorLoggingInException(decodedMessage, _credentials.TwitchUsername)
                });
                return;
            }

            // On Malformed OAuth
            response = ChatParsing.detectedMalformedOAuth(decodedMessage, JoinedChannels);
            if (response.Successful)
            {
                Disconnect();
                OnIncorrectLogin?.Invoke(this, new OnIncorrectLoginArgs {
                    Exception = new ErrorLoggingInException("Invalid OAuth key. Remember to add 'oauth:' as a prefix. Example: oauth:19nds9sbnga9asd", _credentials.TwitchUsername)
                });
                return;
            }

            // On Host Left
            response = ChatParsing.detectedHostLeft(decodedMessage, JoinedChannels);
            if (response.Successful)
            {
                OnHostLeft?.Invoke(this, null);
                return;
            }

            // On Channel State Changed
            response = ChatParsing.detectedChannelStateChanged(decodedMessage, JoinedChannels);
            if (response.Successful)
            {
                OnChannelStateChanged?.Invoke(this, new OnChannelStateChangedArgs {
                    ChannelState = new ChannelState(decodedMessage), Channel = response.Channel
                });
                return;
            }

            // On User State Changed
            response = ChatParsing.detectedUserStateChanged(decodedMessage, JoinedChannels);
            if (response.Successful)
            {
                var userState = new UserState(decodedMessage);
                if (!_hasSeenJoinedChannels.Contains(userState.Channel.ToLower()))
                {
                    // UserState fired from joining channel
                    _hasSeenJoinedChannels.Add(userState.Channel.ToLower());
                    OnUserStateChanged?.Invoke(this, new OnUserStateChangedArgs {
                        UserState = userState
                    });
                }
                else
                {
                    // UserState fired from sending a message
                    OnMessageSent?.Invoke(this, new OnMessageSentArgs {
                        SentMessage = new SentMessage(userState, _lastMessageSent)
                    });
                }
                return;
            }

            // On ReSubscriber
            response = ChatParsing.detectedReSubscriber(decodedMessage, JoinedChannels);
            if (response.Successful)
            {
                var resub = new ReSubscriber(decodedMessage);
                OnReSubscriber?.Invoke(this, new OnReSubscriberArgs {
                    ReSubscriber = resub
                });
                return;
            }

            // On PING received
            response = ChatParsing.detectedPing(decodedMessage);
            if (response.Successful && !DisableAutoPong)
            {
                SendRaw("PONG");
                return;
            }

            // On PONG received (don't do anything)
            response = ChatParsing.detectedPong(decodedMessage);
            if (response.Successful)
            {
                return;
            }

            // On Hosting Stopped
            if (ChatParsing.detectedHostingStopped(decodedMessage))
            {
                int viewers;
                int.TryParse(decodedMessage.Split(' ')[4], out viewers);
                OnHostingStopped?.Invoke(this, new OnHostingStoppedArgs()
                {
                    Viewers = viewers, HostingChannel = decodedMessage.Split(' ')[2].Remove(0, 1)
                });
                return;
            }

            // On Hosting Started
            if (ChatParsing.detectedHostingStarted(decodedMessage))
            {
                int viewers;
                int.TryParse(decodedMessage.Split(' ')[4], out viewers);
                OnHostingStarted?.Invoke(this, new OnHostingStartedArgs()
                {
                    Viewers = viewers, HostingChannel = decodedMessage.Split(' ')[2].Remove(0, 1), TargetChannel = decodedMessage.Split(' ')[3].Remove(0, 1)
                });
                return;
            }

            // On Existing Users Detected
            response = ChatParsing.detectedExistingUsers(decodedMessage, _credentials.TwitchUsername, JoinedChannels);
            if (response.Successful)
            {
                OnExistingUsersDetected?.Invoke(this, new OnExistingUsersDetectedArgs {
                    Channel = response.Channel,
                    Users   = decodedMessage.Replace($":{_credentials.TwitchUsername}.tmi.twitch.tv 353 {_credentials.TwitchUsername} = #{response.Channel} :", "").Split(' ').ToList <string>()
                });
                return;
            }

            // On Now Hosting
            response = ChatParsing.detectedNowHosting(decodedMessage, JoinedChannels);
            if (response.Successful)
            {
                OnNowHosting?.Invoke(this, new OnNowHostingArgs {
                    Channel       = response.Channel,
                    HostedChannel = decodedMessage.Split(' ')[6].Replace(".", "")
                });
                return;
            }

            // On channel join completed with all existing names
            response = ChatParsing.detectedJoinChannelCompleted(decodedMessage);
            if (response.Successful)
            {
                currentlyJoiningChannels = false;
                queueingJoinCheck();
            }
            #endregion

            #region Clear Chat, Timeouts, and Bans
            // On clear chat detected
            response = ChatParsing.detectedClearedChat(decodedMessage, JoinedChannels);
            if (response.Successful)
            {
                OnChatCleared?.Invoke(this, new OnChatClearedArgs {
                    Channel = response.Channel
                });
                return;
            }

            // On timeout detected
            response = ChatParsing.detectedUserTimedout(decodedMessage, JoinedChannels);
            if (response.Successful)
            {
                OnUserTimedout?.Invoke(this, new OnUserTimedoutArgs
                {
                    Channel         = response.Channel,
                    TimeoutDuration = int.Parse(decodedMessage.Split(';')[0].Split('=')[1]),
                    TimeoutReason   = decodedMessage.Split(' ')[0].Split('=')[2].Replace("\\s", " "),
                    Username        = decodedMessage.Split(':')[2]
                });
                return;
            }

            // On ban detected
            response = ChatParsing.detectedUserBanned(decodedMessage, JoinedChannels);
            if (response.Successful)
            {
                OnUserBanned?.Invoke(this, new OnUserBannedArgs
                {
                    Channel   = response.Channel,
                    BanReason = decodedMessage.Split(' ')[0].Split('=')[1].Replace("\\s", " "),
                    Username  = decodedMessage.Split(':')[2]
                });
                return;
            }

            // On moderators received detected
            response = ChatParsing.detectedModeratorsReceived(decodedMessage, JoinedChannels);
            if (response.Successful)
            {
                OnModeratorsReceived?.Invoke(this, new OnModeratorsReceivedArgs
                {
                    Channel    = decodedMessage.Split('#')[1].Split(' ')[0],
                    Moderators = decodedMessage.Replace(" ", "").Split(':')[3].Split(',').ToList <string>()
                });
                return;
            }
            #endregion

            #region Others
            // On chat color changed detected
            response = ChatParsing.detectedChatColorChanged(decodedMessage, JoinedChannels);
            if (response.Successful)
            {
                OnChatColorChanged?.Invoke(this, new OnChatColorChangedArgs
                {
                    Channel = decodedMessage.Split('#')[1].Split(' ')[0]
                });
                return;
            }
            #endregion

            #region Whisper Parsing
            if (decodedMessage.Split(' ').Count() > 2 && (decodedMessage.Split(' ')[1] == "WHISPER" || decodedMessage.Split(' ')[2] == "WHISPER"))
            {
                // On Whisper Message Received
                WhisperMessage receivedMessage = null;
                if (WhisperParsing.detectedWhisperReceived(decodedMessage, _credentials.TwitchUsername))
                {
                    receivedMessage = new WhisperMessage(decodedMessage, _credentials.TwitchUsername);
                    PreviousWhisper = receivedMessage;
                    OnWhisperReceived?.Invoke(this, new OnWhisperReceivedArgs {
                        WhisperMessage = receivedMessage
                    });
                    // Fall through to detect command as well
                }

                // On Whisper Command Received
                if (WhisperParsing.detectedWhisperCommandReceived(decodedMessage, _credentials.TwitchUsername, _whisperCommandIdentifiers))
                {
                    var    whisperMessage    = new WhisperMessage(decodedMessage, _credentials.TwitchUsername);
                    string command           = whisperMessage.Message.Split(' ')?[0].Substring(1, whisperMessage.Message.Split(' ')[0].Length - 1) ?? whisperMessage.Message.Substring(1, whisperMessage.Message.Length - 1);
                    var    argumentsAsList   = whisperMessage.Message.Split(' ')?.Where(arg => arg != whisperMessage.Message[0] + command).ToList <string>() ?? new List <string>();
                    string argumentsAsString = whisperMessage.Message.Replace(whisperMessage.Message.Split(' ')?[0] +" ", "") ?? "";
                    OnWhisperCommandReceived?.Invoke(this, new OnWhisperCommandReceivedArgs {
                        Command = command, WhisperMessage = whisperMessage, ArgumentsAsList = argumentsAsList, ArgumentsAsString = argumentsAsString
                    });
                    return;
                }

                // Return if whisper message was parsed successfully
                if (receivedMessage != null)
                {
                    return;
                }
            }
            #endregion

            // Any other messages here
            if (_logging)
            {
                Common.Log($"Unaccounted for: {decodedMessage}");
            }
        }
        public Client() : base(null)
        {
            _threadDispatcher = new GameObject("TwitchClientUnityDispatcher");
            _threadDispatcher.AddComponent <ThreadDispatcher>();
            UnityEngine.Object.DontDestroyOnLoad(_threadDispatcher);

            base.OnLog                              += ((object sender, OnLogArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnLog?.Invoke(sender, e)); });
            base.OnConnected                        += ((object sender, OnConnectedArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnConnected?.Invoke(sender, e)); });
            base.OnJoinedChannel                    += ((object sender, OnJoinedChannelArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnJoinedChannel?.Invoke(sender, e)); });
            base.OnIncorrectLogin                   += ((object sender, OnIncorrectLoginArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnIncorrectLogin?.Invoke(sender, e)); });
            base.OnChannelStateChanged              += ((object sender, OnChannelStateChangedArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnChannelStateChanged?.Invoke(sender, e)); });
            base.OnUserStateChanged                 += ((object sender, OnUserStateChangedArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnUserStateChanged?.Invoke(sender, e)); });
            base.OnMessageReceived                  += ((object sender, OnMessageReceivedArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnMessageReceived?.Invoke(sender, e)); });
            base.OnWhisperReceived                  += ((object sender, OnWhisperReceivedArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnWhisperReceived?.Invoke(sender, e)); });
            base.OnMessageSent                      += ((object sender, OnMessageSentArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnMessageSent?.Invoke(sender, e)); });
            base.OnWhisperSent                      += ((object sender, OnWhisperSentArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnWhisperSent?.Invoke(sender, e)); });
            base.OnChatCommandReceived              += ((object sender, OnChatCommandReceivedArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnChatCommandReceived?.Invoke(sender, e)); });
            base.OnWhisperCommandReceived           += ((object sender, OnWhisperCommandReceivedArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnWhisperCommandReceived?.Invoke(sender, e)); });
            base.OnUserJoined                       += ((object sender, OnUserJoinedArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnUserJoined?.Invoke(sender, e)); });
            base.OnModeratorJoined                  += ((object sender, OnModeratorJoinedArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnModeratorJoined?.Invoke(sender, e)); });
            base.OnModeratorLeft                    += ((object sender, OnModeratorLeftArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnModeratorLeft?.Invoke(sender, e)); });
            base.OnNewSubscriber                    += ((object sender, OnNewSubscriberArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnNewSubscriber?.Invoke(sender, e)); });
            base.OnReSubscriber                     += ((object sender, OnReSubscriberArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnReSubscriber?.Invoke(sender, e)); });
            base.OnHostLeft                         += ((object sender, EventArgs arg) => { ThreadDispatcher.Instance().Enqueue(() => OnHostLeft(sender, arg)); });
            base.OnExistingUsersDetected            += ((object sender, OnExistingUsersDetectedArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnExistingUsersDetected?.Invoke(sender, e)); });
            base.OnUserLeft                         += ((object sender, OnUserLeftArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnUserLeft?.Invoke(sender, e)); });
            base.OnHostingStarted                   += ((object sender, OnHostingStartedArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnHostingStarted?.Invoke(sender, e)); });
            base.OnHostingStopped                   += ((object sender, OnHostingStoppedArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnHostingStopped?.Invoke(sender, e)); });
            base.OnDisconnected                     += ((object sender, OnDisconnectedArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnDisconnected?.Invoke(sender, e)); });
            base.OnConnectionError                  += ((object sender, OnConnectionErrorArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnConnectionError?.Invoke(sender, e)); });
            base.OnChatCleared                      += ((object sender, OnChatClearedArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnChatCleared?.Invoke(sender, e)); });
            base.OnUserTimedout                     += ((object sender, OnUserTimedoutArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnUserTimedout?.Invoke(sender, e)); });
            base.OnLeftChannel                      += ((object sender, OnLeftChannelArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnLeftChannel?.Invoke(sender, e)); });
            base.OnUserBanned                       += ((object sender, OnUserBannedArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnUserBanned?.Invoke(sender, e)); });
            base.OnModeratorsReceived               += ((object sender, OnModeratorsReceivedArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnModeratorsReceived?.Invoke(sender, e)); });
            base.OnChatColorChanged                 += ((object sender, OnChatColorChangedArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnChatColorChanged?.Invoke(sender, e)); });
            base.OnSendReceiveData                  += ((object sender, OnSendReceiveDataArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnSendReceiveData?.Invoke(sender, e)); });
            base.OnNowHosting                       += ((object sender, OnNowHostingArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnNowHosting?.Invoke(sender, e)); });
            base.OnBeingHosted                      += ((object sender, OnBeingHostedArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnBeingHosted?.Invoke(sender, e)); });
            base.OnRaidNotification                 += ((object sender, OnRaidNotificationArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnRaidNotification?.Invoke(sender, e)); });
            base.OnGiftedSubscription               += ((object sender, OnGiftedSubscriptionArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnGiftedSubscription?.Invoke(sender, e)); });
            base.OnRaidedChannelIsMatureAudience    += ((object sender, EventArgs arg) => { ThreadDispatcher.Instance().Enqueue(() => OnRaidedChannelIsMatureAudience(sender, arg)); });
            base.OnRitualNewChatter                 += ((object sender, OnRitualNewChatterArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnRitualNewChatter?.Invoke(sender, e)); });
            base.OnFailureToReceiveJoinConfirmation += ((object sender, OnFailureToReceiveJoinConfirmationArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnFailureToReceiveJoinConfirmation?.Invoke(sender, e)); });
            base.OnUnaccountedFor                   += ((object sender, OnUnaccountedForArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnUnaccountedFor?.Invoke(sender, e)); });
        }
Exemple #16
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 Client_OnUserBanned(object sender, OnUserBannedArgs e)
 => OnUserBanned?.Invoke(this, e.Map());
Exemple #18
0
        static void SetClientEvents()
        {
            client.Log             += Client_Log;
            client.Ready           += Client_Ready;
            client.MessageReceived += MessageReceived;
            client.ReactionAdded   += Client_ReactionAdded;
            client.ReactionRemoved += Client_ReactionRemoved;
            client.JoinedGuild     += Client_JoinedGuild;

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