public async Task <IEnumerable <User> > GetBans() { var response = await Client.ClientAPI.Send(new GetBansRequest(Id)).ConfigureAwait(false); return(response.Select(x => { var user = new User(Client, x.Id, this); user.Update(x); return user; })); }
internal void Update(InviteReference model) { if (model.Guild != null && _generatedServer != null) { _generatedServer.Update(model.Guild); } if (model.Inviter != null && _generatedInviter != null) { _generatedInviter.Update(model.Inviter); } if (model.Channel != null && _generatedChannel != null) { _generatedChannel.Update(model.Channel); } }
public async Task<IEnumerable<User>> GetBans() { var response = await Client.ClientAPI.Send(new GetBansRequest(Id)).ConfigureAwait(false); return response.Select(x => { var user = new User(Client, x.Id, this); user.Update(x); return user; }); }
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}"); } }
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); } }
private void OnReceivedEvent(WebSocketEventEventArgs e) { try { switch (e.Type) { //Global case "READY": { //TODO: None of this is really threadsafe - should only replace the cache collections when they have been fully populated var data = e.Payload.ToObject <ReadyEvent>(Serializer); int channelCount = 0; for (int i = 0; i < data.Guilds.Length; i++) { channelCount += data.Guilds[i].Channels.Length; } //ConcurrencyLevel = 2 (only REST and WebSocket can add/remove) _servers = new ConcurrentDictionary <ulong, Server>(2, (int)(data.Guilds.Length * 1.05)); _channels = new ConcurrentDictionary <ulong, IChannel>(2, (int)(channelCount * 1.05)); _privateChannels = new ConcurrentDictionary <ulong, PrivateChannel>(2, (int)(data.PrivateChannels.Length * 1.05)); List <ulong> largeServers = new List <ulong>(); SessionId = data.SessionId; PrivateUser = new User(data.User, this, null); PrivateUser.Update(data.User); CurrentUser = new Profile(data.User, this); CurrentUser.Update(data.User); for (int i = 0; i < data.Guilds.Length; i++) { var model = data.Guilds[i]; if (model.Unavailable != true) { var server = AddServer(model.Id); server.Update(model); if (model.IsLarge) { largeServers.Add(server.Id); } } } for (int i = 0; i < data.PrivateChannels.Length; i++) { AddPrivateChannel(data.PrivateChannels[i]); } if (largeServers.Count > 0) { GatewaySocket.SendRequestMembers(largeServers, "", 0); } else { EndConnect(); } } 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 (data.Unavailable != false) { Logger.Info($"GUILD_CREATE: {server}"); } else { Logger.Info($"GUILD_AVAILABLE: {server}"); } 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) { var before = Config.EnablePreUpdateEvents ? server.Clone() : null; server.Update(data); Logger.Info($"GUILD_UPDATE: {server}"); OnServerUpdated(before, 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 (data.Unavailable != true) { Logger.Info($"GUILD_DELETE: {server}"); } else { Logger.Info($"GUILD_UNAVAILABLE: {server}"); } 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); IChannel channel = null; if (data.GuildId != null) { var server = GetServer(data.GuildId.Value); if (server != null) { channel = server.AddChannel(data, true); } else { Logger.Warning("CHANNEL_CREATE referenced an unknown guild."); break; } } else { channel = AddPrivateChannel(data); } Logger.Info($"CHANNEL_CREATE: {channel}"); OnChannelCreated(channel); } break; case "CHANNEL_UPDATE": { var data = e.Payload.ToObject <ChannelUpdateEvent>(Serializer); var channel = GetChannel(data.Id); if (channel != null) { var before = Config.EnablePreUpdateEvents ? (channel as Channel).Clone() : null; (channel as Channel).Update(data); Logger.Info($"CHANNEL_UPDATE: {channel}"); OnChannelUpdated(before, 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) { Logger.Info($"CHANNEL_DELETE: {channel}"); 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, true, true); user.Update(data); user.UpdateActivity(); Logger.Info($"GUILD_MEMBER_ADD: {user}"); 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) { var before = Config.EnablePreUpdateEvents ? user.Clone() : null; user.Update(data); Logger.Info($"GUILD_MEMBER_UPDATE: {user}"); OnUserUpdated(before, 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) { Logger.Info($"GUILD_MEMBER_REMOVE: {user}"); 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, true, false); user.Update(memberData); } Logger.Verbose($"GUILD_MEMBERS_CHUNK: {data.Members.Length} users"); if (server.CurrentUserCount >= server.UserCount) //Finished downloading for there { bool isConnectComplete = true; foreach (var server2 in _servers.Select(x => x.Value)) { if (server2.CurrentUserCount < server2.UserCount) { isConnectComplete = false; } } if (isConnectComplete) { EndConnect(); } } } 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, false); Logger.Info($"GUILD_ROLE_CREATE: {role}"); OnRoleCreated(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) { var before = Config.EnablePreUpdateEvents ? role.Clone() : null; role.Update(data.Data, true); Logger.Info($"GUILD_ROLE_UPDATE: {role}"); OnRoleUpdated(before, 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) { Logger.Info($"GUILD_ROLE_DELETE: {role}"); 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) { Logger.Info($"GUILD_BAN_ADD: {user}"); 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(data.User, this, server); user.Update(data.User); Logger.Info($"GUILD_BAN_REMOVE: {user}"); OnUserUnbanned(user); } else { Logger.Warning("GUILD_BAN_REMOVE referenced an unknown guild."); } } break; //Messages case "MESSAGE_CREATE": { var data = e.Payload.ToObject <MessageCreateEvent>(Serializer); var channel = GetChannel(data.ChannelId) as ITextChannel; if (channel != null) { var user = (channel as Channel).GetUser(data.Author.Id); if (user != null) { Message msg = null; msg = (channel as Channel).MessageManager.Add(data, user); user.UpdateActivity(); Logger.Verbose($"MESSAGE_CREATE: {channel} ({user})"); OnMessageReceived(msg); } else { Logger.Warning("MESSAGE_CREATE referenced an unknown user."); } } else { Logger.Warning("MESSAGE_CREATE referenced an unknown channel."); } } break; case "MESSAGE_UPDATE": { var data = e.Payload.ToObject <MessageUpdateEvent>(Serializer); var channel = GetChannel(data.ChannelId) as ITextChannel; if (channel != null) { var msg = (channel as Channel).MessageManager.Get(data.Id, data.Author?.Id); var before = Config.EnablePreUpdateEvents ? msg.Clone() : null; msg.Update(data); Logger.Verbose($"MESSAGE_UPDATE: {channel} ({data.Author?.Username ?? "Unknown"})"); OnMessageUpdated(before, msg); } else { Logger.Warning("MESSAGE_UPDATE referenced an unknown channel."); } } break; case "MESSAGE_DELETE": { var data = e.Payload.ToObject <MessageDeleteEvent>(Serializer); var channel = GetChannel(data.ChannelId) as ITextChannel; if (channel != null) { var msg = (channel as Channel).MessageManager.Remove(data.Id); Logger.Verbose($"MESSAGE_DELETE: {channel} ({msg.User?.Name ?? "Unknown"})"); OnMessageDeleted(msg); } else { Logger.Warning("MESSAGE_DELETE 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 { user = server.GetUser(data.User.Id); } } if (user != null) { if (Config.LogLevel == LogSeverity.Debug) { Logger.Debug($"PRESENCE_UPDATE: {user}"); } var before = Config.EnablePreUpdateEvents ? user.Clone() : null; user.Update(data); OnUserUpdated(before, 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) as ITextChannel; if (channel != null) { User user = (channel as Channel).GetUser(data.UserId); if (user != null) { if (Config.LogLevel == LogSeverity.Debug) { Logger.Debug($"TYPING_START: {user.ToString(channel)}"); } OnUserIsTypingUpdated(channel, user); user.UpdateActivity(); } } } 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) { if (Config.LogLevel == LogSeverity.Debug) { Logger.Debug($"VOICE_STATE_UPDATE: {user}"); } var before = Config.EnablePreUpdateEvents ? user.Clone() : null; user.Update(data); //Logger.Verbose($"Voice Updated: {server.Name}/{user.Name}"); OnUserUpdated(before, 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) { var before = Config.EnablePreUpdateEvents ? CurrentUser.Clone() : null; CurrentUser.Update(data); PrivateUser.Update(data); foreach (var server in _servers) { server.Value.CurrentUser.Update(data); } Logger.Info($"USER_UPDATE"); OnProfileUpdated(before, CurrentUser); } } break; //Handled in GatewaySocket case "RESUMED": break; //Ignored case "USER_SETTINGS_UPDATE": case "GUILD_INTEGRATIONS_UPDATE": case "VOICE_SERVER_UPDATE": case "GUILD_EMOJIS_UPDATE": case "MESSAGE_ACK": Logger.Debug($"{e.Type} [Ignored]"); break; //Others default: Logger.Warning($"Unknown message type: {e.Type}"); break; } } catch (Exception ex) { Logger.Error($"Error handling {e.Type} event", ex); } }
private async Task<Channel> CreatePMChannel(User user, string userId) { CheckReady(); if (userId == null) throw new ArgumentNullException(nameof(userId)); Channel channel = null; if (user != null) channel = user.PrivateChannel; if (channel == null) { var response = await _api.CreatePMChannel(CurrentUserId, userId).ConfigureAwait(false); user = _users.GetOrAdd(response.Recipient?.Id); user.Update(response.Recipient); channel = _channels.GetOrAdd(response.Id, response.GuildId, response.Recipient?.Id); channel.Update(response); } return channel; }