APRK01 commited on
Commit
6bab161
Β·
1 Parent(s): 6ec7384

feat: add support for custom whitelist drop limits

Browse files
src/database.js CHANGED
@@ -37,6 +37,7 @@ db.exec(`
37
 
38
  CREATE TABLE IF NOT EXISTS whitelist (
39
  user_id TEXT PRIMARY KEY,
 
40
  added_by TEXT NOT NULL,
41
  added_at DATETIME DEFAULT CURRENT_TIMESTAMP
42
  );
@@ -76,7 +77,7 @@ const stmts = {
76
  delState: db.prepare('DELETE FROM bot_state WHERE key = ?'),
77
 
78
  // Whitelist
79
- addWhitelist: db.prepare('INSERT OR REPLACE INTO whitelist (user_id, added_by) VALUES (?, ?)'),
80
  removeWhitelist: db.prepare('DELETE FROM whitelist WHERE user_id = ?'),
81
  getWhitelist: db.prepare('SELECT * FROM whitelist WHERE user_id = ?'),
82
  getAllWhitelist: db.prepare('SELECT * FROM whitelist'),
 
37
 
38
  CREATE TABLE IF NOT EXISTS whitelist (
39
  user_id TEXT PRIMARY KEY,
40
+ max_drops INTEGER DEFAULT 3,
41
  added_by TEXT NOT NULL,
42
  added_at DATETIME DEFAULT CURRENT_TIMESTAMP
43
  );
 
77
  delState: db.prepare('DELETE FROM bot_state WHERE key = ?'),
78
 
79
  // Whitelist
80
+ addWhitelist: db.prepare('INSERT OR REPLACE INTO whitelist (user_id, max_drops, added_by) VALUES (?, ?, ?)'),
81
  removeWhitelist: db.prepare('DELETE FROM whitelist WHERE user_id = ?'),
82
  getWhitelist: db.prepare('SELECT * FROM whitelist WHERE user_id = ?'),
83
  getAllWhitelist: db.prepare('SELECT * FROM whitelist'),
src/events/messageCreate.js CHANGED
@@ -66,7 +66,7 @@ module.exports = {
66
  return message.reply({
67
  embeds: [createEmbed({
68
  title: '⏳ Drop Cooldown',
69
- description: `You've used all **3 drops** in the last 24 hours.\n\n> Resets in **${check.resetIn}**`,
70
  color: Colors.WARNING,
71
  })],
72
  });
@@ -74,7 +74,7 @@ module.exports = {
74
  const session = startDropSession(userId);
75
  await message.reply({
76
  ...getPrompt(session),
77
- content: `πŸ“¦ **Drop ${check.remaining}/3 remaining today**`,
78
  });
79
  return;
80
  }
@@ -92,15 +92,18 @@ module.exports = {
92
  }
93
 
94
  // Whitelist management
95
- if (content.startsWith('whitelist ')) {
96
- const targetId = content.split(' ')[1]?.trim();
 
 
 
97
  if (!targetId || !/^\d{17,20}$/.test(targetId)) {
98
- return message.reply({ embeds: [errorEmbed('Invalid ID', 'Usage: `whitelist <user_id>`')] });
99
  }
100
- stmts.addWhitelist.run(targetId, userId);
101
  const user = await client.users.fetch(targetId).catch(() => null);
102
  const name = user ? `**${user.tag}**` : `ID \`${targetId}\``;
103
- return message.reply({ embeds: [successEmbed('βœ… Whitelisted', `${name} can now use \`drop\` (3/day)`)] });
104
  }
105
 
106
  if (content.startsWith('unwhitelist ')) {
@@ -120,14 +123,14 @@ module.exports = {
120
  const user = await client.users.fetch(w.user_id).catch(() => null);
121
  const name = user ? user.tag : 'Unknown';
122
  const drops = stmts.getDropCount24h.get(w.user_id);
123
- lines.push(`β€’ **${name}** (\`${w.user_id}\`) β€” ${drops.count}/3 drops today`);
124
  }
125
  return message.reply({ embeds: [infoEmbed('πŸ“‹ Whitelist', lines.join('\n'))] });
126
  }
127
 
128
  // Show help
