Ejemplo n.º 1
0
 private async void OnReceivedEvent(WebSocketEventEventArgs e)
 {
     try
     {
         switch (e.Type)
         {
             case "VOICE_STATE_UPDATE":
                 {
                     var data = e.Payload.ToObject<VoiceStateUpdateEvent>(Serializer);
                     if (data.GuildId == VoiceSocket.Server?.Id && data.UserId == Service.Client.CurrentUser?.Id)
                     {
                         if (data.ChannelId == null)
                             await Disconnect().ConfigureAwait(false);
                         else
                         {
                             var channel = Service.Client.GetChannel(data.ChannelId.Value);
                             if (channel != null)
                                 VoiceSocket.Channel = channel;
                             else
                             {
                                 Logger.Warning("VOICE_STATE_UPDATE referenced an unknown channel, disconnecting.");
                                 await Disconnect().ConfigureAwait(false);
                             }
                         }
                     }
                 }
                 break;
             case "VOICE_SERVER_UPDATE":
                 {
                     var data = e.Payload.ToObject<VoiceServerUpdateEvent>(Serializer);
                     if (data.GuildId == VoiceSocket.Server?.Id)
                     {
                         var client = Service.Client;
                         var id = client.CurrentUser?.Id;
                         if (id != null)
                         {
                             var host = "wss://" + e.Payload.Value<string>("endpoint").Split(':')[0];
                             await VoiceSocket.Connect(host, data.Token, id.Value, GatewaySocket.SessionId, CancelToken).ConfigureAwait(false);
                         }
                     }
                 }
                 break;
         }
     }
     catch (Exception ex)
     {
         Logger.Error($"Error handling {e.Type} event", ex);
     }
 }
