internal virtual Task OnReceivedEvent(WebSocketEventEventArgs e)
		{
			try
			{
				switch (e.Type)
				{
					case "READY":
						_currentUserId = e.Payload["user"].Value<string>("id");
						break;
					case "VOICE_SERVER_UPDATE":
						{
							string guildId = e.Payload.Value<string>("guild_id");

							if (_enableVoice && guildId == _voiceSocket.CurrentServerId)
							{
								string token = e.Payload.Value<string>("token");
								_voiceSocket.Host = "wss://" + e.Payload.Value<string>("endpoint").Split(':')[0];
								return _voiceSocket.Login(_currentUserId, _dataSocket.SessionId, token, CancelToken);
							}
						}
						break;
				}
			}
			catch (Exception ex)
			{
				RaiseOnLog(LogMessageSeverity.Error, LogMessageSource.Client, $"Error handling {e.Type} event: {ex.GetBaseException().Message}");
			}
			return TaskHelper.CompletedTask;
		}
Exemple #2
0
		internal override async Task OnReceivedEvent(WebSocketEventEventArgs e)
		{
			try
			{
				await base.OnReceivedEvent(e);

				switch (e.Type)
				{
					//Global
					case "READY": //Resync
						{
							var data = e.Payload.ToObject<ReadyEvent>(_serializer);
							_currentUser = _users.GetOrAdd(data.User.Id);
							_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);
								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);
								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<GuildMemberAddEvent>(_serializer);
							var user = _users.GetOrAdd(data.User.Id);
							user.Update(data.User);
							var member = _members.GetOrAdd(data.User.Id, data.GuildId);
							member.Update(data);
							if (Config.TrackActivity)
								member.UpdateActivity();
							RaiseUserAdded(member);
						}
						break;
					case "GUILD_MEMBER_UPDATE":
						{
							var data = e.Payload.ToObject<GuildMemberUpdateEvent>(_serializer);
							var member = _members[data.User.Id, data.GuildId];
							if (member != null)
							{
								member.Update(data);
								RaiseMemberUpdated(member);
							}
						}
						break;
					case "GUILD_MEMBER_REMOVE":
						{
							var data = e.Payload.ToObject<GuildMemberRemoveEvent>(_serializer);
							var member = _members.TryRemove(data.UserId, data.GuildId);
							if (member != null)
								RaiseUserRemoved(member);
						}
						break;

					//Roles
					case "GUILD_ROLE_CREATE":
						{
							var data = e.Payload.ToObject<GuildRoleCreateEvent>(_serializer);
							var role = _roles.GetOrAdd(data.Data.Id, data.GuildId, false);
							role.Update(data.Data);
							var server = _servers[data.GuildId];
							if (server != null)
								server.AddRole(data.Data.Id);
							RaiseRoleUpdated(role);
						}
						break;
					case "GUILD_ROLE_UPDATE":
						{
							var data = e.Payload.ToObject<GuildRoleUpdateEvent>(_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<GuildRoleDeleteEvent>(_serializer);
							var server = _servers[data.GuildId];
							if (server != null)
								server.RemoveRole(data.RoleId);
							var role = _roles.TryRemove(data.RoleId);
							if (role != null)
								RaiseRoleDeleted(role);
						}
						break;

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

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

							bool isAuthor = data.Author.Id == CurrentUserId;
                            bool hasFinishedSending = false;
							if (Config.UseMessageQueue && isAuthor && data.Nonce != null)
							{
								msg = _messages.Remap("nonce" + data.Nonce, data.Id);
								if (msg != null)
								{
									msg.IsQueued = false;
									msg.Id = data.Id;
									hasFinishedSending = true;
                                }
							}

							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 == null || channel.IsPrivate)
								{
									var user = msg.User;
									if (user != null)
										user.UpdateActivity(data.Timestamp);
								}
								else
								{
									var member = msg.Member;
									if (member != null)
										member.UpdateActivity(data.Timestamp);
								}
							}

							if (Config.AckMessages && isAuthor)
								await _api.AckMessage(data.Id, data.ChannelId);

							if (hasFinishedSending)
								RaiseMessageSent(msg);
							RaiseMessageCreated(msg);
						}
						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 member = _members[data.User.Id, data.GuildId];
							/*if (_config.TrackActivity)
							{
								var user = _users[data.User.Id];
								if (user != null)
									user.UpdateActivity(DateTime.UtcNow);
							}*/
							if (member != null)
							{
								member.Update(data);
								RaiseUserPresenceUpdated(member);
							}
						}
						break;
					case "TYPING_START":
						{
							var data = e.Payload.ToObject<TypingStartEvent>(_serializer);
							var channel = _channels[data.ChannelId];
							var user = _users[data.UserId];

							if (user != null)
							{
								if (channel != null)
									RaiseUserIsTyping(user, channel);
							}
							if (Config.TrackActivity)
							{
								if (channel.IsPrivate)
								{
									if (user != null)
										user.UpdateActivity();
								}
								else
								{
									var member = _members[data.UserId, channel.ServerId];
									if (member != null)
										member.UpdateActivity();
								}
							}
						}
						break;

					//Voice
					case "VOICE_STATE_UPDATE":
						{
							var data = e.Payload.ToObject<VoiceStateUpdateEvent>(_serializer);
							var member = _members[data.UserId, data.GuildId];
							if (member != null)
							{
								if (data.ChannelId != member.VoiceChannelId && member.IsSpeaking)
								{
									member.IsSpeaking = false;
									RaiseUserIsSpeaking(member, false);
								}
								member.Update(data);
								RaiseUserVoiceStateUpdated(member);
							}
						}
						break;

					//Settings
					case "USER_UPDATE":
						{
							var data = e.Payload.ToObject<UserUpdateEvent>(_serializer);
							var user = _users[data.Id];
							if (user != null)
							{
								user.Update(data);
								RaiseUserUpdated(user);
							}
						}
						break;
					case "USER_SETTINGS_UPDATE":
						{
							//TODO: Process this
						}
						break;

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

					//Internal (handled in DiscordSimpleClient)
					case "VOICE_SERVER_UPDATE":
						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}");
			}
		}