const { Client, Events, GatewayIntentBits } = require('discord.js');
const { token, sftp, pterodactyl } = require('./config.json');
const fetch = require('node-fetch');
const SFTPClient = require('ssh2-sftp-client');
const axios = require('axios');
process.on('unhandledRejection', error => {
console.error('Unhandled promise rejection:', error);
const client = new Client({
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent,
GatewayIntentBits.GuildMembers
client.on(Events.MessageCreate, async message => {
if (!message.content.startsWith('!whitelist') || message.author.bot) return;
const args = message.content.slice('!whitelist'.length).trim().split(/ +/);
const command = args.shift().toLowerCase();
if (command === 'help') {
const helpMessage = `**Whitelist Bot Commands:**\n\`\`\`
→ Add a player to the whitelist
2. !whitelist remove <username>
→ Remove a player from the whitelist
→ Show all whitelisted players
4. !whitelist check <username/uuid>
→ Look up a player's UUID or username
→ Show this help message\`\`\``;
await message.channel.send(helpMessage);
if (!message.member.roles.cache.has('REDACTED')) {
return message.channel.send('You do not have permission to use this command!');
if (command === 'check') {
return message.channel.send('Please provide a username or UUID!');
const reply = await message.channel.send('Processing lookup request...');
const isUUID = /^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}$/i.test(query);
const formattedUUID = query.replace(/-/g, '');
const response = await fetch(`https://sessionserver.mojang.com/session/minecraft/profile/${formattedUUID}`);
return await reply.edit('Invalid UUID or player not found.');
const data = await response.json();
await reply.edit(`**UUID Lookup Result:**\n\`\`\`\nUsername: ${data.name}\nUUID: ${query}\`\`\``);
const response = await fetch(`https://api.mojang.com/users/profiles/minecraft/${query}`);
return await reply.edit('Invalid username or player not found.');
const data = await response.json();
const formattedUUID = data.id.replace(/(\w{8})(\w{4})(\w{4})(\w{4})(\w{12})/, '$1-$2-$3-$4-$5');
await reply.edit(`**Username Lookup Result:**\n\`\`\`\nUsername: ${data.name}\nUUID: ${formattedUUID}\`\`\``);
console.error('Lookup Error:', error);
await reply.edit('An error occurred while looking up the player.');
if (command === 'list') {
const sftpClient = new SFTPClient();
await sftpClient.connect({
const whitelistData = await sftpClient.get(sftp.whitelistPath);
const whitelist = JSON.parse(whitelistData.toString());
const playerList = whitelist.map((player, index) => `${index + 1}. ${player.name}`).join('\n');
const formattedMessage = `**Whitelisted Players (${whitelist.length}):**\n\`\`\`\n${playerList}\n\`\`\``;
await message.channel.send(formattedMessage);
console.error('SFTP Error:', error);
await message.channel.send('Failed to retrieve whitelist.');
} else if (command === 'remove') {
return message.channel.send('Please provide a Minecraft username!');
const reply = await message.channel.send('Processing whitelist removal request...');
const sftpClient = new SFTPClient();
await sftpClient.connect({
const whitelistData = await sftpClient.get(sftp.whitelistPath);
let whitelist = JSON.parse(whitelistData.toString());
const initialLength = whitelist.length;
whitelist = whitelist.filter(player => player.name.toLowerCase() !== ign.toLowerCase());
if (whitelist.length === initialLength) {
return await reply.edit(`${ign} is not whitelisted!`);
await sftpClient.put(Buffer.from(JSON.stringify(whitelist, null, 2)), sftp.whitelistPath);
console.error('SFTP Error:', error);
return await reply.edit('Failed to update whitelist file');
`${pterodactyl.apiUrl}/api/client/servers/${pterodactyl.serverId}/command`,
{ command: 'whitelist reload' },
headers: { 'Authorization': `Bearer ${pterodactyl.apiKey}` },
console.error('Pterodactyl API Error:', error);
return await reply.edit('Whitelist updated but failed to reload server whitelist');
await reply.edit(`Successfully removed ${ign} from the whitelist!`);
return message.channel.send('Please provide a Minecraft username!');
const reply = await message.channel.send('Processing whitelist request...');
const response = await fetch(`https://api.mojang.com/users/profiles/minecraft/${ign}`);
return await reply.edit('Failed to fetch player data from Mojang API');
const data = await response.json();
return await reply.edit('Invalid username!');
const sftpClient = new SFTPClient();
await sftpClient.connect({
const whitelistData = await sftpClient.get(sftp.whitelistPath);
whitelist = JSON.parse(whitelistData.toString());
console.log('Creating new whitelist file');
const isWhitelisted = whitelist.some(player =>
player.uuid === data.id ||
player.name.toLowerCase() === data.name.toLowerCase()
return await reply.edit(`${data.name} is already whitelisted!`);
await sftpClient.put(Buffer.from(JSON.stringify(whitelist, null, 2)), sftp.whitelistPath);
console.error('SFTP Error:', error);
return await reply.edit('Failed to update whitelist file');
`${pterodactyl.apiUrl}/api/client/servers/${pterodactyl.serverId}/command`,
{ command: 'whitelist reload' },
headers: { 'Authorization': `Bearer ${pterodactyl.apiKey}` },
console.error('Pterodactyl API Error:', error);
return await reply.edit('Whitelist updated but failed to reload server whitelist');
await reply.edit(`Successfully whitelisted ${data.name}!`);
console.error('Command Error:', error);
await message.channel.send('An error occurred while processing the whitelist command.');
console.error('Failed to send error message:', e);
client.once(Events.ClientReady, c => {
console.log(`Ready! Logged in as ${c.user.tag}`);
client.user.setActivity('!whitelist help', { type: 0 });
client.on('error', error => {
console.error('Discord client error:', error);