const { Snowflake, Client, Guild, VoiceBasedChannel, Events, Status, GatewayDispatchEvents } = require("discord.js"); const adapters = new Map(); const trackedClients = new Set(); const trackedShards = new Map(); function trackClient(client) { if (trackedClients.has(client)) return; trackedClients.add(client); client.ws.on(GatewayDispatchEvents.VoiceServerUpdate, (payload) => { adapters.get(payload.guild_id)?.onVoiceServerUpdate(payload); }); client.ws.on(GatewayDispatchEvents.VoiceStateUpdate, (payload) => { if (payload.guild_id && payload.session_id && payload.user_id === client.user?.id) { adapters.get(payload.guild_id)?.onVoiceStateUpdate(payload); } }); client.on(Events.ShardDisconnect, (_, shardId) => { const guilds = trackedShards.get(shardId); if (guilds) { for (const guildID of guilds.values()) { adapters.get(guildID)?.destroy(); } } trackedShards.delete(shardId); }); } function trackGuild(guild) { let guilds = trackedShards.get(guild.shardId); if (!guilds) { guilds = new Set(); trackedShards.set(guild.shardId, guilds); } guilds.add(guild.id); } module.exports = function (channel) { return (methods) => { adapters.set(channel.guild.id, methods); trackClient(channel.client); trackGuild(channel.guild); return { sendPayload(data) { console.log(channel.guild.shard.status); // if (channel.guild.shard.status === Status.READY) { console.log("Sending shard data"); channel.guild.shard.send(data); return true; // } console.log("Unable to send channel payload"); return false; }, destroy() { console.log("Destroying adapter"); return adapters.delete(channel.guild.id); }, }; }; }