129
  if (content === 'help') {
130
- const allCommands = [...Object.keys(commands), 'drop', 'whitelist', 'whitelist <id>', 'unwhitelist <id>'];
131
  const embed = infoEmbed('WSB Commands', [
132
  'All commands are **DM-only** and **Owner-only**.\n',
133
  ...allCommands.map(cmd => `\`${cmd}\``),
 
66
  return message.reply({
67
  embeds: [createEmbed({
68
  title: '⏳ Drop Cooldown',
69
+ description: `You've used all **${check.limit} drops** in the last 24 hours.\n\n> Resets in **${check.resetIn}**`,
70
  color: Colors.WARNING,
71
  })],
72
  });
 
74
  const session = startDropSession(userId);
75
  await message.reply({
76
  ...getPrompt(session),
77
+ content: `πŸ“¦ **Drop ${check.limit - check.remaining + 1}/${check.limit} for today**`,
78
  });
79
  return;
80
  }
 
92
  }
93
 
94
  // Whitelist management
95
+ if (content.startsWith('whitelist ') && !content.startsWith('whitelist <')) {
96
+ const args = content.split(' ').slice(1);
97
+ const targetId = args[0]?.trim();
98
+ const limit = parseInt(args[1]) || 3;
99
+
100
  if (!targetId || !/^\d{17,20}$/.test(targetId)) {
101
+ return message.reply({ embeds: [errorEmbed('Invalid ID', 'Usage: `whitelist <user_id> [limit]`\nExample: `whitelist 123456789 5`')] });
102
  }
103
+ stmts.addWhitelist.run(targetId, limit, userId);
104
  const user = await client.users.fetch(targetId).catch(() => null);
105
  const name = user ? `**${user.tag}**` : `ID \`${targetId}\``;
106
+ return message.reply({ embeds: [successEmbed('βœ… Whitelisted', `${name} can now use \`drop\` (**${limit}** per day)`)] });
107
  }
108
 
109
  if (content.startsWith('unwhitelist ')) {
 
123
  const user = await client.users.fetch(w.user_id).catch(() => null);
124
  const name = user ? user.tag : 'Unknown';
125
  const drops = stmts.getDropCount24h.get(w.user_id);
126
+ lines.push(`β€’ **${name}** (\`${w.user_id}\`) β€” ${drops.count}/${w.max_drops} drops today`);
127
  }
128
  return message.reply({ embeds: [infoEmbed('πŸ“‹ Whitelist', lines.join('\n'))] });
129
  }
130
 
131
  // Show help
132
  if (content === 'help') {
133
+ const allCommands = [...Object.keys(commands), 'drop', 'whitelist', 'whitelist <id> [limit]', 'unwhitelist <id>'];
134
  const embed = infoEmbed('WSB Commands', [
135
  'All commands are **DM-only** and **Owner-only**.\n',
136
  ...allCommands.map(cmd => `\`${cmd}\``),
src/systems/drops.js CHANGED
@@ -8,7 +8,6 @@ const { createEmbed } = require('../utils/embeds');
8
  const { Colors } = require('../config');
9
  const { stmts } = require('../database');
10
 
11
- const MAX_DROPS_PER_DAY = 3;
12
  const OWNER_ID = process.env.OWNER_ID;
13
 
14
  // Active drop sessions: Map<userId, session>
@@ -17,8 +16,8 @@ const activeSessions = new Map();
17
  const STEPS = ['title', 'file', 'warnings', 'status', 'about', 'image', 'preview'];
18
 
19
  /**
20
- * Check if a user can drop (owner = unlimited, whitelisted = 3/day).
21
- * Returns { allowed: boolean, remaining?: number, resetIn?: string }
22
  */
23
  function canDrop(userId) {
24
  if (userId === OWNER_ID) return { allowed: true, remaining: Infinity };
@@ -26,18 +25,19 @@ function canDrop(userId) {
26
  const wl = stmts.getWhitelist.get(userId);
27
  if (!wl) return { allowed: false, reason: 'not_whitelisted' };
28
 
 
29
  const { count } = stmts.getDropCount24h.get(userId);
30
- if (count >= MAX_DROPS_PER_DAY) {
31
  const last = stmts.getLastDrop.get(userId);
32
  const resetTime = new Date(last.dropped_at + 'Z');
33
  resetTime.setHours(resetTime.getHours() + 24);
34
  const diff = resetTime - new Date();
35
  const hours = Math.floor(diff / 3600000);
36
  const mins = Math.floor((diff % 3600000) / 60000);
37
- return { allowed: false, reason: 'rate_limited', resetIn: `${hours}h ${mins}m` };
38
  }
39
 
40
- return { allowed: true, remaining: MAX_DROPS_PER_DAY - count };
41
  }
42
 
43
  /**
 
8
  const { Colors } = require('../config');
9
  const { stmts } = require('../database');
10
 
 
11
  const OWNER_ID = process.env.OWNER_ID;
12
 
13
  // Active drop sessions: Map<userId, session>
 
16
  const STEPS = ['title', 'file', 'warnings', 'status', 'about', 'image', 'preview'];
17
 
18
  /**
19
+ * Check if a user can drop (owner = unlimited, whitelisted = custom limit).
20
+ * Returns { allowed: boolean, remaining?: number, resetIn?: string, limit?: number }
21
  */
22
  function canDrop(userId) {
23
  if (userId === OWNER_ID) return { allowed: true, remaining: Infinity };
 
25
  const wl = stmts.getWhitelist.get(userId);
26
  if (!wl) return { allowed: false, reason: 'not_whitelisted' };
27
 
28
+ const limit = wl.max_drops;
29
  const { count } = stmts.getDropCount24h.get(userId);
30
+ if (count >= limit) {
31
  const last = stmts.getLastDrop.get(userId);
32
  const resetTime = new Date(last.dropped_at + 'Z');
33
  resetTime.setHours(resetTime.getHours() + 24);
34
  const diff = resetTime - new Date();
35
  const hours = Math.floor(diff / 3600000);
36
  const mins = Math.floor((diff % 3600000) / 60000);
37
+ return { allowed: false, reason: 'rate_limited', resetIn: `${hours}h ${mins}m`, limit };
38
  }
39
 
40
+ return { allowed: true, remaining: limit - count, limit };
41
  }
42
 
43
  /**