import { ActivityType, Client, Events, GatewayIntentBits, OverwriteType, PermissionFlagsBits } from 'discord.js'; import { readFileSync } from "fs"; const client = new Client({ intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers, GatewayIntentBits.GuildPresences, GatewayIntentBits.GuildVoiceStates, GatewayIntentBits.GuildModeration ], }); const config = JSON.parse(readFileSync("config.json", "utf-8")); await client.login(readFileSync("token.txt", "utf-8").split("\n")[0]); const tracker = {}; for (let guild in config) { tracker[guild] = {}; for (let channel in config[guild]) { tracker[guild][channel] = new Set(); } } async function resyncChannel(channelObj) { if (tracker[channelObj.guild.id] && tracker[channelObj.guild.id][channelObj.id]) { tracker[channelObj.guild.id][channelObj.id] = new Set(channelObj.members.map((v, k) => k)); } } async function fullSync() { for (let guild in config) { const guildObj = await client.guilds.fetch(guild); for (let channel in config[guild]) { const channelObj = await guildObj.channels.fetch(channel); await resyncChannel(channelObj); await updateChannel(channelObj.id, await guildObj.channels.fetch(config[guild][channel])); } } } async function updateChannel(vcId, channelObj) { if (!tracker[channelObj.guild.id] || !tracker[channelObj.guild.id][vcId]) return; let t = tracker[channelObj.guild.id][vcId]; const permissions = channelObj.permissionOverwrites.cache.filter((v) => v.type === OverwriteType.Member); let extraneous = permissions.filter((v) => !t.has(v.id)); let missing = Array.from(t).filter(id => !permissions.has(id)); extraneous.each(v => { channelObj.permissionOverwrites.delete(v.id, "Not in VC"); }); for (let a of missing) { channelObj.permissionOverwrites.create( a, { ViewChannel: true, SendMessages: true, AddReactions: true }, { type: OverwriteType.Member, reason: "User in VC" } ); } } client.on(Events.GuildAvailable, async g => { console.log(g.name,"available"); await fullSync(); }); client.on(Events.GuildCreate, async g => { console.log(g.name,"create"); await fullSync(); }); client.on(Events.ClientReady, async () => { client.user.setActivity({ type: ActivityType.Competing, name: "best bot competition 2025" }) }) client.on(Events.VoiceStateUpdate, async (oldState, newState) => { if (oldState.channelId === newState.channelId) return; let affectedChannels = new Set(); if (oldState.channelId && tracker[oldState.guild.id] && tracker[oldState.guild.id][oldState.channelId]) { tracker[oldState.guild.id][oldState.channelId].delete(oldState.id); affectedChannels.add(oldState.channelId); } if (newState.channelId && tracker[newState.guild.id] && tracker[newState.guild.id][newState.channelId]) { tracker[newState.guild.id][newState.channelId].add(newState.id); affectedChannels.add(newState.channelId); } for (let ch of Array.from(affectedChannels)) { if ( config[oldState.guild.id] && config[oldState.guild.id][ch]) { await updateChannel(ch, await oldState.guild.channels.fetch(config[oldState.guild.id][ch])); } } });