UNPKG

discord.js-light

Version:

All the power of discord.js, zero caching. This library modifies discord.js's internal classes and functions in order to give you full control over its caching behaviour.

824 lines (769 loc) 27.8 kB
"use strict"; const { Constants, Collection, Channel, DMChannel, ButtonInteraction, CommandInteraction, SelectMenuInteraction, UserContextMenuInteraction, MessageContextMenuInteraction, AutocompleteInteraction, Typing, LimitedCollection, ModalSubmitInteraction } = require("discord.js"); const { getOrCreateGuild, getOrCreateChannel, getOrCreateMessage, makePartial } = require("./functions"); module.exports = { // called by GuildChannelManager.create() ChannelCreate: function(data) { const c = this.client; const guild = data.guild_id ? getOrCreateGuild(c, data.guild_id, data.shardId) : void 0; const channel = c.channels._add(data, guild); return { channel }; }, ChannelDelete: function(data) { const c = this.client; const guild = data.guild_id ? getOrCreateGuild(c, data.guild_id, data.shardId) : void 0; const channel = c.channels.cache.get(data.id) || c.channels._add(data, guild); if(!channel) { return {}; } if(channel.messages?.cache.size && !(channel instanceof DMChannel)) { for(const message of channel.messages.cache.values()) { message.deleted = true; } } channel.deleted = true; c.channels._remove(channel.id); return { channel }; }, // called by GuildChannel.edit(), ThreadChannel.edit() ChannelUpdate: function(data) { const c = this.client; const guild = data.guild_id ? getOrCreateGuild(c, data.guild_id, data.shardId) : void 0; let channel = c.channels.cache.get(data.id); let old; if(channel) { old = channel._update(data); if(Constants.ChannelTypes[channel.type] !== data.type) { const changedChannel = Channel.create(c, data, guild); for(const [id, message] of channel.messages.cache) { changedChannel.messages.cache.forceSet(id, message); } channel = changedChannel; c.channels.cache.set(channel.id, channel); channel.guild?.channels.cache.set(channel.id, channel); } } else { channel = c.channels._add(data, guild); old = c.channels._add({ id: data.id, type: data.type }, guild, { cache: false, allowUnknownGuild: true }); if(old) { makePartial(old); } } return { old, updated: channel }; }, GuildBanAdd: function(data) { const c = this.client; const guild = getOrCreateGuild(c, data.guild_id, data.shardId); c.emit(Constants.Events.GUILD_BAN_ADD, guild.bans._add(data)); }, GuildBanRemove: function(data) { const c = this.client; const guild = getOrCreateGuild(c, data.guild_id, data.shardId); const ban = guild.bans.cache.get(data.user.id) || guild.bans._add(data); guild.bans.cache.delete(ban.user.id); c.emit(Constants.Events.GUILD_BAN_REMOVE, ban); }, GuildDelete: function(data) { const c = this.client; const guild = getOrCreateGuild(c, data.id, data.shardId); if(data.unavailable) { guild.available = false; c.emit(Constants.Events.GUILD_UNAVAILABLE, guild); return { guild: null }; } for(const channel of guild.channels.cache.values()) { c.channels._remove(channel.id); } c.voice.adapters.get(data.id)?.destroy(); c.guilds.cache.delete(guild.id); guild.deleted = true; return { guild }; }, GuildUpdate: function(data) { const c = this.client; let guild = c.guilds.cache.get(data.id); let old; if(guild) { old = guild._update(data); } else { guild = c.guilds._add(data); old = c.guilds._add({ id: data.id, shardId: data.shardId }, false); old.partial = true; } return { old, updated: guild }; }, // called by GuildEmojisUpdate, GuildEmojiManager.create() GuildEmojiCreate: function(guild, emoji) { const created = guild.emojis._add(emoji); return { emoji: created }; }, // called by GuildEmojisUpdate GuildEmojiDelete: function(emoji) { emoji.guild.emojis.cache.delete(emoji.id); emoji.deleted = true; return { emoji }; }, // called by GuildEmojisUpdate GuildEmojiUpdate: function(current, data) { const old = current._update(data); return { old, emoji: current }; }, // called by Guild._patch() GuildEmojisUpdate: function(data) { const c = this.client; const guild = getOrCreateGuild(c, data.guild_id, data.shardId); const deletions = new Map(guild.emojis.cache); for(const emoji of data.emojis) { const cached = guild.emojis.cache.get(emoji.id); if(cached) { deletions.delete(emoji.id); if(!cached.equals(emoji)) { const result = c.actions.GuildEmojiUpdate.handle(cached, emoji); c.emit(Constants.Events.GUILD_EMOJI_UPDATE, result.old, result.emoji); } } else { const result = c.actions.GuildEmojiCreate.handle(guild, emoji); c.emit(Constants.Events.GUILD_EMOJI_CREATE, result.emoji); } } for(const deleted of deletions.values()) { const result = c.actions.GuildEmojiDelete.handle(deleted); c.emit(Constants.Events.GUILD_EMOJI_DELETE, result.emoji); } }, GuildIntegrationsUpdate: function(data) { const c = this.client; const guild = getOrCreateGuild(c, data.guild_id, data.shardId); c.emit(Constants.Events.GUILD_INTEGRATIONS_UPDATE, guild); }, GuildMemberRemove: function(data) { const c = this.client; const guild = getOrCreateGuild(c, data.guild_id, data.shardId); let member = guild.members.cache.get(data.user.id); if(!member) { member = guild.members._add({ user: data.user }, false); // has built in partial } member.deleted = true; guild.members.cache.delete(data.user.id); guild.presences.cache.delete(data.user.id); guild.voiceStates.cache.delete(data.user.id); if(guild.memberCount) { guild.memberCount--; } return { guild, member }; }, GuildMemberUpdate: function(data) { const c = this.client; if(data.user.username) { const user = c.users.cache.get(data.user.id); if(!user) { c.users._add(data.user); } else if(!user._equals(data.user)) { const { old, updated } = c.actions.UserUpdate.handle(data.user); c.emit(Constants.Events.USER_UPDATE, old, updated); } } const guild = getOrCreateGuild(c, data.guild_id, data.shardId); let member = guild.members.cache.get(data.user.id); let old; if(member) { old = member._update(data); if(!member.equals(old)) { c.emit(Constants.Events.GUILD_MEMBER_UPDATE, old, member); } } else { member = guild.members._add(data); old = guild.members._add({ user: data.user }, false); // has built in partial c.emit(Constants.Events.GUILD_MEMBER_UPDATE, old, member); } }, // called by RoleManager.create() GuildRoleCreate: function(data) { const c = this.client; const guild = getOrCreateGuild(c, data.guild_id, data.shardId); const role = guild.roles._add(data.role); return { role }; }, // called by Role.delete() GuildRoleDelete: function(data) { const c = this.client; const guild = getOrCreateGuild(c, data.guild_id, data.shardId); let role = guild.roles.cache.get(data.role_id); if(!role) { role = guild.roles._add({ id: data.role_id, permissions: 0 }, false); role.partial = true; } guild.roles.cache.delete(data.role_id); role.deleted = true; return { role }; }, GuildRoleUpdate: function(data) { const c = this.client; const guild = getOrCreateGuild(c, data.guild_id, data.shardId); let role = guild.roles.cache.get(data.role.id); let old; if(role) { old = role._update(data.role); } else { role = guild.roles._add(data.role); old = guild.roles._add({ id: data.role.id, permissions: 0 }, false); old.partial = true; } return { old, updated: role }; }, GuildScheduledEventCreate: function(data) { const c = this.client; const guild = getOrCreateGuild(c, data.guild_id, data.shardId); const guildScheduledEvent = guild.scheduledEvents._add(data); return { guildScheduledEvent }; }, GuildScheduledEventDelete: function(data) { const c = this.client; const guild = getOrCreateGuild(c, data.guild_id, data.shardId); let guildScheduledEvent = guild.scheduledEvents.cache.get(data.id); if(guildScheduledEvent) { guild.scheduledEvents.cache.delete(guildScheduledEvent.id); } else { guildScheduledEvent = guild.scheduledEvents._add(data, false); } guildScheduledEvent.deleted = true; return { guildScheduledEvent }; }, GuildScheduledEventUpdate: function(data) { const c = this.client; const guild = getOrCreateGuild(c, data.guild_id, data.shardId); const oldGuildScheduledEvent = guild.scheduledEvents.cache.get(data.id)?._clone() ?? guild.scheduledEvents._add(data, false); const newGuildScheduledEvent = guild.scheduledEvents._add(data); return { oldGuildScheduledEvent, newGuildScheduledEvent }; }, GuildScheduledEventUserAdd: function(data) { const c = this.client; const guild = getOrCreateGuild(c, data.guild_id, data.shardId); let guildScheduledEvent = guild.scheduledEvents.cache.get(data.guild_scheduled_event_id); if(!guildScheduledEvent) { guildScheduledEvent = guild.scheduledEvents._add({ id: data.guild_scheduled_event_id, guild_id: data.guild_id }, false); guildScheduledEvent.partial = true; } let user = c.users.cache.get(data.user_id); if(!user) { user = c.users._add({ id: data.user_id }, false); // has built in partial } return { guildScheduledEvent, user }; }, GuildScheduledEventUserRemove: function(data) { const c = this.client; const guild = getOrCreateGuild(c, data.guild_id, data.shardId); let guildScheduledEvent = guild.scheduledEvents.cache.get(data.guild_scheduled_event_id); if(!guildScheduledEvent) { guildScheduledEvent = guild.scheduledEvents._add({ id: data.guild_scheduled_event_id, guild_id: data.guild_id }, false); guildScheduledEvent.partial = true; } let user = c.users.cache.get(data.user_id); if(!user) { user = c.users._add({ id: data.user_id }, false); // has built in partial } return { guildScheduledEvent, user }; }, // called by GuildStickersUpdate, GuildStickerManager.create() GuildStickerCreate: function(guild, createdSticker) { const sticker = guild.stickers._add(createdSticker); return { sticker }; }, // called by GuildStickersUpdate GuildStickerDelete: function(sticker) { sticker.guild.stickers.cache.delete(sticker.id); sticker.deleted = true; return { sticker }; }, // called by GuildStickersUpdate GuildStickerUpdate: function(current, data) { const old = current._update(data); return { old, sticker: current }; }, // called by Guild._patch() GuildStickersUpdate: function(data) { const c = this.client; const guild = getOrCreateGuild(c, data.guild_id, data.shardId); const deletions = new Map(guild.stickers.cache); for(const sticker of data.stickers) { const cached = guild.stickers.cache.get(sticker.id); if(cached) { deletions.delete(sticker.id); if(!cached.equals(sticker)) { const result = c.actions.GuildStickerUpdate.handle(cached, sticker); this.client.emit(Constants.Events.GUILD_STICKER_UPDATE, result.old, result.sticker); } } else { const result = c.actions.GuildStickerCreate.handle(guild, sticker); this.client.emit(Constants.Events.GUILD_STICKER_CREATE, result.sticker); } } for(const deleted of deletions.values()) { const result = c.actions.GuildStickerDelete.handle(deleted); this.client.emit(Constants.Events.GUILD_STICKER_DELETE, result.sticker); } }, InteractionCreate: function(data) { const c = this.client; let InteractionType; switch(data.type) { case Constants.InteractionTypes.APPLICATION_COMMAND: { switch(data.data.type) { case Constants.ApplicationCommandTypes.CHAT_INPUT: InteractionType = CommandInteraction; break; case Constants.ApplicationCommandTypes.USER: InteractionType = UserContextMenuInteraction; break; case Constants.ApplicationCommandTypes.MESSAGE: InteractionType = MessageContextMenuInteraction; break; default: c.emit(Constants.Events.DEBUG, `[INTERACTION] Received application command interaction with unknown type: ${data.data.type}`); return; } break; } case Constants.InteractionTypes.MESSAGE_COMPONENT: { switch(data.data.component_type) { case Constants.MessageComponentTypes.BUTTON: { InteractionType = ButtonInteraction; break; } case Constants.MessageComponentTypes.SELECT_MENU: InteractionType = SelectMenuInteraction; break; default: { c.emit(Constants.Events.DEBUG, `[INTERACTION] Received component interaction with unknown type: ${data.data.component_type}`); return; } } break; } case Constants.InteractionTypes.APPLICATION_COMMAND_AUTOCOMPLETE: { InteractionType = AutocompleteInteraction; break; } case Constants.InteractionTypes.MODAL_SUBMIT: { InteractionType = ModalSubmitInteraction; break; } default: { c.emit(Constants.Events.DEBUG, `[INTERACTION] Received interaction with unknown type: ${data.type}`); return; } } c.emit(Constants.Events.INTERACTION_CREATE, new InteractionType(c, data)); }, InviteCreate: function(data) { const c = this.client; if(!data.guild_id) { return; } const guild = getOrCreateGuild(c, data.guild_id, data.shardId); const channel = getOrCreateChannel(c, data.channel_id, guild); if(!channel) { return {}; } const invite = guild.invites._add(Object.assign(data, { channel, guild })); return { invite }; }, InviteDelete: function(data) { const c = this.client; if(!data.guild_id) { return; } const guild = getOrCreateGuild(c, data.guild_id, data.shardId); let invite = guild.invites.cache.get(data.code); if(!invite) { const channel = getOrCreateChannel(c, data.channel_id, guild); if(!channel) { return {}; } invite = guild.invites._add(Object.assign(data, { channel, guild }), false); invite.partial = true; } guild.invites.cache.delete(invite.code); return { invite }; }, MessageCreate: function(data) { const c = this.client; const guild = data.guild_id ? getOrCreateGuild(c, data.guild_id, data.shardId) : void 0; const channel = getOrCreateChannel(c, data.channel_id, guild, data.author); if(!channel || !channel.messages) { return {}; } channel.lastMessageId = data.id; const message = channel.messages._add(data); return { message }; }, // called by TextBasedChannel.send() MessageDelete: function(data) { const c = this.client; const guild = data.guild_id ? getOrCreateGuild(c, data.guild_id, data.shardId) : void 0; const channel = getOrCreateChannel(c, data.channel_id, guild); if(!channel || !channel.messages) { return {}; } const message = getOrCreateMessage(channel, data.id); channel.messages.cache.delete(message.id); message.deleted = true; return { message }; }, MessageDeleteBulk: function(data) { const c = this.client; const guild = data.guild_id ? getOrCreateGuild(c, data.guild_id, data.shardId) : void 0; const channel = getOrCreateChannel(c, data.channel_id, guild); if(!channel || !channel.messages) { return {}; } const deleted = new Collection(); for(const id of data.ids) { const message = getOrCreateMessage(channel, id); channel.messages.cache.delete(message.id); message.deleted = true; deleted.set(id, message); } return { messages: deleted }; }, MessageUpdate: function(data) { const c = this.client; const guild = data.guild_id ? getOrCreateGuild(c, data.guild_id, data.shardId) : void 0; const channel = getOrCreateChannel(c, data.channel_id, guild, data.author); if(!channel || !channel.messages) { return {}; } let message = channel.messages.cache.get(data.id); let old; if(message) { old = message._update(data); } else { message = channel.messages._add(data); old = channel.messages._add({ id: data.id }, false); // has built in partial } return { old, updated: message }; }, // called by Message.react() MessageReactionAdd: function(data) { const c = this.client; let channel = data.channel; if(!channel) { const guild = data.guild_id ? getOrCreateGuild(c, data.guild_id, data.shardId) : void 0; channel = getOrCreateChannel(c, data.channel_id, guild); if(!channel || !channel.messages) { return {}; } } let user = data.user || c.users.cache.get(data.user_id); if(!user) { if(data.member?.user) { user = c.users._add(data.member.user); } else { user = c.users._add({ id: data.user_id }, false); // has built in partial } } const message = data.message || getOrCreateMessage(channel, data.message_id); const reaction = message.reactions.cache.get(data.emoji.id ?? decodeURIComponent(data.emoji.name)) || message.reactions._add({ emoji: data.emoji, count: message.partial ? null : 0, me: user.id === c.user.id }); reaction._add(user); return { message, reaction, user }; }, MessageReactionRemove: function(data) { const c = this.client; const guild = data.guild_id ? getOrCreateGuild(c, data.guild_id, data.shardId) : void 0; const channel = getOrCreateChannel(c, data.channel_id, guild); if(!channel || !channel.messages) { return {}; } let user = c.users.cache.get(data.user_id); if(!user) { user = c.users._add({ id: data.user_id }, false); // has built in partial } const message = getOrCreateMessage(channel, data.message_id); let reaction = message.reactions.cache.get(data.emoji.id ?? decodeURIComponent(data.emoji.name)); if(!reaction) { reaction = message.reactions._add({ emoji: data.emoji, count: null, me: user.id === c.user.id }, false); // built in partial if count is null } reaction._remove(user); return { message, reaction, user }; }, MessageReactionRemoveAll: function(data) { const c = this.client; const guild = data.guild_id ? getOrCreateGuild(c, data.guild_id, data.shardId) : void 0; const channel = getOrCreateChannel(c, data.channel_id, guild); if(!channel || !channel.messages) { return {}; } const message = getOrCreateMessage(channel, data.message_id); const removed = message.reactions.cache.clone(); message.reactions.cache.clear(); return { message, removed }; }, MessageReactionRemoveEmoji: function(data) { const c = this.client; const guild = data.guild_id ? getOrCreateGuild(c, data.guild_id, data.shardId) : void 0; const channel = getOrCreateChannel(c, data.channel_id, guild); if(!channel || !channel.messages) { return {}; } const message = getOrCreateMessage(channel, data.message_id); let reaction = message.reactions.cache.get(data.emoji.id ?? decodeURIComponent(data.emoji.name)); if(!reaction) { reaction = message.reactions._add({ emoji: data.emoji, count: null, me: null }, false); // built in partial if count is null } if(!message.partial) { message.reactions.cache.delete(reaction.emoji.id ?? reaction.emoji.name); } return { reaction }; }, PresenceUpdate: function(data) { const c = this.client; if(data.user.username) { const user = c.users.cache.get(data.user.id) || c.users._add(data.user); if(!user._equals(data.user)) { const { old, updated } = c.actions.UserUpdate.handle(data.user); c.emit(Constants.Events.USER_UPDATE, old, updated); } } const guild = getOrCreateGuild(c, data.guild_id, data.shardId); let old = guild.presences.cache.get(data.user.id)?._clone(); if(!old) { old = guild.presences._add({ user: { id: data.user.id }, guild }, false); old.partial = true; } const presence = guild.presences._add(Object.assign(data, { guild })); if(c.listenerCount(Constants.Events.PRESENCE_UPDATE) && (old.partial || !presence.equals(old))) { c.emit(Constants.Events.PRESENCE_UPDATE, old, presence); } if(!(guild.members.cache instanceof LimitedCollection) && !guild.members.cache.has(data.user.id) && data.status !== "offline") { const member = guild.members._add({ user: data.user, deaf: false, mute: false }); c.emit(Constants.Events.GUILD_MEMBER_AVAILABLE, member); } }, StageInstanceCreate: function(data) { const c = this.client; const guild = getOrCreateGuild(c, data.guild_id, data.shardId); const channel = getOrCreateChannel(c, data.channel_id, guild); if(!channel) { return {}; } const stageInstance = channel.guild.stageInstances._add(data); c.emit(Constants.Events.STAGE_INSTANCE_CREATE, stageInstance); return { stageInstance }; }, StageInstanceDelete: function(data) { const c = this.client; const guild = getOrCreateGuild(c, data.guild_id, data.shardId); const channel = getOrCreateChannel(c, data.channel_id, guild); if(!channel) { return {}; } const stageInstance = channel.guild.stageInstances._add(data); if(stageInstance) { channel.guild.stageInstances.cache.delete(stageInstance.id); stageInstance.deleted = true; } c.emit(Constants.Events.STAGE_INSTANCE_DELETE, stageInstance); return { stageInstance }; }, StageInstanceUpdate: function(data) { const c = this.client; const guild = getOrCreateGuild(c, data.guild_id, data.shardId); const channel = getOrCreateChannel(c, data.channel_id, guild); if(!channel) { return {}; } let oldStageInstance = channel.guild.stageInstances.cache.get(data.id)?._clone(); if(!oldStageInstance) { oldStageInstance = channel.guild.stageInstances._add({ id: data.id }, false); oldStageInstance.partial = true; } const newStageInstance = channel.guild.stageInstances._add(data); c.emit(Constants.Events.STAGE_INSTANCE_UPDATE, oldStageInstance, newStageInstance); return { oldStageInstance, newStageInstance }; }, // called by ThreadManager.create() ThreadCreate: function(data) { const c = this.client; const guild = getOrCreateGuild(c, data.guild_id, data.shardId); const thread = c.channels._add(data, guild); if(!thread) { return {}; } c.emit(Constants.Events.THREAD_CREATE, thread, data.newly_created ?? false); return { thread }; }, ThreadDelete: function(data) { const c = this.client; let channel = c.channels.cache.get(data.id); if(!channel) { const guild = getOrCreateGuild(c, data.guild_id, data.shardId); channel = c.channels._add(data, guild, { cache: false, allowUnknownGuild: true }); if(!channel || !channel.messages) { return {}; } makePartial(channel); } for(const message of channel.messages.cache.values()) { message.deleted = true; } c.channels._remove(channel.id); channel.deleted = true; c.emit(Constants.Events.THREAD_DELETE, channel); return { channel }; }, ThreadListSync: function(data) { const c = this.client; const guild = data.guild_id ? getOrCreateGuild(c, data.guild_id, data.shardId) : void 0; if(data.channel_ids) { for(const id of data.channel_ids) { const channel = c.channels.resolve(id); if(channel) { this.removeStale(channel); } } } else { for(const channel of guild.channels.cache.values()) { this.removeStale(channel); } } const syncedThreads = data.threads.reduce((coll, rawThread) => { const thread = c.channels._add(rawThread); if(!thread) { return coll; } return coll.set(thread.id, thread); }, new Collection()); for(const rawMember of Object.values(data.members)) { const thread = c.channels.cache.get(rawMember.id) || syncedThreads.get(rawMember.id); if(thread) { thread.members._add(rawMember); } } c.emit(Constants.Events.THREAD_LIST_SYNC, syncedThreads); return { syncedThreads }; }, ThreadMemberUpdate: function(data) { const c = this.client; let thread = c.channels.cache.get(data.id); if(!thread) { const guild = getOrCreateGuild(c, data.guild_id, data.shardId); thread = c.channels._add({ id: data.id, type: 11 }, guild, { cache: false, allowUnknownGuild: true }); makePartial(thread); } let member = thread.members.cache.get(data.user_id); let old; if(member) { old = member._update(data); } else { member = thread.members._add(data); old = thread.members._add({ user_id: data.user_id }, false); old.partial = true; } c.emit(Constants.Events.THREAD_MEMBER_UPDATE, old, member); return {}; }, ThreadMembersUpdate: function(data) { const c = this.client; let thread = c.channels.cache.get(data.id); let old; if(thread) { old = thread.members.cache.clone(); thread.memberCount = data.member_count; data._added_members?.forEach(rawMember => { thread.members._add(rawMember); }); data.removed_member_ids?.forEach(memberId => { thread.members.cache.delete(memberId); }); } else { const guild = getOrCreateGuild(c, data.guild_id, data.shardId); thread = c.channels._add({ id: data.id, type: 11 }, guild, { cache: false, allowUnknownGuild: true }); data._added_members?.forEach(rawMember => { thread.members._add(rawMember); }); old = new thread.members.cache.constructor(); } c.emit(Constants.Events.THREAD_MEMBERS_UPDATE, old, thread.members.cache); return {}; }, TypingStart: function(data) { const c = this.client; const guild = data.guild_id ? getOrCreateGuild(c, data.guild_id, data.shardId) : void 0; const channel = getOrCreateChannel(c, data.channel_id, guild); if(!channel || !channel.messages) { return; } let user = c.users.cache.get(data.user_id); if(!user) { if(data.member?.user) { user = c.users._add(data.member.user); } else { user = c.users._add({ id: data.user_id }, false); // has built in partial } } c.emit(Constants.Events.TYPING_START, new Typing(channel, user, data)); }, // called by ClientUser.edit() UserUpdate: function(data) { const c = this.client; let user = c.users.cache.get(data.id); let old; if(user) { old = user._update(data); } else { user = c.users._add(data); old = c.users._add({ id: data.id }, false); // has built in partial } return { old, updated: user }; }, VoiceStateUpdate: function(data) { const c = this.client; const guild = getOrCreateGuild(c, data.guild_id, data.shardId); if(data.member?.user) { const user = c.users.cache.get(data.user_id) || c.users._add(data.member.user); if(data.member.user.username && !user._equals(data.member.user)) { const { old, updated } = c.actions.UserUpdate.handle(data.member.user); c.emit(Constants.Events.USER_UPDATE, old, updated); } const member = guild.members.cache.get(data.user_id); if(member) { member._update(data.member); } else { guild.members._add(data.member); } } const oldState = guild.voiceStates.cache.get(data.user_id)?._clone() || guild.voiceStates._add({ user_id: data.user_id }); const newState = guild.voiceStates._add(data); c.emit(Constants.Events.VOICE_STATE_UPDATE, oldState, newState); if(data.user_id === c.user.id) { c.emit("debug", `[VOICE] received voice state update: ${JSON.stringify(data)}`); c.voice.onVoiceStateUpdate(data); } }, WebhooksUpdate: function(data) { const c = this.client; const guild = getOrCreateGuild(c, data.guild_id, data.shardId); const channel = getOrCreateChannel(c, data.channel_id, guild); if(!channel) { return; } c.emit(Constants.Events.WEBHOOKS_UPDATE, channel); } };