void OnEvent(string eventname, int seq, JsonNode data) { sequence = seq; switch (eventname) { case "READY": gatewayversion = data.SelectValue <int>("v"); sessionid = data.SelectValue <string>("session_id"); OnConnected(); break; case "RESUMED": OnConnected(); break; case "INVALID_SESSION": Disconnect(1021, "Authentication failure", /*data.SelectValue<bool>("d")*/ false); break; case "CHANNEL_CREATE": ChannelCreated?.Invoke(JSON.Serializer.Read <Channel>(data)); break; case "CHANNEL_UPDATE": ChannelUpdated?.Invoke(JSON.Serializer.Read <Channel>(data)); break; case "CHANNEL_DELETE": ChannelDeleted?.Invoke(JSON.Serializer.Read <Channel>(data)); break; case "CHANNEL_PINS_UPDATED": ChannelPinUpdated?.Invoke(data.SelectValue <string>("channel_id")); break; case "MESSAGE_CREATE": MessageCreated?.Invoke(JSON.Serializer.Read <Message>(data)); break; case "MESSAGE_UPDATE": MessageUpdated?.Invoke(JSON.Serializer.Read <Message>(data)); break; case "MESSAGE_DELETE": MessageDeleted?.Invoke(data.SelectValue <string>("channel_id"), data.SelectValue <string>("id")); break; case "MESSAGE_DELETE_BULK": MessagesDeleted?.Invoke(data.SelectValue <string>("channel_id"), data.SelectValue <string[]>("ids")); break; case "GUILD_CREATE": GuildCreated?.Invoke(JSON.Serializer.Read <Guild>(data)); break; case "GUILD_UPDATE": GuildUpdated?.Invoke(JSON.Serializer.Read <Guild>(data)); break; case "GUILD_DELETE": GuildDeleted?.Invoke(JSON.Serializer.Read <UnavailableGuild>(data)); break; case "GUILD_BAN_ADD": UserBanned?.Invoke(JSON.Serializer.Read <GuildUser>(data)); break; case "GUILD_BAN_REMOVED": UserUnbanned?.Invoke(JSON.Serializer.Read <GuildUser>(data)); break; case "GUILD_EMOJIS_UPDATE": EmojisUpdated?.Invoke(data.SelectValue <string>("guild_id"), JSON.Serializer.Read <Emoji[]>(data["emojis"])); break; case "GUILD_INTEGRATIONS_UPDATE": GuildIntegrationsUpdated?.Invoke(data.SelectValue <string>("guild_id")); break; case "GUILD_MEMBER_ADD": GuildMemberAdded?.Invoke(data.SelectValue <string>("guild_id"), JSON.Serializer.Read <GuildMember>(data)); break; case "GUILD_MEMBER_REMOVE": GuildMemberRemoved?.Invoke(data.SelectValue <string>("guild_id"), JSON.Serializer.Read <User>(data)); break; case "GUILD_MEMBER_UPDATE": GuildMemberUpdated?.Invoke(data.SelectValue <string>("guild_id"), JSON.Serializer.Read <Role[]>(data["roles"]), JSON.Serializer.Read <User>(data["user"]), data.SelectValue <string>("nick")); break; case "GUILD_MEMBERS_CHUNK": GuildMembersChunk?.Invoke(data.SelectValue <string>("guild_id"), JSON.Serializer.Read <GuildMember[]>(data["members"])); break; case "GUILD_ROLE_CREATE": GuildRoleCreated?.Invoke(data.SelectValue <string>("guild_id"), JSON.Serializer.Read <Role>(data["role"])); break; case "GUILD_ROLE_UPDATE": GuildRoleUpdated?.Invoke(data.SelectValue <string>("guild_id"), JSON.Serializer.Read <Role>(data["role"])); break; case "GUILD_ROLE_DELETE": GuildRoleDeleted?.Invoke(data.SelectValue <string>("guild_id"), data.SelectValue <string>("role_id")); break; case "MESSAGE_REACTION_ADD": MessageReactionAdded?.Invoke(data.SelectValue <string>("user_id"), data.SelectValue <string>("channel_id"), data.SelectValue <string>("message_id"), JSON.Serializer.Read <Emoji>(data["emoji"])); break; case "MESSAGE_REACTION_REMOVE": MessageReactionRemoved?.Invoke(data.SelectValue <string>("user_id"), data.SelectValue <string>("channel_id"), data.SelectValue <string>("message_id"), JSON.Serializer.Read <Emoji>(data["emoji"])); break; case "MESSAGE_REACTION_REMOVE_ALL": MessageReactionRemovedAll?.Invoke(data.SelectValue <string>("channel_id"), data.SelectValue <string>("message_id")); break; case "PRESENCE_UPDATE": PresenceUpdated?.Invoke(JSON.Serializer.Read <PresenceUpdate>(data)); break; case "TYPING_START": TypingStarted?.Invoke(data.SelectValue <string>("guild_id"), data.SelectValue <string>("user_id"), data.SelectValue <int>("timestamp").ToDateTime()); break; case "USER_UPDATE": UserUpdated?.Invoke(JSON.Serializer.Read <User>(data)); break; case "VOICE_STATE_UPDATE": VoiceStateUpdated?.Invoke(JSON.Serializer.Read <VoiceState>(data)); break; case "VOICE_SERVER_UPDATE": VoiceServerUpdated?.Invoke(data.SelectValue <string>("token"), data.SelectValue <string>("guild_id"), data.SelectValue <string>("endpoint")); break; case "WEBHOOKS_UPDATE": WebhooksUpdated?.Invoke(data.SelectValue <string>("guild_id"), data.SelectValue <string>("channel_id")); break; default: Logger.Warning(this, $"'{eventname}' event not handled", data.ToString()); break; } }
//TODO: Typing Start //TODO: Integrations //TODO: User Updates //TODO: Voice Chat private void GatewayMessageHandler(string eventName, string payload) { _Logger?.Debug($"{eventName} - {payload}"); var eventValue = (Events)Enum.Parse(typeof(Events), eventName); var eventPayload = JObject.Parse(payload); switch (eventValue) { case Events.READY: { var guilds = eventPayload["guilds"] as JArray; foreach (var guild in guilds) { var g = new Guild { Id = guild["id"].ToString(), Unavailable = guild["unavailable"].ToObject <bool>() }; Guilds.Add(g.Id, g); } break; } case Events.GUILD_CREATE: { Guild g = null; if (Guilds.ContainsKey(eventPayload["id"].ToString())) { g = Guilds[eventPayload["id"].ToString()]; } else { g = new Guild() { Id = eventPayload["id"].ToString() }; Guilds.Add(g.Id, g); } JsonConvert.PopulateObject(payload, g); foreach (var channel in g.Channels) { if (!Channels.ContainsKey(channel.Key)) { Channels.Add(channel.Key, channel.Value); } channel.Value.Guild_Id = g.Id; channel.Value.Guild = g; } foreach (var member in g.Members) { if (!Users.ContainsKey(member.Key)) { Users.Add(member.Key, member.Value.User); } else if (member.Value.User != Users[member.Key]) { member.Value.User = Users[member.Key]; } member.Value.Guild = g; } foreach (var presence in g.Presences.Values) { presence.User = Users[presence.User.Id]; } g.UpdateAllUserPermissions(); GuildCreated?.Invoke(g); break; } case Events.GUILD_UPDATE: { var g = Guilds[eventPayload["id"].ToString()]; // TODO: Double check that this is the correct behavior. JsonConvert.PopulateObject(payload, g); GuildUpdated?.Invoke(g); break; } case Events.GUILD_DELETE: { var g = Guilds[eventPayload["id"].ToString()]; Guilds.Remove(eventPayload["id"].ToString()); GuildDeleted?.Invoke(g); break; } case Events.CHANNEL_CREATE: { var c = eventPayload.ToObject <GuildChannel>(); var g = Guilds[c.Guild_Id]; c.Guild = g; g.Channels.Add(c.Id, c); Channels.Add(c.Id, c); ChannelCreate?.Invoke(g, c); break; } case Events.CHANNEL_UPDATE: { var g = Guilds[eventPayload["guild_id"].ToString()]; var c = g.Channels[eventPayload["id"].ToString()]; JsonConvert.PopulateObject(payload, c); ChannelUpdate?.Invoke(g, c); break; } case Events.CHANNEL_DELETE: { var g = Guilds[eventPayload["guild_id"].ToString()]; var c = g.Channels[eventPayload["id"].ToString()]; g.Channels.Remove(c.Id); Channels.Remove(c.Id); ChannelDelete?.Invoke(g, c); break; } case Events.GUILD_BAN_ADD: { // TODO: User knows about bans var g = Guilds[eventPayload["guild_id"].ToString()]; var m = g.Members[eventPayload["id"].ToString()]; Users[m.User.Id].Guilds.Remove(g); g.Members.Remove(m.User.Id); BanAdd?.Invoke(g, m.User); break; } case Events.GUILD_BAN_REMOVE: { var g = Guilds[eventPayload["guild_id"].ToString()]; BanRemove?.Invoke(g, eventPayload.ToObject <DiscordUser>()); break; } case Events.GUILD_EMOJIS_UPDATE: { var g = Guilds[eventPayload["guild_id"].ToString()]; g.Emojis.Clear(); JsonConvert.PopulateObject(payload, g); EmojiUpdate?.Invoke(g, eventPayload["emojis"].ToObject <List <Guild.Emoji> >()); break; } case Events.GUILD_MEMBER_ADD: { var g = Guilds[eventPayload["guild_id"].ToString()]; var m = eventPayload.ToObject <GuildMember>(); if (!Users.ContainsKey(m.User.Id)) { Users.Add(m.User.Id, m.User); } else { m.User = Users[m.User.Id]; } g.Members.Add(m.User.Id, m); m.User.Guilds.Add(g); m.Guild = g; g.UpdateUserPermission(m); MemberAdd?.Invoke(g, m); break; } case Events.GUILD_MEMBER_REMOVE: { var g = Guilds[eventPayload["guild_id"].ToString()]; var m = g.Members[eventPayload["user"]["id"].ToString()]; g.Members.Remove(m.User.Id); m.User.Guilds.Remove(g); MemberRemove?.Invoke(g, m); break; } case Events.GUILD_MEMBER_UPDATE: { var g = Guilds[eventPayload["guild_id"].ToString()]; var m = g.Members[eventPayload["user"]["id"].ToString()]; JsonConvert.PopulateObject(payload, m); g.UpdateUserPermission(m); MemberUpdate?.Invoke(g, m); break; } case Events.GUILD_MEMBERS_CHUNK: { var g = Guilds[eventPayload["guild_id"].ToString()]; var members = eventPayload["members"].ToObject <List <GuildMember> >(); foreach (var member in members) { if (Users.ContainsKey(member.User.Id)) { member.User = Users[member.User.Id]; } else { Users.Add(member.User.Id, member.User); } g.Members.Remove(member.User.Id); g.Members.Add(member.User.Id, member); } MemberChunkUpdate?.Invoke(g, members); break; } case Events.GUILD_ROLE_CREATE: { var g = Guilds[eventPayload["guild_id"].ToString()]; var r = eventPayload["role"].ToObject <Guild.Role>(); g.Roles.Add(r.Id, r); RoleCreate?.Invoke(g, r); break; } case Events.GUILD_ROLE_UPDATE: { var g = Guilds[eventPayload["guild_id"].ToString()]; var r = g.Roles[eventPayload["role"]["id"].ToString()]; JsonConvert.PopulateObject(eventPayload["role"].ToString(), r); RoleUpdate?.Invoke(g, r); break; } case Events.GUILD_ROLE_DELETE: { var g = Guilds[eventPayload["guild_id"].ToString()]; var r = g.Roles[eventPayload["role_id"].ToString()]; g.Roles.Remove(r.Id); RoleDelete?.Invoke(g, r); break; } case Events.MESSAGE_CREATE: { var message = eventPayload.ToObject <Message>(); var c = Channels[message.Channel_Id]; message.Channel = c; if (string.IsNullOrEmpty(message.Webhook_Id)) { if (Users.ContainsKey(message.Author.Id)) { message.Author = Users[message.Author.Id]; } } MessageCreate?.Invoke(c, message); break; } case Events.MESSAGE_UPDATE: { var message = eventPayload.ToObject <Message>(); var c = Channels[message.Channel_Id]; MessageUpdate?.Invoke(c, message); break; } case Events.MESSAGE_DELETE: { var message = eventPayload.ToObject <Message>(); var c = Channels[message.Channel_Id]; MessageDelete?.Invoke(c, message); break; } case Events.MESSAGE_DELETE_BULK: { var messages = eventPayload.ToObject <List <Message> >(); var c = Channels[eventPayload["channel_id"].ToString()]; MessagesBulkDelete?.Invoke(c, messages); break; } case Events.PRESENCE_UPDATE: { var presense = eventPayload.ToObject <Guild.Presence>(); var g = Guilds[eventPayload["guild_id"].ToString()]; if (g.Presences.ContainsKey(presense.User.Id)) { var p = g.Presences[presense.User.Id]; p.Game = presense.Game; p.Status = presense.Status; presense = p; } else { presense.User = Users[presense.User.Id]; g.Presences.Add(presense.User.Id, presense); } PresenceUpdate?.Invoke(g, presense); break; } } }