/// <summary> /// Please see <seealso cref="IEncodeMessageService{T}.Encode" /> for documentation. /// </summary> /// <param name="feedDeleteParameters">-</param> /// <returns>-</returns> public EncodedMessage Encode(FeedDeleteParameters feedDeleteParameters) { var messageHeaderParameters = new MessageHeaderParameters { ApplicationMessageId = feedDeleteParameters.ApplicationMessageId, TeamSetContextId = feedDeleteParameters.TeamsetContextId ?? "", TechnicalMessageType = TechnicalMessageTypes.DkeFeedConfirm, Mode = RequestEnvelope.Types.Mode.Direct }; var messagePayloadParameters = new MessagePayloadParameters { TypeUrl = MessageDelete.Descriptor.FullName }; var messageDelete = new MessageDelete(); feedDeleteParameters.Senders?.ForEach(sender => messageDelete.Senders.Add(sender)); feedDeleteParameters.MessageIds?.ForEach(messageId => messageDelete.MessageIds.Add(messageId)); feedDeleteParameters.ValidityPeriod = feedDeleteParameters.ValidityPeriod; messagePayloadParameters.Value = messageDelete.ToByteString(); var encodedMessage = new EncodedMessage { Id = Guid.NewGuid().ToString(), Content = EncodeMessageService.Encode(messageHeaderParameters, messagePayloadParameters) }; return(encodedMessage); }
public async void OnMessageDelete(IGatewayClient gatewayClient, Message message) { Channel channel = await Channels.Find(message.ChannelId); if (channel is TextChannel textChannel) { Message messgeCached = await textChannel.Messages.Find(message.Id); if (messgeCached != null) { message = messgeCached; } } MessageDelete?.Invoke(this, new ClientArgs <Message> { Data = message, GatewayClient = gatewayClient }); }
public void SocketMessage(object sender, MessageEventArgs e) { RPayload payload = JsonConvert.DeserializeObject <RPayload>(e.Data); if (payload.Sequence.HasValue) { client.Sequence = payload.Sequence.Value; } if (client.Settings.Debugging) { Interface.Oxide.LogDebug($"Recieved socket message, OpCode: {payload.OpCode}"); } switch (payload.OpCode) { // Dispatch (dispatches an event) case OpCodes.Dispatch: { if (client.Settings.Debugging) { Interface.Oxide.LogDebug($"Recieved OpCode 0, event: {payload.EventName}"); } // Listed here: https://discordapp.com/developers/docs/topics/gateway#commands-and-events-gateway-events switch (payload.EventName) { case "READY": { /* * Moved to DiscordClient.Initialized -> Not at all cases will READY be called. * client.UpdatePluginReference(); * client.CallHook("DiscordSocket_Initialized"); */ Ready ready = payload.EventData.ToObject <Ready>(); if (ready.Guilds.Count != 0) { Interface.Oxide.LogWarning($"[Discord Extension] Your bot was found in {ready.Guilds.Count} Guilds!"); } if (ready.Guilds.Count == 0 && client.Settings.Debugging) { Interface.Oxide.LogDebug($"[Discord Extension] Ready event but no Guilds sent."); } client.DiscordServers = ready.Guilds; client.SessionID = ready.SessionID; client.CallHook("Discord_Ready", null, ready); break; } case "RESUMED": { Resumed resumed = payload.EventData.ToObject <Resumed>(); Interface.Oxide.LogWarning("[Discord Extension] Session resumed!"); client.CallHook("Discord_Resumed", null, resumed); break; } case "CHANNEL_CREATE": { Channel channelCreate = payload.EventData.ToObject <Channel>(); if (channelCreate.type == ChannelType.DM || channelCreate.type == ChannelType.GROUP_DM) { client.DMs.Add(channelCreate); } else { client.GetGuild(channelCreate.guild_id).channels.Add(channelCreate); } client.CallHook("Discord_ChannelCreate", null, channelCreate); break; } case "CHANNEL_UPDATE": { Channel channelUpdated = payload.EventData.ToObject <Channel>(); Channel channelPrevious = (channelUpdated.type == ChannelType.DM || channelUpdated.type == ChannelType.GROUP_DM) ? client.DMs?.FirstOrDefault(x => x.id == channelUpdated.id) : client.GetGuild(channelUpdated.guild_id).channels.FirstOrDefault(x => x.id == channelUpdated.id); if (channelPrevious != null) { if (channelUpdated.type == ChannelType.DM || channelUpdated.type == ChannelType.GROUP_DM) { client.DMs.Remove(channelPrevious); } else { client.GetGuild(channelUpdated.guild_id).channels.Remove(channelPrevious); } } if (channelUpdated.type == ChannelType.DM || channelUpdated.type == ChannelType.GROUP_DM) { client.DMs.Add(channelUpdated); } else { client.GetGuild(channelUpdated.guild_id).channels.Add(channelUpdated); } client.CallHook("Discord_ChannelUpdate", null, channelUpdated, channelPrevious); break; } case "CHANNEL_DELETE": { Channel channelDelete = payload.EventData.ToObject <Channel>(); client.GetGuild(channelDelete.guild_id).channels.Remove(channelDelete); client.CallHook("Discord_ChannelDelete", null, channelDelete); break; } case "CHANNEL_PINS_UPDATE": { ChannelPinsUpdate channelPinsUpdate = payload.EventData.ToObject <ChannelPinsUpdate>(); client.CallHook("Discord_ChannelPinsUpdate", null, channelPinsUpdate); break; } // NOTE: Some elements of Guild object is only sent with GUILD_CREATE case "GUILD_CREATE": { Guild guildCreate = payload.EventData.ToObject <Guild>(); string g_id = guildCreate.id; bool g_unavail = guildCreate.unavailable ?? false; if (client.GetGuild(g_id) == null) { client.DiscordServers.Add(guildCreate); if (client.Settings.Debugging) { Interface.Oxide.LogDebug($"[Discord Extension] Guild ID ({g_id}) added to list."); } } else if (g_unavail == false && (client.GetGuild(g_id)?.unavailable ?? false) == true) { client.UpdateGuild(g_id, guildCreate); if (client.Settings.Debugging) { Interface.Oxide.LogDebug($"[Discord Extension] Guild ID ({g_id}) updated to list."); } } client.CallHook("Discord_GuildCreate", null, guildCreate); break; } case "GUILD_UPDATE": { Guild guildUpdate = payload.EventData.ToObject <Guild>(); //client.UpdateGuild(guildUpdate.id, guildUpdate); // <-- DON'T REPLACE GUILD REFERENCE!!!! client.GetGuild(guildUpdate.id).Update(guildUpdate); client.CallHook("Discord_GuildUpdate", null, guildUpdate); break; } case "GUILD_DELETE": { Guild guildDelete = payload.EventData.ToObject <Guild>(); if (guildDelete.unavailable ?? false == true) // outage { Interface.Oxide.LogDebug($"[DEBUG] Guild ID {guildDelete.id} outage!"); client.UpdateGuild(guildDelete.id, guildDelete); } else { Interface.Oxide.LogDebug($"[DEBUG] Guild ID {guildDelete.id} removed from list"); client.DiscordServers.Remove(client.GetGuild(guildDelete.id)); // guildDelete may not be same reference } client.CallHook("Discord_GuildDelete", null, guildDelete); break; } case "GUILD_BAN_ADD": { User bannedUser = payload.EventData.ToObject <BanObject>().user; client.CallHook("Discord_GuildBanAdd", null, bannedUser); break; } case "GUILD_BAN_REMOVE": { User unbannedUser = payload.EventData.ToObject <BanObject>().user; client.CallHook("Discord_GuildBanRemove", null, unbannedUser); break; } case "GUILD_EMOJIS_UPDATE": { GuildEmojisUpdate guildEmojisUpdate = payload.EventData.ToObject <GuildEmojisUpdate>(); client.CallHook("Discord_GuildEmojisUpdate", null, guildEmojisUpdate); break; } case "GUILD_INTEGRATIONS_UPDATE": { GuildIntergrationsUpdate guildIntergrationsUpdate = payload.EventData.ToObject <GuildIntergrationsUpdate>(); client.CallHook("Discord_GuildIntergrationsUpdate", null, guildIntergrationsUpdate); break; } case "GUILD_MEMBER_ADD": { GuildMemberAdd memberAdded = payload.EventData.ToObject <GuildMemberAdd>(); GuildMember guildMember = memberAdded as GuildMember; client.GetGuild(memberAdded.guild_id)?.members.Add(guildMember); client.CallHook("Discord_MemberAdded", null, guildMember); break; } case "GUILD_MEMBER_REMOVE": { GuildMemberRemove memberRemoved = payload.EventData.ToObject <GuildMemberRemove>(); GuildMember member = client.GetGuild(memberRemoved.guild_id)?.members.FirstOrDefault(x => x.user.id == memberRemoved.user.id); if (member != null) { client.GetGuild(memberRemoved.guild_id)?.members.Remove(member); } client.CallHook("Discord_MemberRemoved", null, member); break; } case "GUILD_MEMBER_UPDATE": { GuildMemberUpdate memberUpdated = payload.EventData.ToObject <GuildMemberUpdate>(); GuildMember newMember = client.GetGuild(memberUpdated.guild_id)?.members.FirstOrDefault(x => x.user.id == memberUpdated.user.id); GuildMember oldMember = Newtonsoft.Json.Linq.JObject.FromObject(newMember).ToObject <GuildMember>(); // lazy way to copy the object if (newMember != null) { if (memberUpdated.user != null) { newMember.user = memberUpdated.user; } if (memberUpdated.nick != null) { newMember.nick = memberUpdated.nick; } if (memberUpdated.roles != null) { newMember.roles = memberUpdated.roles; } } client.CallHook("Discord_GuildMemberUpdate", null, memberUpdated, oldMember); break; } case "GUILD_MEMBERS_CHUNK": { GuildMembersChunk guildMembersChunk = payload.EventData.ToObject <GuildMembersChunk>(); client.CallHook("Discord_GuildMembersChunk", null, guildMembersChunk); break; } case "GUILD_ROLE_CREATE": { GuildRoleCreate guildRoleCreate = payload.EventData.ToObject <GuildRoleCreate>(); client.GetGuild(guildRoleCreate.guild_id)?.roles.Add(guildRoleCreate.role); client.CallHook("Discord_GuildRoleCreate", null, guildRoleCreate.role); break; } case "GUILD_ROLE_UPDATE": { GuildRoleUpdate guildRoleUpdate = payload.EventData.ToObject <GuildRoleUpdate>(); Role newRole = guildRoleUpdate.role; Role oldRole = client.GetGuild(guildRoleUpdate.guild_id).roles.FirstOrDefault(x => x.id == newRole.id); if (oldRole != null) { client.GetGuild(guildRoleUpdate.guild_id).roles.Remove(oldRole); } client.GetGuild(guildRoleUpdate.guild_id).roles.Add(newRole); client.CallHook("Discord_GuildRoleUpdate", null, newRole, oldRole); break; } case "GUILD_ROLE_DELETE": { GuildRoleDelete guildRoleDelete = payload.EventData.ToObject <GuildRoleDelete>(); Role deletedRole = client.GetGuild(guildRoleDelete.guild_id)?.roles.FirstOrDefault(x => x.id == guildRoleDelete.role_id); if (deletedRole != null) { client.GetGuild(guildRoleDelete.guild_id).roles.Remove(deletedRole); } client.CallHook("Discord_GuildRoleDelete", null, deletedRole); break; } case "MESSAGE_CREATE": { Message messageCreate = payload.EventData.ToObject <Message>(); Channel c; if (messageCreate.guild_id != null) { c = client.GetGuild(messageCreate.guild_id)?.channels.FirstOrDefault(x => x.id == messageCreate.channel_id); } else { c = client.DMs.FirstOrDefault(x => x.id == messageCreate.channel_id); } if (c != null) { c.last_message_id = messageCreate.id; } client.CallHook("Discord_MessageCreate", null, messageCreate); break; } case "MESSAGE_UPDATE": { Message messageUpdate = payload.EventData.ToObject <Message>(); client.CallHook("Discord_MessageUpdate", null, messageUpdate); break; } case "MESSAGE_DELETE": { MessageDelete messageDelete = payload.EventData.ToObject <MessageDelete>(); client.CallHook("Discord_MessageDelete", null, messageDelete); break; } case "MESSAGE_DELETE_BULK": { MessageDeleteBulk messageDeleteBulk = payload.EventData.ToObject <MessageDeleteBulk>(); client.CallHook("Discord_MessageDeleteBulk", null, messageDeleteBulk); break; } case "MESSAGE_REACTION_ADD": { MessageReactionUpdate messageReactionAdd = payload.EventData.ToObject <MessageReactionUpdate>(); client.CallHook("Discord_MessageReactionAdd", null, messageReactionAdd); break; } case "MESSAGE_REACTION_REMOVE": { MessageReactionUpdate messageReactionRemove = payload.EventData.ToObject <MessageReactionUpdate>(); client.CallHook("Discord_MessageReactionRemove", null, messageReactionRemove); break; } case "MESSAGE_REACTION_REMOVE_ALL": { MessageReactionRemoveAll messageReactionRemoveAll = payload.EventData.ToObject <MessageReactionRemoveAll>(); client.CallHook("Discord_MessageReactionRemoveAll", null, messageReactionRemoveAll); break; } /* * From Discord API docs: * The user object within this event can be partial, the only field which must be sent is the id field, everything else is optional. * Along with this limitation, no fields are required, and the types of the fields are not validated. * Your client should expect any combination of fields and types within this event. */ case "PRESENCE_UPDATE": { PresenceUpdate presenceUpdate = payload.EventData.ToObject <PresenceUpdate>(); User updatedPresence = presenceUpdate?.user; if (updatedPresence != null) { var updatedMember = client.GetGuild(presenceUpdate.guild_id)?.members.FirstOrDefault(x => x.user.id == updatedPresence.id); if (updatedMember != null) { //updatedMember.user = updatedPresence; updatedMember.user.Update(updatedPresence); } } client.CallHook("Discord_PresenceUpdate", null, updatedPresence); break; } // Bots should ignore this case "PRESENCES_REPLACE": break; case "TYPING_START": { TypingStart typingStart = payload.EventData.ToObject <TypingStart>(); client.CallHook("Discord_TypingStart", null, typingStart); break; } case "USER_UPDATE": { User userUpdate = payload.EventData.ToObject <User>(); //GuildMember memberUpdate = client.DiscordServer.members.FirstOrDefault(x => x.user.id == userUpdate.id); //memberUpdate.user = userUpdate; var guilds = client.DiscordServers.Where(x => x.members.FirstOrDefault(y => y.user.id == userUpdate.id) != null).ToList(); foreach (Guild g in guilds) { GuildMember memberUpdate = g.members.FirstOrDefault(x => x.user.id == userUpdate.id); memberUpdate.user = userUpdate; } client.CallHook("Discord_UserUpdate", null, userUpdate); break; } case "VOICE_STATE_UPDATE": { VoiceState voiceStateUpdate = payload.EventData.ToObject <VoiceState>(); client.CallHook("Discord_VoiceStateUpdate", null, voiceStateUpdate); break; } case "VOICE_SERVER_UPDATE": { VoiceServerUpdate voiceServerUpdate = payload.EventData.ToObject <VoiceServerUpdate>(); client.CallHook("Discord_VoiceServerUpdate", null, voiceServerUpdate); break; } case "WEBHOOKS_UPDATE": { WebhooksUpdate webhooksUpdate = payload.EventData.ToObject <WebhooksUpdate>(); client.CallHook("Discord_WebhooksUpdate", null, webhooksUpdate); break; } default: { client.CallHook("Discord_UnhandledEvent", null, payload); Interface.Oxide.LogWarning($"[Discord Extension] [Debug] Unhandled event: {payload.EventName}"); break; } } break; } // Heartbeat // https://discordapp.com/developers/docs/topics/gateway#gateway-heartbeat case OpCodes.Heartbeat: { Interface.Oxide.LogInfo($"[Discord Extension] Manully sent heartbeat (received opcode 1)"); client.SendHeartbeat(); break; } // Reconnect (used to tell clients to reconnect to the gateway) // we should immediately reconnect here case OpCodes.Reconnect: { Interface.Oxide.LogInfo($"[Discord Extension] Reconnect has been called (opcode 7)! Reconnecting..."); webSocket.hasConnectedOnce = true; // attempt resume opcode webSocket.Connect(client.WSSURL); break; } // Invalid Session (used to notify client they have an invalid session ID) case OpCodes.InvalidSession: { Interface.Oxide.LogInfo($"[Discord Extension] Invalid Session ID opcode recieved!"); client.requestReconnect = true; webSocket.hasConnectedOnce = false; webSocket.Disconnect(false); break; } // Hello (sent immediately after connecting, contains heartbeat and server debug information) case OpCodes.Hello: { Hello hello = payload.EventData.ToObject <Hello>(); client.CreateHeartbeat(hello.HeartbeatInterval); // Client should now perform identification //client.Identify(); if (webSocket.hasConnectedOnce) { Interface.Oxide.LogWarning("[Discord Extension] Attempting resume opcode..."); client.Resume(); } else { client.Identify(); webSocket.hasConnectedOnce = true; } break; } // Heartbeat ACK (sent immediately following a client heartbeat // that was received) // (See 'zombied or failed connections') case OpCodes.HeartbeatACK: { client.HeartbeatACK = true; break; } default: { Interface.Oxide.LogInfo($"[Discord Extension] Unhandled OP code: code {payload.OpCode}"); break; } } }
public async Task HandleMessage(DiscordSocketClient discordSocketClient, SocketMessage message, Logger _logger, Program program) { if (message.Author.Username == "BeatSaber Bot") { return; } MessageDelete.DeleteMessageCheck(message, discordSocketClient); if (message.Content.Length <= 3) { return; } if (message.Content.Substring(0, 3).Contains("!bs")) { var messageCommand = message.Content.ToLower(); var typingState = message.Channel.EnterTypingState(new RequestOptions { Timeout = GlobalConfiguration.TypingTimeOut, }); Console.WriteLine(message.Content); if (messageCommand.Contains(" help")) { GenericCommands.Help(discordSocketClient, message); } else if (messageCommand.Contains(" rolecolor")) { DutchServerCommands.RoleColor(discordSocketClient, message); } else if (messageCommand.Contains(" topsong")) { GlobalScoresaberCommands.NewTopSong(discordSocketClient, message); } else if (messageCommand.Contains(" search")) { GlobalScoresaberCommands.NewSearch(discordSocketClient, message); } else if (messageCommand.Contains(" updateroles")) { DutchServerCommands.UpdateRoles(discordSocketClient, message); } else if (messageCommand.Contains(" linkednames")) { DutchServerCommands.LinkedNames(discordSocketClient, message); } else if (messageCommand.Contains(" notlinkednames")) { DutchServerCommands.NotLinkedNames(discordSocketClient, message); } else if (messageCommand.Contains(" recentsong")) { GlobalScoresaberCommands.NewRecentSong(discordSocketClient, message); } else if (messageCommand.Contains(" changecolor")) { DutchServerCommands.ChangeColor(discordSocketClient, message); } else if (messageCommand.Contains(" playing")) { GenericCommands.Playing(discordSocketClient, message); } else if (messageCommand.Contains(" invite")) { GenericCommands.Invite(discordSocketClient, message); } else if (messageCommand.Contains(" poll")) { GenericCommands.Poll(discordSocketClient, message); } else if (messageCommand.Contains(" compare")) { GlobalScoresaberCommands.Compare(discordSocketClient, message); } else if (messageCommand.Contains(" unlink")) { DutchServerCommands.LinkScoresaberWithDiscord(discordSocketClient, message); } else if (messageCommand.Contains(" link")) { DutchServerCommands.LinkScoresaberWithDiscord(discordSocketClient, message); } else if (messageCommand.Contains(" typing")) { GlobalScoresaberCommands.Typing(discordSocketClient, message); message.DeleteAsync(); } else if (messageCommand.Contains(" ranks")) { var builderList = await BeatSaberInfoExtension.GetRanks(); foreach (var builder in builderList) { await message.Channel.SendMessageAsync("", false, builder.Build()); } } else if (messageCommand.Contains(" senddm")) { GenericCommands.SendDM(discordSocketClient, message); } else if (messageCommand.Contains(" approvedutchuser")) { var guildUserSender = message.Author as SocketGuildUser; if (guildUserSender.IsDutchAdmin()) { var userId = message.Content.Substring(21).Replace("<@!", "").Replace(">", "").Trim(); var user = discordSocketClient.GetUser(ulong.Parse(userId)); var guildService = new GuildService(discordSocketClient, 505485680344956928); await guildService.AddRole("Koos Rankloos", user); await program.UserJoinedMessage(user); } await message.DeleteAsync(); } else if (messageCommand.Contains(" songs")) { await message.Channel.SendMessageAsync(null, false, EmbedBuilderExtension.NullEmbed("Ewh..", "This command is outdated. Blame silverhaze to remake it").Build()); //GlobalScoresaberCommands.Songs(discordSocketClient, message); } else if (messageCommand.Contains(" irlevent create")) { DutchServerCommands.IRLevent(discordSocketClient, message); } else if (messageCommand.Contains(" randomevent create")) { DutchServerCommands.RandomEvent(discordSocketClient, message); } else { var embedBuilder = EmbedBuilderExtension.NullEmbed("Oops", "There is no command like that, try something else", null, null); await message.Channel.SendMessageAsync(null, false, embedBuilder.Build()); } typingState.Dispose(); } }
public void SocketMessage(object sender, MessageEventArgs e) { RPayload payload = JsonConvert.DeserializeObject <RPayload>(e.Data); if (payload.Sequence.HasValue) { client.Sequence = payload.Sequence.Value; } if (client.Settings.Debugging) { Interface.Oxide.LogDebug($"Recieved socket message, OpCode: {payload.OpCode}"); } switch (payload.OpCode) { // Dispatch (dispatches an event) case OpCodes.Dispatch: { if (client.Settings.Debugging) { Interface.Oxide.LogDebug($"Recieved OpCode 0, event: {payload.EventName}"); } // Listed here: https://discordapp.com/developers/docs/topics/gateway#commands-and-events-gateway-events switch (payload.EventName) { case "READY": { client.UpdatePluginReference(); client.CallHook("DiscordSocket_Initialized"); Ready ready = payload.EventData.ToObject <Ready>(); if (ready.Guilds.Count > 1) { Interface.Oxide.LogWarning($"[Oxide.Ext.Discord] Your bot was found in more than one Guild. Multiple guilds are not supported by this extension."); } if (ready.Guilds.Count == 0 && client.Settings.Debugging) { Interface.Oxide.LogDebug($"Ready event but no Guilds sent."); } client.DiscordServer = ready.Guilds.FirstOrDefault(); client.SessionID = ready.SessionID; client.CallHook("Discord_Ready", null, ready); break; } case "RESUMED": { Resumed resumed = payload.EventData.ToObject <Resumed>(); client.CallHook("Discord_Resumed", null, resumed); break; } case "CHANNEL_CREATE": { Channel channelCreate = payload.EventData.ToObject <Channel>(); client.DiscordServer.channels.Add(channelCreate); client.CallHook("Discord_ChannelCreate", null, channelCreate); break; } case "CHANNEL_UPDATE": { Channel channelUpdated = payload.EventData.ToObject <Channel>(); Channel channelPrevious = client.DiscordServer.channels.FirstOrDefault(x => x.id == channelUpdated.id); if (channelPrevious != null) { client.DiscordServer.channels.Remove(channelPrevious); } client.DiscordServer.channels.Add(channelUpdated); client.CallHook("Discord_ChannelUpdate", null, channelUpdated, channelPrevious); break; } case "CHANNEL_DELETE": { Channel channelDelete = payload.EventData.ToObject <Channel>(); client.DiscordServer.channels.Remove(channelDelete); client.CallHook("Discord_ChannelDelete", null, channelDelete); break; } case "CHANNEL_PINS_UPDATE": { ChannelPinsUpdate channelPinsUpdate = payload.EventData.ToObject <ChannelPinsUpdate>(); client.CallHook("Discord_ChannelPinsUpdate", null, channelPinsUpdate); break; } // this isn't set up right // https://discordapp.com/developers/docs/topics/gateway#guild-create case "GUILD_CREATE": { Guild guildCreate = payload.EventData.ToObject <Guild>(); client.DiscordServer = guildCreate; client.CallHook("Discord_GuildCreate", null, guildCreate); break; } case "GUILD_UPDATE": { Guild guildUpdate = payload.EventData.ToObject <Guild>(); client.CallHook("Discord_GuildUpdate", null, guildUpdate); break; } case "GUILD_DELETE": { Guild guildDelete = payload.EventData.ToObject <Guild>(); client.CallHook("Discord_GuildDelete", null, guildDelete); break; } case "GUILD_BAN_ADD": { User bannedUser = payload.EventData.ToObject <BanObject>().user; client.CallHook("Discord_GuildBanAdd", null, bannedUser); break; } case "GUILD_BAN_REMOVE": { User unbannedUser = payload.EventData.ToObject <BanObject>().user; client.CallHook("Discord_GuildBanRemove", null, unbannedUser); break; } case "GUILD_EMOJIS_UPDATE": { GuildEmojisUpdate guildEmojisUpdate = payload.EventData.ToObject <GuildEmojisUpdate>(); client.CallHook("Discord_GuildEmojisUpdate", null, guildEmojisUpdate); break; } case "GUILD_INTEGRATIONS_UPDATE": { GuildIntergrationsUpdate guildIntergrationsUpdate = payload.EventData.ToObject <GuildIntergrationsUpdate>(); client.CallHook("Discord_GuildIntergrationsUpdate", null, guildIntergrationsUpdate); break; } case "GUILD_MEMBER_ADD": { GuildMemberAdd memberAdded = payload.EventData.ToObject <GuildMemberAdd>(); GuildMember guildMember = memberAdded as GuildMember; client.DiscordServer.members.Add(guildMember); client.CallHook("Discord_MemberAdded", null, guildMember); break; } case "GUILD_MEMBER_REMOVE": { GuildMemberRemove memberRemoved = payload.EventData.ToObject <GuildMemberRemove>(); GuildMember member = client.DiscordServer.members.FirstOrDefault(x => x.user.id == memberRemoved.user.id); if (member != null) { client.DiscordServer.members.Remove(member); } client.CallHook("Discord_MemberRemoved", null, member); break; } case "GUILD_MEMBER_UPDATE": { GuildMemberUpdate memberUpdated = payload.EventData.ToObject <GuildMemberUpdate>(); GuildMember oldMember = client.DiscordServer.members.FirstOrDefault(x => x.user.id == memberUpdated.user.id); if (oldMember != null) { client.DiscordServer.members.Remove(oldMember); } client.CallHook("Discord_GuildMemberUpdate", null, memberUpdated, oldMember); break; } case "GUILD_MEMBERS_CHUNK": { GuildMembersChunk guildMembersChunk = payload.EventData.ToObject <GuildMembersChunk>(); client.CallHook("Discord_GuildMembersChunk", null, guildMembersChunk); break; } case "GUILD_ROLE_CREATE": { GuildRoleCreate guildRoleCreate = payload.EventData.ToObject <GuildRoleCreate>(); client.DiscordServer.roles.Add(guildRoleCreate.role); client.CallHook("Discord_GuildRoleCreate", null, guildRoleCreate.role); break; } case "GUILD_ROLE_UPDATE": { GuildRoleUpdate guildRoleUpdate = payload.EventData.ToObject <GuildRoleUpdate>(); Role newRole = guildRoleUpdate.role; Role oldRole = client.DiscordServer.roles.FirstOrDefault(x => x.id == newRole.id); if (oldRole != null) { client.DiscordServer.roles.Remove(oldRole); } client.DiscordServer.roles.Add(newRole); client.CallHook("Discord_GuildRoleUpdate", null, newRole, oldRole); break; } case "GUILD_ROLE_DELETE": { GuildRoleDelete guildRoleDelete = payload.EventData.ToObject <GuildRoleDelete>(); Role deletedRole = client.DiscordServer.roles.FirstOrDefault(x => x.id == guildRoleDelete.role_id); if (deletedRole != null) { client.DiscordServer.roles.Remove(deletedRole); } client.CallHook("Discord_GuildRoleDelete", null, deletedRole); break; } case "MESSAGE_CREATE": { Message messageCreate = payload.EventData.ToObject <Message>(); client.CallHook("Discord_MessageCreate", null, messageCreate); break; } case "MESSAGE_UPDATE": { Message messageUpdate = payload.EventData.ToObject <Message>(); client.CallHook("Discord_MessageUpdate", null, messageUpdate); break; } case "MESSAGE_DELETE": { MessageDelete messageDelete = payload.EventData.ToObject <MessageDelete>(); client.CallHook("Discord_MessageDelete", null, messageDelete); break; } case "MESSAGE_DELETE_BULK": { MessageDeleteBulk messageDeleteBulk = payload.EventData.ToObject <MessageDeleteBulk>(); client.CallHook("Discord_MessageDeleteBulk", null, messageDeleteBulk); break; } case "MESSAGE_REACTION_ADD": { MessageReactionUpdate messageReactionAdd = payload.EventData.ToObject <MessageReactionUpdate>(); client.CallHook("Discord_MessageReactionAdd", null, messageReactionAdd); break; } case "MESSAGE_REACTION_REMOVE": { MessageReactionUpdate messageReactionRemove = payload.EventData.ToObject <MessageReactionUpdate>(); client.CallHook("Discord_MessageReactionRemove", null, messageReactionRemove); break; } case "MESSAGE_REACTION_REMOVE_ALL": { MessageReactionRemoveAll messageReactionRemoveAll = payload.EventData.ToObject <MessageReactionRemoveAll>(); client.CallHook("Discord_MessageReactionRemoveAll", null, messageReactionRemoveAll); break; } case "PRESENCE_UPDATE": { PresenceUpdate presenceUpdate = payload.EventData.ToObject <PresenceUpdate>(); User updatedPresence = presenceUpdate?.user; if (updatedPresence != null) { var updatedMember = client.DiscordServer.members.FirstOrDefault(x => x.user.id == updatedPresence.id); if (updatedMember != null) { updatedMember.user = updatedPresence; } } client.CallHook("Discord_PresenceUpdate", null, updatedPresence); break; } case "TYPING_START": { TypingStart typingStart = payload.EventData.ToObject <TypingStart>(); client.CallHook("Discord_TypingStart", null, typingStart); break; } case "USER_UPDATE": { User userUpdate = payload.EventData.ToObject <User>(); GuildMember memberUpdate = client.DiscordServer.members.FirstOrDefault(x => x.user.id == userUpdate.id); memberUpdate.user = userUpdate; client.CallHook("Discord_UserUpdate", null, userUpdate); break; } case "VOICE_STATE_UPDATE": { VoiceState voiceStateUpdate = payload.EventData.ToObject <VoiceState>(); client.CallHook("Discord_VoiceStateUpdate", null, voiceStateUpdate); break; } case "VOICE_SERVER_UPDATE": { VoiceServerUpdate voiceServerUpdate = payload.EventData.ToObject <VoiceServerUpdate>(); client.CallHook("Discord_VoiceServerUpdate", null, voiceServerUpdate); break; } case "WEBHOOKS_UPDATE": { WebhooksUpdate webhooksUpdate = payload.EventData.ToObject <WebhooksUpdate>(); client.CallHook("Discord_WebhooksUpdate", null, webhooksUpdate); break; } default: { client.CallHook("Discord_UnhandledEvent", null, payload); Interface.Oxide.LogWarning($"[Discord Ext] [Debug] Unhandled event: {payload.EventName}"); break; } } break; } // Heartbeat // https://discordapp.com/developers/docs/topics/gateway#gateway-heartbeat case OpCodes.Heartbeat: { Interface.Oxide.LogInfo($"[DiscordExt] Manully sent heartbeat (received opcode 1)"); client.SendHeartbeat(); break; } // Reconnect (used to tell clients to reconnect to the gateway) // we should immediately reconnect here case OpCodes.Reconnect: { Interface.Oxide.LogInfo($"[DiscordExt] Reconnect has been called (opcode 7)! Reconnecting..."); webSocket.Connect(client.WSSURL); break; } // Invalid Session (used to notify client they have an invalid session ID) case OpCodes.InvalidSession: { Interface.Oxide.LogInfo($"[DiscordExt] Invalid Session ID opcode recieved!"); break; } // Hello (sent immediately after connecting, contains heartbeat and server debug information) case OpCodes.Hello: { Hello hello = payload.EventData.ToObject <Hello>(); client.CreateHeartbeat(hello.HeartbeatInterval); // Client should now perform identification client.Identify(); break; } // Heartbeat ACK (sent immediately following a client heartbeat // that was received) // This should be changed: https://discordapp.com/developers/docs/topics/gateway#heartbeating // (See 'zombied or failed connections') case OpCodes.HeartbeatACK: break; default: { Interface.Oxide.LogInfo($"[DiscordExt] Unhandled OP code: code {payload.OpCode}"); 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; } } }
private void HandleDispatchEvent(GatewayPayload evnt, TaskCompletionSource <bool> readySignal) { switch (evnt.DispatchType) { case GatewayDispatchType.Ready: var readyEvent = evnt.Data as ReadyEvent; SetSession(readyEvent.SessionId); readySignal.TrySetResult(true); Ready?.Invoke(readyEvent); break; case GatewayDispatchType.Resumed: readySignal.TrySetResult(true); Resumed?.Invoke(); break; case GatewayDispatchType.GuildCreate: GuildCreate?.Invoke(evnt.Data as GatewayGuild); break; case GatewayDispatchType.GuildUpdate: GuildUpdate?.Invoke(evnt.Data as Guild); break; case GatewayDispatchType.GuildDelete: GuildDelete?.Invoke(evnt.Data as UnavailableGuild); break; case GatewayDispatchType.ChannelCreate: ChannelCreate?.Invoke(evnt.Data as Channel); break; case GatewayDispatchType.ChannelUpdate: ChannelUpdate?.Invoke(evnt.Data as Channel); break; case GatewayDispatchType.ChannelDelete: ChannelDelete?.Invoke(evnt.Data as Channel); break; case GatewayDispatchType.ChannelPinsUpdate: ChannelPinsUpdate?.Invoke(evnt.Data as ChannelPinsUpdateEvent); break; case GatewayDispatchType.GuildMemberAdd: GuildMemberAdd?.Invoke(evnt.Data as GuildMemberAddEvent); break; case GatewayDispatchType.GuildMemberUpdate: GuildMemberUpdate?.Invoke(evnt.Data as GuildMemberUpdateEvent); break; case GatewayDispatchType.GuildMemberRemove: GuildMemberRemove?.Invoke(evnt.Data as GuildMemberRemoveEvent); break; case GatewayDispatchType.GuildMembersChunk: GuildMembersChunk?.Invoke(evnt.Data as GuildMembersChunkEvent); break; case GatewayDispatchType.GuildRoleCreate: GuildRoleCreate?.Invoke(evnt.Data as GuildRoleCreateEvent); break; case GatewayDispatchType.GuildRoleUpdate: GuildRoleUpdate?.Invoke(evnt.Data as GuildRoleUpdateEvent); break; case GatewayDispatchType.GuildRoleDelete: GuildRoleDelete?.Invoke(evnt.Data as GuildRoleDeleteEvent); break; case GatewayDispatchType.GuildBanAdd: GuildBanAdd?.Invoke(evnt.Data as GuildBanAddEvent); break; case GatewayDispatchType.GuildBanRemove: GuildBanRemove?.Invoke(evnt.Data as GuildBanRemoveEvent); break; case GatewayDispatchType.GuildEmojisUpdate: GuildEmojisUpdate?.Invoke(evnt.Data as GuildEmojiUpdateEvent); break; case GatewayDispatchType.GuildIntegrationsUpdate: GuildIntegrationsUpdate?.Invoke(evnt.Data as GuildIntegrationsUpdateEvent); break; case GatewayDispatchType.MessageCreate: MessageCreate?.Invoke(evnt.Data as Message); break; case GatewayDispatchType.MessageUpdate: MessageUpdate?.Invoke(evnt.Data as Message); break; case GatewayDispatchType.MessageDelete: MessageDelete?.Invoke(evnt.Data as MessageDeleteEvent); break; case GatewayDispatchType.MessageDeleteBulk: MessageDeleteBulk?.Invoke(evnt.Data as MessageDeleteBulkEvent); break; case GatewayDispatchType.MessageReactionAdd: MessageReactionAdd?.Invoke(evnt.Data as MessageReactionAddEvent); break; case GatewayDispatchType.MessageReactionRemove: MessageReactionRemove?.Invoke(evnt.Data as MessageReactionRemoveEvent); break; case GatewayDispatchType.MessageReactionRemoveAll: MessageReactionRemoveAll?.Invoke(evnt.Data as MessageReactionRemoveAllEvent); break; case GatewayDispatchType.PresenceUpdate: PresenceUpdate?.Invoke(evnt.Data as Presence); break; case GatewayDispatchType.UserUpdate: UserUpdate?.Invoke(evnt.Data as User); break; case GatewayDispatchType.TypingStart: TypingStart?.Invoke(evnt.Data as TypingStartEvent); break; case GatewayDispatchType.VoiceStateUpdate: VoiceStateUpdate?.Invoke(evnt.Data as VoiceState); break; case GatewayDispatchType.VoiceServerUpdate: VoiceServerUpdate?.Invoke(evnt.Data as VoiceServerUpdateEvent); break; case GatewayDispatchType.WebhooksUpdate: WebhooksUpdate?.Invoke(evnt.Data as WebhooksUpdateEvent); break; } }