176 lines
8.1 KiB
JavaScript
Raw Permalink Normal View History

2025-02-06 11:13:24 -05:00
let targetUserIds = [];
2025-02-05 21:02:07 -05:00
let isKickActive = false;
let voiceStateHandler = null;
let lastKickTime = 0;
let consecutiveKicks = 0;
let cooldownTime = 0;
let checkInterval = null;
const getRandomDelay = () => {
2025-02-05 22:12:55 -05:00
const delay = Math.floor(Math.random() * 250) + 100;
console.log(`[KICKVC] Generated event delay: ${delay}ms`);
return delay;
2025-02-05 21:02:07 -05:00
};
const getRandomCheckDelay = () => {
2025-02-05 22:12:55 -05:00
const delay = Math.floor(Math.random() * 250) + 200;
console.log(`[KICKVC] Generated interval check delay: ${delay}ms`);
return delay;
2025-02-05 21:02:07 -05:00
};
const getCooldown = (kicks) => {
2025-02-05 22:12:55 -05:00
let cooldown;
if (kicks <= 3) cooldown = 200;
else if (kicks <= 5) cooldown = 500;
else if (kicks <= 10) cooldown = 1000;
else cooldown = 2500;
console.log(`[KICKVC] New cooldown calculated for ${kicks} kicks: ${cooldown}ms`);
return cooldown;
2025-02-05 21:02:07 -05:00
};
module.exports = {
name: 'kickvc',
2025-02-06 11:13:24 -05:00
description: 'Automatically kicks specified users from voice channels.',
2025-02-05 21:02:07 -05:00
async execute(message, args, deleteTimeout) {
if (args[0]?.toLowerCase() === 'stop') {
if (voiceStateHandler) {
message.client.removeListener('voiceStateUpdate', voiceStateHandler);
voiceStateHandler = null;
}
if (checkInterval) {
clearInterval(checkInterval);
checkInterval = null;
}
isKickActive = false;
2025-02-06 11:13:24 -05:00
targetUserIds = [];
2025-02-05 21:02:07 -05:00
lastKickTime = 0;
consecutiveKicks = 0;
cooldownTime = 0;
console.log('[KICKVC] System deactivated - all variables reset');
message.channel.send('Voice kick has been deactivated.')
.then(msg => setTimeout(() => msg.delete().catch(console.error), deleteTimeout));
return;
}
2025-02-06 11:13:24 -05:00
const userIds = args.filter(arg => /^\d{17,19}$/.test(arg));
if (!userIds.length) {
console.log('[KICKVC] Invalid user IDs provided');
message.channel.send('Please provide at least one valid user ID.')
2025-02-05 21:02:07 -05:00
.then(msg => setTimeout(() => msg.delete().catch(console.error), deleteTimeout));
return;
}
2025-02-06 11:13:24 -05:00
targetUserIds = userIds;
2025-02-05 21:02:07 -05:00
isKickActive = true;
2025-02-06 11:13:24 -05:00
console.log(`[KICKVC] System activated - Targeting user IDs: ${targetUserIds.join(', ')}`);
2025-02-05 21:02:07 -05:00
if (voiceStateHandler) {
message.client.removeListener('voiceStateUpdate', voiceStateHandler);
2025-02-05 22:12:55 -05:00
console.log('[KICKVC] Removed old voice state handler');
2025-02-05 21:02:07 -05:00
}
if (checkInterval) {
clearInterval(checkInterval);
2025-02-05 22:12:55 -05:00
console.log('[KICKVC] Cleared old check interval');
2025-02-05 21:02:07 -05:00
}
const kickUser = async (member, guild, fromEvent = false) => {
if (!isKickActive) return;
const currentTime = Date.now();
const timeSinceLastKick = currentTime - lastKickTime;
if (timeSinceLastKick < cooldownTime) {
2025-02-05 22:12:55 -05:00
console.log(`[KICKVC] On cooldown - ${cooldownTime - timeSinceLastKick}ms remaining`);
2025-02-05 21:02:07 -05:00
return;
}
try {
2025-02-06 11:13:24 -05:00
const selfMember = await guild.members.fetch(member.client.user.id);
if (!selfMember.permissions.has("ADMINISTRATOR")) {
console.log(`[KICKVC] No admin permissions in ${guild.name}, skipping`);
2025-02-05 22:12:55 -05:00
return;
}
2025-02-06 11:13:24 -05:00
const delay = fromEvent ? getRandomDelay() : getRandomCheckDelay();
console.log(`[KICKVC] Admin check passed in ${guild.name}, waiting ${delay}ms before kick...`);
await new Promise(resolve => setTimeout(resolve, delay));
if (!member.voice.channel) return;
console.log(`[KICKVC] Target in voice: ${member.user.tag} | ${guild.name} | ${member.voice.channel.name}`);
2025-02-05 21:02:07 -05:00
await member.voice.disconnect();
lastKickTime = currentTime;
consecutiveKicks++;
cooldownTime = getCooldown(consecutiveKicks);
setTimeout(() => {
if (consecutiveKicks > 0) {
consecutiveKicks--;
cooldownTime = getCooldown(consecutiveKicks);
}
}, 15000);
2025-02-05 22:12:55 -05:00
} catch (error) {
2025-02-06 11:13:24 -05:00
console.log(`[KICKVC] Error kicking in ${guild.name}:`, error);
2025-02-05 21:02:07 -05:00
try {
await member.voice.setChannel(null);
2025-02-06 11:13:24 -05:00
console.log('[KICKVC] Succeeded with alternate method (setChannel null)');
2025-02-05 21:02:07 -05:00
} catch {
try {
await member.voice.channel.permissionOverwrites.create(member, {
Connect: false,
Speak: false
});
await member.voice.disconnect();
2025-02-06 11:13:24 -05:00
console.log('[KICKVC] Succeeded with permissions override');
2025-02-05 22:12:55 -05:00
} catch {
2025-02-06 11:13:24 -05:00
console.log('[KICKVC] All disconnect methods failed');
2025-02-05 22:12:55 -05:00
}
2025-02-05 21:02:07 -05:00
}
}
};
voiceStateHandler = async (oldState, newState) => {
2025-02-06 11:13:24 -05:00
if (!isKickActive || targetUserIds.length === 0) return;
const id = newState?.member?.id || oldState?.member?.id;
if (!targetUserIds.includes(id)) return;
2025-02-05 21:02:07 -05:00
const voiceState = newState?.channelId ? newState : oldState;
if (!voiceState?.channel) return;
2025-02-05 22:12:55 -05:00
console.log('[KICKVC] Voice state update detected for target');
2025-02-05 21:02:07 -05:00
try {
const guild = voiceState.guild;
2025-02-06 11:13:24 -05:00
const member = await guild.members.fetch(id).catch(() => null);
2025-02-05 21:02:07 -05:00
if (member?.voice?.channel) {
await kickUser(member, guild, true);
}
2025-02-05 22:12:55 -05:00
} catch (error) {
console.log('[KICKVC] Error in voice state handler:', error);
}
2025-02-05 21:02:07 -05:00
};
const intervalTime = Math.floor(Math.random() * 500) + 1000;
2025-02-05 22:12:55 -05:00
console.log(`[KICKVC] Setting up interval check every ${intervalTime}ms`);
2025-02-05 21:02:07 -05:00
checkInterval = setInterval(async () => {
if (!isKickActive) return;
for (const guild of message.client.guilds.cache.values()) {
2025-02-06 11:13:24 -05:00
for (const id of targetUserIds) {
try {
const member = await guild.members.fetch(id).catch(() => null);
if (member?.voice?.channel) {
await kickUser(member, guild, false);
}
} catch { }
}
2025-02-05 21:02:07 -05:00
}
}, intervalTime);
message.client.on('voiceStateUpdate', voiceStateHandler);
2025-02-05 22:12:55 -05:00
console.log('[KICKVC] New voice state handler and check interval registered');
2025-02-05 21:02:07 -05:00
try {
2025-02-06 11:13:24 -05:00
const users = await Promise.all(targetUserIds.map(id => message.client.users.fetch(id).catch(() => null)));
const userTags = users.filter(u => u).map(u => `${u.tag} (${u.id})`);
console.log(`[KICKVC] Successfully fetched target users: ${userTags.join(', ')}`);
message.channel.send(`Now automatically kicking: ${userTags.join(', ')} from voice channels.`)
2025-02-05 21:02:07 -05:00
.then(msg => setTimeout(() => msg.delete().catch(console.error), deleteTimeout));
2025-02-05 22:12:55 -05:00
console.log('[KICKVC] Performing initial guild check');
2025-02-05 21:02:07 -05:00
message.client.guilds.cache.forEach(async (guild) => {
2025-02-06 11:13:24 -05:00
for (const id of targetUserIds) {
const member = await guild.members.fetch(id).catch(() => null);
if (member?.voice?.channel) {
console.log(`[KICKVC] Target found in voice during initial check - Server: ${guild.name}`);
await kickUser(member, guild, true);
}
2025-02-05 21:02:07 -05:00
}
});
2025-02-05 22:12:55 -05:00
} catch (error) {
console.log('[KICKVC] Could not fetch user information:', error);
2025-02-06 11:13:24 -05:00
message.channel.send(`Now automatically kicking user IDs: ${targetUserIds.join(', ')} from voice channels.`)
2025-02-05 21:02:07 -05:00
.then(msg => setTimeout(() => msg.delete().catch(console.error), deleteTimeout));
}
},
};