Ejemplo n.º 2
0
		internal override async Task OnReceivedEvent(WebSocketEventEventArgs e)
		{
			try
			{
				switch (e.Type)
				{
					//Global
					case "READY": //Resync 
						{
							base.OnReceivedEvent(e).Wait(); //This cannot be an await, or we'll get later messages before we're ready
							var data = e.Payload.ToObject<ReadyEvent>(_serializer);
							_currentUser = _users.GetOrAdd(data.User.Id, null);
							_currentUser.Update(data.User);
							foreach (var model in data.Guilds)
							{
								if (!model.Unavailable)
								{
									var server = _servers.GetOrAdd(model.Id);
									server.Update(model);
								}
							}
							foreach (var model in data.PrivateChannels)
							{
								var user = _users.GetOrAdd(model.Recipient.Id, null);
								user.Update(model.Recipient);
								var channel = _channels.GetOrAdd(model.Id, null, user.Id);
								channel.Update(model);
							}
						}
						break;

					//Servers
					case "GUILD_CREATE":
						{
							var data = e.Payload.ToObject<GuildCreateEvent>(_serializer);
							if (!data.Unavailable)
							{
								var server = _servers.GetOrAdd(data.Id);
								server.Update(data);
								if (data.Unavailable == false)
									RaiseServerAvailable(server);
								else
									RaiseServerCreated(server);
							}
						}
						break;
					case "GUILD_UPDATE":
						{
							var data = e.Payload.ToObject<GuildUpdateEvent>(_serializer);
							var server = _servers[data.Id];
							if (server != null)
							{
								server.Update(data);
								RaiseServerUpdated(server);
							}
						}
						break;
					case "GUILD_DELETE":
						{
							var data = e.Payload.ToObject<GuildDeleteEvent>(_serializer);
							var server = _servers.TryRemove(data.Id);
							if (server != null)
							{
								if (data.Unavailable == true)
									RaiseServerAvailable(server);
								else
									RaiseServerDestroyed(server);
							}
						}
						break;

					//Channels
					case "CHANNEL_CREATE":
						{
							var data = e.Payload.ToObject<ChannelCreateEvent>(_serializer);
							Channel channel;
							if (data.IsPrivate)
							{
								var user = _users.GetOrAdd(data.Recipient.Id, null);
								user.Update(data.Recipient);
								channel = _channels.GetOrAdd(data.Id, null, user.Id);
							}
							else
								channel = _channels.GetOrAdd(data.Id, data.GuildId, null);
							channel.Update(data);
							RaiseChannelCreated(channel);
						}
						break;
					case "CHANNEL_UPDATE":
						{
							var data = e.Payload.ToObject<ChannelUpdateEvent>(_serializer);
							var channel = _channels[data.Id];
							if (channel != null)
							{
								channel.Update(data);
								RaiseChannelUpdated(channel);
							}
						}
						break;
					case "CHANNEL_DELETE":
						{
							var data = e.Payload.ToObject<ChannelDeleteEvent>(_serializer);
							var channel = _channels.TryRemove(data.Id);
							if (channel != null)
								RaiseChannelDestroyed(channel);
						}
						break;

					//Members
					case "GUILD_MEMBER_ADD":
						{
							var data = e.Payload.ToObject<MemberAddEvent>(_serializer);
							var user = _users.GetOrAdd(data.User.Id, data.GuildId);
							user.Update(data);
							if (Config.TrackActivity)
								user.UpdateActivity();
							RaiseUserAdded(user);
						}
						break;
					case "GUILD_MEMBER_UPDATE":
						{
							var data = e.Payload.ToObject<MemberUpdateEvent>(_serializer);
							var user = _users[data.User.Id, data.GuildId];
							if (user != null)
							{
								user.Update(data);
								RaiseUserUpdated(user);
							}
						}
						break;
					case "GUILD_MEMBER_REMOVE":
						{
							var data = e.Payload.ToObject<MemberRemoveEvent>(_serializer);
							var user = _users.TryRemove(data.UserId, data.GuildId);
							if (user != null)
								RaiseUserRemoved(user);
						}
						break;
					case "GUILD_MEMBERS_CHUNK":
						{
							var data = e.Payload.ToObject<MembersChunkEvent>(_serializer);
							foreach (var memberData in data.Members)
							{
								var user = _users.GetOrAdd(memberData.User.Id, memberData.GuildId);
								user.Update(memberData);
								//RaiseUserAdded(user);
							}
						}
						break;

					//Roles
					case "GUILD_ROLE_CREATE":
						{
							var data = e.Payload.ToObject<RoleCreateEvent>(_serializer);
							var role = _roles.GetOrAdd(data.Data.Id, data.GuildId);
							role.Update(data.Data);
							var server = _servers[data.GuildId];
							if (server != null)
								server.AddRole(role);
							RaiseRoleUpdated(role);
						}
						break;
					case "GUILD_ROLE_UPDATE":
						{
							var data = e.Payload.ToObject<RoleUpdateEvent>(_serializer);
							var role = _roles[data.Data.Id];
							if (role != null)
							{
								role.Update(data.Data);
								RaiseRoleUpdated(role);
							}
						}
						break;
					case "GUILD_ROLE_DELETE":
						{
							var data = e.Payload.ToObject<RoleDeleteEvent>(_serializer);
							var role = _roles.TryRemove(data.RoleId);
							if (role != null)
							{
								RaiseRoleDeleted(role);
								var server = _servers[data.GuildId];
								if (server != null)
									server.RemoveRole(role);
							}
						}
						break;

					//Bans
					case "GUILD_BAN_ADD":
						{
							var data = e.Payload.ToObject<BanAddEvent>(_serializer);
							var server = _servers[data.GuildId];
							if (server != null)
							{
								server.AddBan(data.User?.Id);
								RaiseUserBanned(data.User?.Id, server);
							}
						}
						break;
					case "GUILD_BAN_REMOVE":
						{
							var data = e.Payload.ToObject<BanRemoveEvent>(_serializer);
							var server = _servers[data.GuildId];
							if (server != null && server.RemoveBan(data.User?.Id))
								RaiseUserUnbanned(data.User?.Id, server);
						}
						break;

					//Messages
					case "MESSAGE_CREATE":
						{
							var data = e.Payload.ToObject<MessageCreateEvent>(_serializer);
							Message msg = null;

							bool isAuthor = data.Author.Id == _userId;

							if (msg == null)
								msg = _messages.GetOrAdd(data.Id, data.ChannelId, data.Author.Id);
							msg.Update(data);
							if (Config.TrackActivity)
							{
								var channel = msg.Channel;
								if (channel?.IsPrivate == false)
								{
									var user = msg.User;
									if (user != null)
										user.UpdateActivity(data.Timestamp);
								}
							}

							RaiseMessageReceived(msg);

							if (Config.AckMessages && !isAuthor)
								await _api.AckMessage(data.Id, data.ChannelId).ConfigureAwait(false);
						}
						break;
					case "MESSAGE_UPDATE":
						{
							var data = e.Payload.ToObject<MessageUpdateEvent>(_serializer);
							var msg = _messages[data.Id];
							if (msg != null)
							{
								msg.Update(data);
								RaiseMessageUpdated(msg);
							}
						}
						break;
					case "MESSAGE_DELETE":
						{
							var data = e.Payload.ToObject<MessageDeleteEvent>(_serializer);
							var msg = _messages.TryRemove(data.Id);
							if (msg != null)
								RaiseMessageDeleted(msg);
						}
						break;
					case "MESSAGE_ACK":
						{
							var data = e.Payload.ToObject<MessageAckEvent>(_serializer);
							var msg = GetMessage(data.MessageId);
							if (msg != null)
								RaiseMessageReadRemotely(msg);
						}
						break;

					//Statuses
					case "PRESENCE_UPDATE":
						{
							var data = e.Payload.ToObject<PresenceUpdateEvent>(_serializer);
							var user = _users.GetOrAdd(data.User.Id, data.GuildId);
							if (user != null)
							{
								user.Update(data);
								RaiseUserPresenceUpdated(user);
							}
						}
						break;
					case "TYPING_START":
						{
							var data = e.Payload.ToObject<TypingStartEvent>(_serializer);
							var channel = _channels[data.ChannelId];
							if (channel != null)
							{
								var user = _users[data.UserId, channel.Server?.Id];
								if (user != null)
								{
									if (channel != null)
										RaiseUserIsTyping(user, channel);
								}

								if (Config.TrackActivity)
								{
									if (!channel.IsPrivate)
									{
										if (user != null)
											user.UpdateActivity();
									}
								}
							}
						}
						break;

					//Voice
					case "VOICE_STATE_UPDATE":
						{
							var data = e.Payload.ToObject<MemberVoiceStateUpdateEvent>(_serializer);
							var user = _users[data.UserId, data.GuildId];
							if (user != null)
							{
								var voiceChannel = user.VoiceChannel;
                                if (voiceChannel != null && data.ChannelId != voiceChannel.Id && user.IsSpeaking)
								{
									user.IsSpeaking = false;
									RaiseUserIsSpeaking(user, _channels[voiceChannel.Id], false);
								}
								user.Update(data);
								RaiseUserVoiceStateUpdated(user);
							}
						}
						break;

					//Settings
					case "USER_UPDATE":
						{
							var data = e.Payload.ToObject<UserUpdateEvent>(_serializer);
							var user = _globalUsers[data.Id];
							if (user != null)
							{
								user.Update(data);
								RaiseProfileUpdated();
							}
						}
						break;

					//Ignored
					case "USER_SETTINGS_UPDATE":
					case "GUILD_INTEGRATIONS_UPDATE":
                        break;

					//Internal (handled in DataWebSocket)
					case "RESUMED":
						break;

					//Pass to DiscordWSClient
					case "VOICE_SERVER_UPDATE":
						await base.OnReceivedEvent(e).ConfigureAwait(false);
						break;

					//Others
					default:
						RaiseOnLog(LogMessageSeverity.Warning, LogMessageSource.DataWebSocket, $"Unknown message type: {e.Type}");
						break;
				}
			}
			catch (Exception ex)
			{
				RaiseOnLog(LogMessageSeverity.Error, LogMessageSource.Client, $"Error handling {e.Type} event: {ex.GetBaseException().Message}");
			}
		}
