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; }
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}"); } }