File size: 9,868 Bytes
e5c9966 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 | const { ChannelType } = require('discord.js');
const { errorEmbed, infoEmbed, successEmbed, createEmbed } = require('../utils/embeds');
const { logCommand } = require('../systems/logger');
const { startDropSession, hasSession, getPrompt, handleDropMessage, canDrop } = require('../systems/drops');
const { startMassDropSession, hasMassSession, getMassPrompt, handleMassDropMessage } = require('../systems/massdrop');
const { stmts } = require('../database');
const { Colors } = require('../config');
// Import command handlers
const setup = require('../commands/setup');
const createRoles = require('../commands/createRoles');
const createChannels = require('../commands/createChannels');
const backupLayout = require('../commands/backupLayout');
const shutdown = require('../commands/shutdown');
const ticketStats = require('../commands/ticketStats');
const permissionAudit = require('../commands/permissionAudit');
const postRules = require('../commands/postRules');
const postDisclaimer = require('../commands/postDisclaimer');
const applyUpdates = require('../commands/applyUpdates');
const fixPings = require('../commands/fixPings');
const clearDrops = require('../commands/clearDrops');
const fixDownloads = require('../commands/fixDownloads');
const coOwnerRole = require('../commands/coOwnerRole');
const editDrop = require('../commands/editDrop');
const deleteDrop = require('../commands/deleteDrop');
const OWNER_ID = process.env.OWNER_ID;
// Owner-only command registry
const commands = {
'setup server': setup,
'create roles': createRoles,
'create channels': createChannels,
'backup layout': backupLayout,
'shutdown bot': shutdown,
'ticket stats': ticketStats,
'permission audit': permissionAudit,
'post rules': postRules,
'post disclaimer': postDisclaimer,
'apply updates': applyUpdates,
'fix pings': fixPings,
};
module.exports = {
name: 'messageCreate',
async execute(client, message) {
if (message.author.bot) return;
if (message.channel.type !== ChannelType.DM) return;
const userId = message.author.id;
const content = message.content.trim().toLowerCase();
// ββ Handle active drop session (owner OR whitelisted) ββ
if (hasSession(userId)) {
try {
const handled = await handleDropMessage(message);
if (handled) return;
} catch (err) {
console.error('[Drop Error]', err);
await message.reply({ content: `β Drop error: ${err.message}` }).catch(() => { });
return;
}
}
// ββ Handle active mass drop session ββ
if (hasMassSession(userId)) {
try {
const handled = await handleMassDropMessage(message);
if (handled) return;
} catch (err) {
console.error('[Mass Drop Error]', err);
await message.reply({ content: `β Mass Drop error: ${err.message}` }).catch(() => { });
return;
}
}
// ββ Whitelisted user: only allow "drop" ββ
if (userId !== OWNER_ID) {
if (content === 'drop' || content === 'linkdrop') {
const check = await canDrop(userId);
if (!check.allowed) {
if (check.reason === 'not_whitelisted') {
return; // Silently ignore non-whitelisted users
}
// Rate limited
return message.reply({
embeds: [createEmbed({
title: 'β³ Drop Cooldown',
description: `You've used all **${check.limit} drops** in the last 24 hours.\n\n> Resets in **${check.resetIn}**`,
color: Colors.WARNING,
})],
});
}
const session = startDropSession(userId);
await message.reply({
...getPrompt(session),
content: `π¦ **Drop ${check.limit - check.remaining + 1}/${check.limit} for today**`,
});
return;
}
return; // Whitelisted users can only use "drop" or "linkdrop"
}
// ββ Owner-only commands below ββββββββββββββββββββββββββ
// Drop (no rate limit for owner)
if (content === 'drop' || content === 'linkdrop') {
await logCommand(client, content);
const session = startDropSession(userId);
await message.reply(getPrompt(session));
return;
}
// Mass Drop (no rate limit for owner)
if (content === 'massdrop') {
await logCommand(client, 'massdrop');
const session = startMassDropSession(userId);
await message.reply(getMassPrompt(session));
return;
}
// Whitelist management
if (content.startsWith('whitelist ') && !content.startsWith('whitelist <')) {
const args = content.split(' ').slice(1);
const targetId = args[0]?.trim();
const limit = parseInt(args[1]) || 3;
if (!targetId || !/^\d{17,20}$/.test(targetId)) {
return message.reply({ embeds: [errorEmbed('Invalid ID', 'Usage: `whitelist <user_id> [limit]`\nExample: `whitelist 123456789 5`')] });
}
await stmts.addWhitelist(targetId, limit, userId);
const user = await client.users.fetch(targetId).catch(() => null);
const name = user ? `**${user.tag}**` : `ID \`${targetId}\``;
return message.reply({ embeds: [successEmbed('β
Whitelisted', `${name} can now use \`drop\` (**${limit}** per day)`)] });
}
if (content.startsWith('unwhitelist ')) {
const targetId = content.split(' ')[1]?.trim();
if (!targetId) return message.reply({ embeds: [errorEmbed('Invalid ID', 'Usage: `unwhitelist <user_id>`')] });
await stmts.removeWhitelist(targetId);
return message.reply({ embeds: [successEmbed('β
Removed', `User \`${targetId}\` removed from whitelist`)] });
}
// Clear Drops
if (content.startsWith('clear ')) {
const args = content.split(' ').slice(1);
return clearDrops.execute(client, message, args);
}
// Fix Downloads (migrate old Link buttons to interactive buttons)
if (content.startsWith('fix downloads')) {
const args = content.split(' ').slice(2);
return fixDownloads.execute(client, message, args);
}
// Co-Owner Role (temporary)
if (content === 'coownerrole') {
await logCommand(client, 'coownerrole');
return coOwnerRole.execute(client, message);
}
// Web Administration Commands
if (content.startsWith('editdrop ')) {
const args = content.split(' ').slice(1);
return editDrop.execute(client, message, args);
}
if (content.startsWith('deletedrop ')) {
const args = content.split(' ').slice(1);
return deleteDrop.execute(client, message, args);
}
if (content === 'whitelist') {
const all = await stmts.getAllWhitelist();
if (all.length === 0) {
return message.reply({ embeds: [infoEmbed('Whitelist', 'No users whitelisted.\n\nUse `whitelist <user_id>` to add.')] });
}
const lines = [];
for (const w of all) {
const user = await client.users.fetch(w.user_id).catch(() => null);
const name = user ? user.tag : 'Unknown';
const drops = await stmts.getDropCount24h(w.user_id);
lines.push(`β’ **${name}** (\`${w.user_id}\`) β ${drops.count}/${w.max_drops} drops today`);
}
return message.reply({ embeds: [infoEmbed('π Whitelist', lines.join('\n'))] });
}
// Show help
if (content === 'help') {
const allCommands = [...Object.keys(commands), 'drop', 'massdrop', 'linkdrop', 'whitelist', 'whitelist <id> [limit]', 'unwhitelist <id>', 'clear <channel_id>'];
const embed = infoEmbed('WSB Commands', [
'All commands are **DM-only** and **Owner-only**.\n',
...allCommands.map(cmd => `\`${cmd}\``),
].join('\n'));
return message.reply({ embeds: [embed] });
}
// Find matching command
const handler = commands[content];
if (!handler) {
if (content.startsWith('setup') || content.startsWith('create') ||
content.startsWith('backup') || content.startsWith('shutdown') ||
content.startsWith('ticket') || content.startsWith('permission') ||
content.startsWith('post') || content.startsWith('drop') ||
content.startsWith('mass') || content.startsWith('link') ||
content.startsWith('apply') || content.startsWith('fix') ||
content.startsWith('clear')) {
return message.reply({ embeds: [errorEmbed('Unknown Command', `Did you mean one of these?\n${[...Object.keys(commands), 'drop', 'massdrop', 'linkdrop', 'clear <channel_id>'].map(c => `\`${c}\``).join('\n')}`)] });
}
return;
}
try {
await logCommand(client, content);
await handler.execute(client, message);
} catch (err) {
console.error(`[Command Error] ${content}:`, err);
await message.reply({ embeds: [errorEmbed('Error', `Command failed: \`${err.message}\``)] }).catch(() => { });
}
},
};
|