Ejemplo n.º 3
0
		internal virtual async Task OnReceivedEvent(WebSocketEventEventArgs e)
		{
			try
			{
				switch (e.Type)
				{
					case "READY":
						_userId = e.Payload["user"].Value<string>("id");
						break;
					case "VOICE_SERVER_UPDATE":
						{
							string guildId = e.Payload.Value<string>("guild_id");

							if (_config.EnableVoice && guildId == _voiceSocket.CurrentServerId)
							{
								string token = e.Payload.Value<string>("token");
								_voiceSocket.Host = "wss://" + e.Payload.Value<string>("endpoint").Split(':')[0];
								await _voiceSocket.Login(_userId, _dataSocket.SessionId, token, _cancelToken).ConfigureAwait(false);
							}
						}
						break;
				}
			}
			catch (Exception ex)
			{
				RaiseOnLog(LogMessageSeverity.Error, LogMessageSource.Client, $"Error handling {e.Type} event: {ex.GetBaseException().Message}");
			}
		}
Ejemplo n.º 4
0
        private void OnReceivedEvent(WebSocketEventEventArgs e)
        {
            try
            {
                switch (e.Type)
                {
                    //Global
                    case "READY":
                        {
                            Stopwatch stopwatch = null;
                            if (Config.LogLevel >= LogSeverity.Verbose)
                                stopwatch = Stopwatch.StartNew();
                            var data = e.Payload.ToObject<ReadyEvent>(_serializer);
                            GatewaySocket.StartHeartbeat(data.HeartbeatInterval);
                            GatewaySocket.SessionId = data.SessionId;
                            SessionId = data.SessionId;
                            PrivateUser = new User(this, data.User.Id, null);
                            PrivateUser.Update(data.User);
                            CurrentUser = new Profile(this, data.User.Id);
                            CurrentUser.Update(data.User);
                            foreach (var model in data.Guilds)
                            {
                                if (model.Unavailable != true)
                                {
                                    var server = AddServer(model.Id);
                                    server.Update(model);
                                }
                            }
                            foreach (var model in data.PrivateChannels)
                            {
                                var channel = AddPrivateChannel(model.Id, model.Recipient.Id);
                                channel.Update(model);
                            }
                            if (Config.LogLevel >= LogSeverity.Verbose)
                            {
                                stopwatch.Stop();
                                double seconds = Math.Round(stopwatch.ElapsedTicks / (double)TimeSpan.TicksPerSecond, 2);
                                Logger.Verbose($"READY took {seconds} sec");
                            }
                        }
                        break;
                    case "RESUMED":
                        {
                            var data = e.Payload.ToObject<ResumedEvent>(_serializer);
                            GatewaySocket.StartHeartbeat(data.HeartbeatInterval);
                        }
                        break;

                    //Servers
                    case "GUILD_CREATE":
                        {
                            var data = e.Payload.ToObject<GuildCreateEvent>(_serializer);
                            if (data.Unavailable != true)
                            {
                                var server = AddServer(data.Id);
                                server.Update(data);

                                if (Config.LogEvents)
                                {
                                    if (data.Unavailable != false)
                                        Logger.Info($"Server Created: {server.Name}");
                                    else
                                        Logger.Info($"Server Available: {server.Name}");
                                }

                                if (data.Unavailable != false)
                                    OnJoinedServer(server);
                                OnServerAvailable(server);
                            }
                        }
                        break;
                    case "GUILD_UPDATE":
                        {
                            var data = e.Payload.ToObject<GuildUpdateEvent>(_serializer);
                            var server = GetServer(data.Id);
                            if (server != null)
                            {
                                server.Update(data);
                                if (Config.LogEvents)
                                    Logger.Info($"Server Updated: {server.Name}");
                                OnServerUpdated(server);
                            }
                            else
                                Logger.Warning("GUILD_UPDATE referenced an unknown guild.");
                        }
                        break;
                    case "GUILD_DELETE":
                        {
                            var data = e.Payload.ToObject<GuildDeleteEvent>(_serializer);
                            Server server = RemoveServer(data.Id);
                            if (server != null)
                            {
                                if (Config.LogEvents)
                                {
                                    if (data.Unavailable != true)
                                        Logger.Info($"Server Destroyed: {server.Name}");
                                    else
                                        Logger.Info($"Server Unavailable: {server.Name}");
                                }

                                OnServerUnavailable(server);
                                if (data.Unavailable != true)
                                    OnLeftServer(server);
                            }
                            else
                                Logger.Warning("GUILD_DELETE referenced an unknown guild.");
                        }
                        break;

                    //Channels
                    case "CHANNEL_CREATE":
                        {
                            var data = e.Payload.ToObject<ChannelCreateEvent>(_serializer);

                            Channel channel = null;
                            if (data.GuildId != null)
                            {
                                var server = GetServer(data.GuildId.Value);
                                if (server != null)
                                    channel = server.AddChannel(data.Id);
                                else
                                    Logger.Warning("CHANNEL_CREATE referenced an unknown guild.");
                            }
                            else
                                channel = AddPrivateChannel(data.Id, data.Recipient.Id);
                            if (channel != null)
                            {
                                channel.Update(data);
                                if (Config.LogEvents)
                                    Logger.Info($"Channel Created: {channel.Server?.Name ?? "[Private]"}/{channel.Name}");
                                OnChannelCreated(channel);
                            }
                        }
                        break;
                    case "CHANNEL_UPDATE":
                        {
                            var data = e.Payload.ToObject<ChannelUpdateEvent>(_serializer);
                            var channel = GetChannel(data.Id);
                            if (channel != null)
                            {
                                channel.Update(data);
                                if (Config.LogEvents)
                                    Logger.Info($"Channel Updated: {channel.Server?.Name ?? "[Private]"}/{channel.Name}");
                                OnChannelUpdated(channel);
                            }
                            else
                                Logger.Warning("CHANNEL_UPDATE referenced an unknown channel.");
                        }
                        break;
                    case "CHANNEL_DELETE":
                        {
                            var data = e.Payload.ToObject<ChannelDeleteEvent>(_serializer);
                            var channel = RemoveChannel(data.Id);
                            if (channel != null)
                            {
                                if (Config.LogEvents)
                                    Logger.Info($"Channel Destroyed: {channel.Server?.Name ?? "[Private]"}/{channel.Name}");
                                OnChannelDestroyed(channel);
                            }
                            else
                                Logger.Warning("CHANNEL_DELETE referenced an unknown channel.");
                        }
                        break;

                    //Members
                    case "GUILD_MEMBER_ADD":
                        {
                            var data = e.Payload.ToObject<GuildMemberAddEvent>(_serializer);
                            var server = GetServer(data.GuildId.Value);
                            if (server != null)
                            {
                                var user = server.AddUser(data.User.Id);
                                user.Update(data);
                                user.UpdateActivity();
                                if (Config.LogEvents)
                                    Logger.Info($"User Joined: {server.Name}/{user.Name}");
                                OnUserJoined(user);
                            }
                            else
                                Logger.Warning("GUILD_MEMBER_ADD referenced an unknown guild.");
                        }
                        break;
                    case "GUILD_MEMBER_UPDATE":
                        {
                            var data = e.Payload.ToObject<GuildMemberUpdateEvent>(_serializer);
                            var server = GetServer(data.GuildId.Value);
                            if (server != null)
                            {
                                var user = server.GetUser(data.User.Id);
                                if (user != null)
                                {
                                    user.Update(data);
                                    if (Config.LogEvents)
                                        Logger.Info($"User Updated: {server.Name}/{user.Name}");
                                    OnUserUpdated(user);
                                }
                                else
                                    Logger.Warning("GUILD_MEMBER_UPDATE referenced an unknown user.");
                            }
                            else
                                Logger.Warning("GUILD_MEMBER_UPDATE referenced an unknown guild.");
                        }
                        break;
                    case "GUILD_MEMBER_REMOVE":
                        {
                            var data = e.Payload.ToObject<GuildMemberRemoveEvent>(_serializer);
                            var server = GetServer(data.GuildId.Value);
                            if (server != null)
                            {
                                var user = server.RemoveUser(data.User.Id);
                                if (user != null)
                                {
                                    if (Config.LogEvents)
                                        Logger.Info($"User Left: {server.Name}/{user.Name}");
                                    OnUserLeft(user);
                                }
                                else
                                    Logger.Warning("GUILD_MEMBER_REMOVE referenced an unknown user.");
                            }
                            else
                                Logger.Warning("GUILD_MEMBER_REMOVE referenced an unknown guild.");
                        }
                        break;
                    case "GUILD_MEMBERS_CHUNK":
                        {
                            var data = e.Payload.ToObject<GuildMembersChunkEvent>(_serializer);
                            var server = GetServer(data.GuildId);
                            if (server != null)
                            {
                                foreach (var memberData in data.Members)
                                {
                                    var user = server.AddUser(memberData.User.Id);
                                    user.Update(memberData);
                                    //OnUserAdded(user);
                                }
                            }
                            else
                                Logger.Warning("GUILD_MEMBERS_CHUNK referenced an unknown guild.");
                        }
                        break;

                    //Roles
                    case "GUILD_ROLE_CREATE":
                        {
                            var data = e.Payload.ToObject<GuildRoleCreateEvent>(_serializer);
                            var server = GetServer(data.GuildId);
                            if (server != null)
                            {
                                var role = server.AddRole(data.Data.Id);
                                role.Update(data.Data);
                                if (Config.LogEvents)
                                    Logger.Info($"Role Created: {server.Name}/{role.Name}");
                                OnRoleUpdated(role);
                            }
                            else
                                Logger.Warning("GUILD_ROLE_CREATE referenced an unknown guild.");
                        }
                        break;
                    case "GUILD_ROLE_UPDATE":
                        {
                            var data = e.Payload.ToObject<GuildRoleUpdateEvent>(_serializer);
                            var server = GetServer(data.GuildId);
                            if (server != null)
                            {
                                var role = server.GetRole(data.Data.Id);
                                if (role != null)
                                {
                                    role.Update(data.Data);
                                    if (Config.LogEvents)
                                        Logger.Info($"Role Updated: {server.Name}/{role.Name}");
                                    OnRoleUpdated(role);
                                }
                                else
                                    Logger.Warning("GUILD_ROLE_UPDATE referenced an unknown role.");
                            }
                            else
                                Logger.Warning("GUILD_ROLE_UPDATE referenced an unknown guild.");
                        }
                        break;
                    case "GUILD_ROLE_DELETE":
                        {
                            var data = e.Payload.ToObject<GuildRoleDeleteEvent>(_serializer);
                            var server = GetServer(data.GuildId);
                            if (server != null)
                            {
                                var role = server.RemoveRole(data.RoleId);
                                if (role != null)
                                {
                                    if (Config.LogEvents)
                                        Logger.Info($"Role Deleted: {server.Name}/{role.Name}");
                                    OnRoleDeleted(role);
                                }
                                else
                                    Logger.Warning("GUILD_ROLE_DELETE referenced an unknown role.");
                            }
                            else
                                Logger.Warning("GUILD_ROLE_DELETE referenced an unknown guild.");
                        }
                        break;

                    //Bans
                    case "GUILD_BAN_ADD":
                        {
                            var data = e.Payload.ToObject<GuildBanAddEvent>(_serializer);
                            var server = GetServer(data.GuildId.Value);
                            if (server != null)
                            {
                                var user = server.GetUser(data.User.Id);
                                if (user != null)
                                {
                                    if (Config.LogEvents)
                                        Logger.Info($"User Banned: {server.Name}/{user.Name}");
                                    OnUserBanned(user);
                                }
                                else
                                    Logger.Warning("GUILD_BAN_ADD referenced an unknown user.");
                            }
                            else
                                Logger.Warning("GUILD_BAN_ADD referenced an unknown guild.");
                        }
                        break;
                    case "GUILD_BAN_REMOVE":
                        {
                            var data = e.Payload.ToObject<GuildBanRemoveEvent>(_serializer);
                            var server = GetServer(data.GuildId.Value);
                            if (server != null)
                            {
                                var user = new User(this, data.User.Id, server);
                                user.Update(data.User);
                                if (Config.LogEvents)
                                    Logger.Info($"User Unbanned: {server.Name}/{user.Name}");
                                OnUserUnbanned(user);
                            }
                            else
                                Logger.Warning("GUILD_BAN_REMOVE referenced an unknown guild.");
                        }
                        break;

                    //Messages
                    case "MESSAGE_CREATE":
                        {
                            var data = e.Payload.ToObject<MessageCreateEvent>(_serializer);

                            Channel channel = GetChannel(data.ChannelId);
                            if (channel != null)
                            {
                                var user = channel.GetUser(data.Author.Id);
                                if (user != null)
                                {
                                    Message msg = null;
                                    bool isAuthor = data.Author.Id == CurrentUser.Id;
                                    //ulong nonce = 0;

                                    /*if (data.Author.Id == _privateUser.Id && Config.UseMessageQueue)
                                    {
                                        if (data.Nonce != null && ulong.TryParse(data.Nonce, out nonce))
                                            msg = _messages[nonce];
                                    }*/
                                    if (msg == null)
                                    {
                                        msg = channel.AddMessage(data.Id, user, data.Timestamp.Value);
                                        //nonce = 0;
                                    }

                                    //Remapped queued message
                                    /*if (nonce != 0)
                                    {
                                        msg = _messages.Remap(nonce, data.Id);
                                        msg.Id = data.Id;
                                        RaiseMessageSent(msg);
                                    }*/

                                    msg.Update(data);
                                    user.UpdateActivity();

                                    msg.State = MessageState.Normal;
                                    if (Config.LogEvents)
                                        Logger.Verbose($"Message Received: {channel.Server?.Name ?? "[Private]"}/{channel.Name}");
                                    OnMessageReceived(msg);
                                }
                            }
                            else
                                Logger.Warning("MESSAGE_CREATE referenced an unknown channel.");
                        }
                        break;
                    case "MESSAGE_UPDATE":
                        {
                            if (Config.MessageCacheSize > 0)
                            {
                                var data = e.Payload.ToObject<MessageUpdateEvent>(_serializer);
                                var channel = GetChannel(data.ChannelId);
                                if (channel != null)
                                {
                                    var msg = channel.GetMessage(data.Id);
                                    if (msg != null)
                                    {
                                        msg.Update(data);
                                        msg.State = MessageState.Normal;
                                        if (Config.LogEvents)
                                            Logger.Info($"Message Update: {channel.Server?.Name ?? "[Private]"}/{channel.Name}");
                                        OnMessageUpdated(msg);
                                    }
                                }
                                else
                                    Logger.Warning("MESSAGE_UPDATE referenced an unknown channel.");
                            }
                        }
                        break;
                    case "MESSAGE_DELETE":
                        {
                            if (Config.MessageCacheSize > 0)
                            {
                                var data = e.Payload.ToObject<MessageDeleteEvent>(_serializer);
                                var channel = GetChannel(data.ChannelId);
                                if (channel != null)
                                {
                                    var msg = channel.RemoveMessage(data.Id);
                                    if (msg != null)
                                    {
                                        if (Config.LogEvents)
                                            Logger.Info($"Message Deleted: {channel.Server?.Name ?? "[Private]"}/{channel.Name}");
                                        OnMessageDeleted(msg);
                                    }
                                }
                                else
                                    Logger.Warning("MESSAGE_DELETE referenced an unknown channel.");
                            }
                        }
                        break;
                    case "MESSAGE_ACK":
                        {
                            if (Config.MessageCacheSize > 0)
                            {
                                var data = e.Payload.ToObject<MessageAckEvent>(_serializer);
                                var channel = GetChannel(data.ChannelId);
                                if (channel != null)
                                {
                                    var msg = channel.GetMessage(data.MessageId);
                                    if (msg != null)
                                    {
                                        if (Config.LogEvents)
                                            Logger.Verbose($"Message Ack: {channel.Server?.Name ?? "[Private]"}/{channel.Name}");
                                        OnMessageAcknowledged(msg);
                                    }
                                }
                                else
                                    Logger.Warning("MESSAGE_ACK referenced an unknown channel.");
                            }
                        }
                        break;

                    //Statuses
                    case "PRESENCE_UPDATE":
                        {
                            var data = e.Payload.ToObject<PresenceUpdateEvent>(_serializer);
                            User user;
                            Server server;
                            if (data.GuildId == null)
                            {
                                server = null;
                                user = GetPrivateChannel(data.User.Id)?.Recipient;
                            }
                            else
                            {
                                server = GetServer(data.GuildId.Value);
                                if (server == null)
                                {
                                    Logger.Warning("PRESENCE_UPDATE referenced an unknown server.");
                                    break;
                                }
                                else
                                {
                                    if (Config.UseLargeThreshold)
                                        user = server.AddUser(data.User.Id);
                                    else
                                        user = server.GetUser(data.User.Id);
                                }
                            }

                            if (user != null)
                            {
                                user.Update(data);
                                //Logger.Verbose($"Presence Updated: {server.Name}/{user.Name}");
                                OnUserPresenceUpdated(user);
                            }
                            /*else //Occurs when a user leaves a server
                                Logger.Warning("PRESENCE_UPDATE referenced an unknown user.");*/
                        }
                        break;
                    case "TYPING_START":
                        {
                            var data = e.Payload.ToObject<TypingStartEvent>(_serializer);
                            var channel = GetChannel(data.ChannelId);
                            if (channel != null)
                            {
                                User user;
                                if (channel.IsPrivate)
                                {
                                    if (channel.Recipient.Id == data.UserId)
                                        user = channel.Recipient;
                                    else
                                        return; ;
                                }
                                else
                                    user = channel.Server.GetUser(data.UserId);
                                if (user != null)
                                {
                                    //Logger.Verbose($"Is Typing: {channel.Server?.Name ?? "[Private]"}/{channel.Name}/{user.Name}");
                                    OnUserIsTypingUpdated(channel, user);
                                    user.UpdateActivity();
                                }
                            }
                            else
                                Logger.Warning("TYPING_START referenced an unknown channel.");
                        }
                        break;

                    //Voice
                    case "VOICE_STATE_UPDATE":
                        {
                            var data = e.Payload.ToObject<VoiceStateUpdateEvent>(_serializer);
                            var server = GetServer(data.GuildId);
                            if (server != null)
                            {
                                var user = server.GetUser(data.UserId);
                                if (user != null)
                                {
                                    user.Update(data);
                                    //Logger.Verbose($"Voice Updated: {server.Name}/{user.Name}");
                                    OnUserVoiceStateUpdated(user);
                                }
                                /*else //Occurs when a user leaves a server
                                    Logger.Warning("VOICE_STATE_UPDATE referenced an unknown user.");*/
                            }
                            else
                                Logger.Warning("VOICE_STATE_UPDATE referenced an unknown server.");
                        }
                        break;

                    //Settings
                    case "USER_UPDATE":
                        {
                            var data = e.Payload.ToObject<UserUpdateEvent>(_serializer);
                            if (data.Id == CurrentUser.Id)
                            {
                                CurrentUser.Update(data);
                                PrivateUser.Update(data);
                                foreach (var server in _servers)
                                    server.Value.CurrentUser.Update(data);
                                if (Config.LogEvents)
                                    Logger.Info("Profile Updated");
                                OnProfileUpdated(CurrentUser);
                            }
                        }
                        break;

                    //Ignored
                    case "USER_SETTINGS_UPDATE":
                    case "GUILD_INTEGRATIONS_UPDATE":
                    case "VOICE_SERVER_UPDATE":
                    case "GUILD_EMOJIS_UPDATE":
                        break;

                    //Others
                    default:
                        Logger.Warning($"Unknown message type: {e.Type}");
                        break;
                }
            }
            catch (Exception ex)
            {
                Logger.Error($"Error handling {e.Type} event", ex);
            }
        }