dankgrinder 8.110.0 → 8.111.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commands/adventure.js +5 -2
- package/lib/commands/beg.js +3 -2
- package/lib/commands/blackjack.js +5 -4
- package/lib/commands/crime.js +2 -1
- package/lib/commands/deposit.js +2 -1
- package/lib/commands/dig.js +3 -2
- package/lib/commands/drops.js +2 -1
- package/lib/commands/farm.js +5 -4
- package/lib/commands/fish.js +8 -6
- package/lib/commands/gamble.js +17 -12
- package/lib/commands/generic.js +11 -6
- package/lib/commands/highlow.js +2 -1
- package/lib/commands/hunt.js +3 -2
- package/lib/commands/inventory.js +2 -1
- package/lib/commands/postmemes.js +2 -1
- package/lib/commands/profile.js +3 -2
- package/lib/commands/scratch.js +2 -1
- package/lib/commands/search.js +2 -1
- package/lib/commands/shop.js +2 -1
- package/lib/commands/stream.js +3 -2
- package/lib/commands/trivia.js +2 -1
- package/lib/commands/utils.js +29 -0
- package/lib/commands/work.js +5 -4
- package/lib/grinder.js +2 -0
- package/package.json +1 -1
|
@@ -37,6 +37,7 @@ const {
|
|
|
37
37
|
LOG, c, sleep, humanDelay, getFullText, parseCoins,
|
|
38
38
|
getAllButtons, getAllSelectMenus, findButton,
|
|
39
39
|
safeClickButton, isHoldTight, logMsg, checkLevelLock,
|
|
40
|
+
sendCommand,
|
|
40
41
|
} = require('./utils');
|
|
41
42
|
|
|
42
43
|
const RE_DISCORD_TIMESTAMP = /<t:(\d+)(?::[tTdDfFR])?>/g;
|
|
@@ -276,13 +277,15 @@ async function playAdventureRounds(channel, msg, adventureAnswers) {
|
|
|
276
277
|
* @param {function} opts.waitForDankMemer - Waits for Dank Memer response
|
|
277
278
|
* @param {object} [opts.client] - Discord client (for modal handling in shop)
|
|
278
279
|
* @param {object} [opts.adventureAnswers] - Per-type answer map from AccountWorker.ADVENTURE_ANSWERS
|
|
280
|
+
* @param {boolean} [opts.useSlash] - Use Discord slash command API instead of text
|
|
281
|
+
* @param {string} [opts.prefix] - Text prefix ('pls' or '/')
|
|
279
282
|
* @returns {Promise<{result: string, coins: number, nextCooldownSec: number|null}>}
|
|
280
283
|
*/
|
|
281
|
-
async function runAdventure({ channel, waitForDankMemer, client, adventureAnswers }) {
|
|
284
|
+
async function runAdventure({ channel, waitForDankMemer, client, adventureAnswers, useSlash, prefix = 'pls' }) {
|
|
282
285
|
LOG.cmd(`${c.white}${c.bold}pls adventure${c.reset}`);
|
|
283
286
|
|
|
284
287
|
// Step 1: Send the command
|
|
285
|
-
await channel
|
|
288
|
+
await sendCommand(channel, 'adventure', { useSlash, prefix });
|
|
286
289
|
let response = await waitForDankMemer(12000);
|
|
287
290
|
|
|
288
291
|
if (!response) {
|
package/lib/commands/beg.js
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* Simple command: send "pls beg", parse coins from response.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
const { LOG, c, getFullText, parseCoins, logMsg, isHoldTight, getHoldTightReason, sleep, checkLevelLock
|
|
6
|
+
const { LOG, c, getFullText, parseCoins, logMsg, isHoldTight, getHoldTightReason, sleep, checkLevelLock,
|
|
7
|
+
sendCommand, } = require('./utils');
|
|
7
8
|
|
|
8
9
|
const RE_NEWLINE = /\n/g;
|
|
9
10
|
|
|
@@ -16,7 +17,7 @@ const RE_NEWLINE = /\n/g;
|
|
|
16
17
|
async function runBeg({ channel, waitForDankMemer }) {
|
|
17
18
|
LOG.cmd(`${c.white}${c.bold}pls beg${c.reset}`);
|
|
18
19
|
|
|
19
|
-
await channel
|
|
20
|
+
await sendCommand(channel, 'beg', { useSlash, prefix });
|
|
20
21
|
const response = await waitForDankMemer(10000);
|
|
21
22
|
|
|
22
23
|
if (!response) {
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
const {
|
|
8
8
|
LOG, c, getFullText, parseCoins, getAllButtons, safeClickButton,
|
|
9
9
|
logMsg, isHoldTight, getHoldTightReason, sleep, humanDelay, ensureCV2, checkLevelLock,
|
|
10
|
+
sendCommand,
|
|
10
11
|
} = require('./utils');
|
|
11
12
|
|
|
12
13
|
const RE_BACKTICK_SCORE = /`\s*(\d+)\s*`/;
|
|
@@ -133,11 +134,11 @@ async function clickFast(msg, btn, retries = 2) {
|
|
|
133
134
|
return null;
|
|
134
135
|
}
|
|
135
136
|
|
|
136
|
-
async function runBlackjack({ channel, waitForDankMemer, betAmount = 5000 }) {
|
|
137
|
-
const
|
|
137
|
+
async function runBlackjack({ channel, waitForDankMemer, betAmount = 5000, useSlash, prefix = 'pls' }) {
|
|
138
|
+
const cmdName = 'bj';
|
|
139
|
+
const cmd = `${prefix} ${cmdName} ${betAmount}`;
|
|
138
140
|
LOG.cmd(`${c.white}${c.bold}${cmd}${c.reset}`);
|
|
139
|
-
|
|
140
|
-
await channel.send(cmd);
|
|
141
|
+
await sendCommand(channel, cmdName, { useSlash, prefix, args: [betAmount] });
|
|
141
142
|
let current = await waitForDankMemer(12000);
|
|
142
143
|
|
|
143
144
|
if (!current) {
|
package/lib/commands/crime.js
CHANGED
|
@@ -12,6 +12,7 @@ const {
|
|
|
12
12
|
LOG, c, getFullText, parseCoins, getAllButtons, safeClickButton,
|
|
13
13
|
logMsg, isHoldTight, getHoldTightReason, sleep, humanDelay,
|
|
14
14
|
isCV2, ensureCV2, checkLevelLock,
|
|
15
|
+
sendCommand,
|
|
15
16
|
} = require('./utils');
|
|
16
17
|
const { Trie, VoseAlias, LRUCache } = require('../structures');
|
|
17
18
|
|
|
@@ -86,7 +87,7 @@ function pickSafeButton(buttons, customSafe) {
|
|
|
86
87
|
async function runCrime({ channel, waitForDankMemer, safeAnswers }) {
|
|
87
88
|
LOG.cmd(`${c.white}${c.bold}pls crime${c.reset}`);
|
|
88
89
|
|
|
89
|
-
await channel
|
|
90
|
+
await sendCommand(channel, 'crime', { useSlash, prefix });
|
|
90
91
|
const response = await waitForDankMemer(10000);
|
|
91
92
|
|
|
92
93
|
if (!response) {
|
package/lib/commands/deposit.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
const {
|
|
7
7
|
LOG, c, getFullText, parseCoins, logMsg, isHoldTight, getHoldTightReason, sleep,
|
|
8
|
+
sendCommand,
|
|
8
9
|
} = require('./utils');
|
|
9
10
|
|
|
10
11
|
/**
|
|
@@ -16,7 +17,7 @@ const {
|
|
|
16
17
|
async function runDeposit({ channel, waitForDankMemer }) {
|
|
17
18
|
LOG.cmd(`${c.white}${c.bold}pls dep max${c.reset}`);
|
|
18
19
|
|
|
19
|
-
await channel
|
|
20
|
+
await sendCommand(channel, 'dep max', { useSlash, prefix });
|
|
20
21
|
const response = await waitForDankMemer(10000);
|
|
21
22
|
|
|
22
23
|
if (!response) {
|
package/lib/commands/dig.js
CHANGED
|
@@ -7,6 +7,7 @@ const {
|
|
|
7
7
|
LOG, c, getFullText, parseCoins, getAllButtons, safeClickButton, humanDelay,
|
|
8
8
|
logMsg, isHoldTight, getHoldTightReason, sleep, needsItem,
|
|
9
9
|
isCV2, ensureCV2, stripAnsi, checkLevelLock,
|
|
10
|
+
sendCommand,
|
|
10
11
|
} = require('./utils');
|
|
11
12
|
const { buyItem } = require('./shop');
|
|
12
13
|
|
|
@@ -96,7 +97,7 @@ async function resolveDigFlow({ channel, waitForDankMemer, response }) {
|
|
|
96
97
|
async function runDig({ channel, waitForDankMemer, client }) {
|
|
97
98
|
LOG.cmd(`${c.white}${c.bold}pls dig${c.reset}`);
|
|
98
99
|
|
|
99
|
-
await channel
|
|
100
|
+
await sendCommand(channel, 'dig', { useSlash, prefix });
|
|
100
101
|
const response = await waitForDankMemer(10000);
|
|
101
102
|
|
|
102
103
|
if (!response) {
|
|
@@ -142,7 +143,7 @@ async function runDig({ channel, waitForDankMemer, client }) {
|
|
|
142
143
|
while (await waitForDankMemer(1500)) { /* drain */ }
|
|
143
144
|
await sleep(1000);
|
|
144
145
|
|
|
145
|
-
await channel
|
|
146
|
+
await sendCommand(channel, 'dig', { useSlash, prefix });
|
|
146
147
|
const r2 = await waitForDankMemer(10000);
|
|
147
148
|
if (r2) {
|
|
148
149
|
if (isCV2(r2)) await ensureCV2(r2);
|
package/lib/commands/drops.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const {
|
|
2
2
|
LOG, c, getFullText, parseCoins, getAllButtons,
|
|
3
3
|
safeClickButton, logMsg, isHoldTight, getHoldTightReason, sleep, humanDelay,
|
|
4
|
+
sendCommand,
|
|
4
5
|
} = require('./utils');
|
|
5
6
|
|
|
6
7
|
const RE_BLOCK_SPLIT = /\n\n+/;
|
|
@@ -16,7 +17,7 @@ const RE_WHITESPACE_UNDERSCORE = /\s+/g;
|
|
|
16
17
|
async function runDrops({ channel, waitForDankMemer, redis, accountId }) {
|
|
17
18
|
LOG.cmd(`${c.white}${c.bold}pls drops${c.reset}`);
|
|
18
19
|
|
|
19
|
-
await channel
|
|
20
|
+
await sendCommand(channel, 'drops', { useSlash, prefix });
|
|
20
21
|
const response = await waitForDankMemer(10000);
|
|
21
22
|
|
|
22
23
|
if (!response) return { result: 'no response', coins: 0 };
|
package/lib/commands/farm.js
CHANGED
|
@@ -2,6 +2,7 @@ const {
|
|
|
2
2
|
LOG, c, getFullText, parseCoins, getAllButtons, getAllSelectMenus,
|
|
3
3
|
safeClickButton, logMsg, isHoldTight, getHoldTightReason, sleep, humanDelay,
|
|
4
4
|
isCV2, ensureCV2, stripAnsi, needsItem, clickCV2SelectMenu, checkLevelLock,
|
|
5
|
+
sendCommand,
|
|
5
6
|
} = require('./utils');
|
|
6
7
|
const { buyItem, buyItemsBatch } = require('./shop');
|
|
7
8
|
const rawLogger = require('../../lib/rawLogger');
|
|
@@ -1295,7 +1296,7 @@ async function advancePastConfirmation(response, waitForDankMemer) {
|
|
|
1295
1296
|
async function runFarm({ channel, waitForDankMemer, client, redis, accountId, forceRun }) {
|
|
1296
1297
|
LOG.cmd(`${c.white}${c.bold}pls farm view${c.reset}`);
|
|
1297
1298
|
|
|
1298
|
-
await channel
|
|
1299
|
+
await sendCommand(channel, 'farm view', { useSlash, prefix });
|
|
1299
1300
|
let response = await waitForDankMemer(12000);
|
|
1300
1301
|
|
|
1301
1302
|
if (!response) {
|
|
@@ -1322,7 +1323,7 @@ async function runFarm({ channel, waitForDankMemer, client, redis, accountId, fo
|
|
|
1322
1323
|
// Subcommand required — retry once.
|
|
1323
1324
|
if (lower.includes('must specify a subcommand')) {
|
|
1324
1325
|
LOG.warn('[farm] Subcommand required; retrying "pls farm view"');
|
|
1325
|
-
await channel
|
|
1326
|
+
await sendCommand(channel, 'farm view', { useSlash, prefix });
|
|
1326
1327
|
const retry = await waitForDankMemer(12000);
|
|
1327
1328
|
if (!retry) return { result: 'no response after farm view retry', coins: 0, nextCooldownSec: 120 };
|
|
1328
1329
|
response = retry;
|
|
@@ -1383,7 +1384,7 @@ async function runFarm({ channel, waitForDankMemer, client, redis, accountId, fo
|
|
|
1383
1384
|
LOG.success(`[farm] Auto-bought ${bought.itemName}. Retrying farm flow...`);
|
|
1384
1385
|
await sleep(1200);
|
|
1385
1386
|
// Retry once with the same flow.
|
|
1386
|
-
await channel
|
|
1387
|
+
await sendCommand(channel, 'farm view', { useSlash, prefix });
|
|
1387
1388
|
response = await waitForDankMemer(12000);
|
|
1388
1389
|
if (!response) return { result: 'no response after retry', coins: 0, nextCooldownSec: 90 };
|
|
1389
1390
|
if (isCV2(response)) await ensureCV2(response);
|
|
@@ -1474,7 +1475,7 @@ async function runFarm({ channel, waitForDankMemer, client, redis, accountId, fo
|
|
|
1474
1475
|
LOG.success(`[farm] Bought ${missing}. Retrying cycle...`);
|
|
1475
1476
|
await sleep(1200);
|
|
1476
1477
|
// Restart the whole cycle after buying
|
|
1477
|
-
await channel
|
|
1478
|
+
await sendCommand(channel, 'farm view', { useSlash, prefix });
|
|
1478
1479
|
const re = await waitForDankMemer(12000);
|
|
1479
1480
|
if (!re) return { result: 'no response after restock retry', coins: 0, nextCooldownSec: 90 };
|
|
1480
1481
|
if (isCV2(re)) await ensureCV2(re);
|
package/lib/commands/fish.js
CHANGED
|
@@ -18,10 +18,12 @@ const {
|
|
|
18
18
|
LOG, c, getFullText, parseCoins, getAllButtons, safeClickButton,
|
|
19
19
|
logMsg, isHoldTight, getHoldTightReason, sleep, humanDelay,
|
|
20
20
|
isCV2, ensureCV2, checkLevelLock,
|
|
21
|
+
sendCommand,
|
|
21
22
|
} = require('./utils');
|
|
22
23
|
const { downloadImage, extractImageUrl, findSafeCells } = require('./fishVision');
|
|
23
24
|
|
|
24
|
-
const { DANK_MEMER_ID
|
|
25
|
+
const { DANK_MEMER_ID sendCommand,
|
|
26
|
+
} = require('./utils');
|
|
25
27
|
|
|
26
28
|
const RE_FISH_COOLDOWN_TS = /<t:(\d+):R>/;
|
|
27
29
|
const RE_FISH_HEADER = /###\s*(.+?)(?:\s*-#|$)/;
|
|
@@ -41,7 +43,7 @@ async function refetchMsg(channel, msgId) {
|
|
|
41
43
|
*/
|
|
42
44
|
async function sellAllFish({ channel, waitForDankMemer, sellFor = 'tokens' }) {
|
|
43
45
|
LOG.info('[fish] Selling all fish from buckets...');
|
|
44
|
-
await channel
|
|
46
|
+
await sendCommand(channel, 'fish buckets', { useSlash, prefix });
|
|
45
47
|
let msg = await waitForDankMemer(8000);
|
|
46
48
|
if (!msg) { LOG.warn('[fish] No response to pls fish buckets'); return false; }
|
|
47
49
|
let fresh = await refetchMsg(channel, msg.id);
|
|
@@ -308,7 +310,7 @@ async function playFishRound({ gameMsg, channel, msgId, waitForDankMemer }) {
|
|
|
308
310
|
async function runFish({ channel, waitForDankMemer }) {
|
|
309
311
|
LOG.cmd(`${c.white}${c.bold}pls fish catch${c.reset}`);
|
|
310
312
|
|
|
311
|
-
await channel
|
|
313
|
+
await sendCommand(channel, 'fish catch', { useSlash, prefix });
|
|
312
314
|
let response = await waitForDankMemer(10000);
|
|
313
315
|
if (!response) return { result: 'no response', coins: 0 };
|
|
314
316
|
|
|
@@ -393,7 +395,7 @@ async function runFish({ channel, waitForDankMemer }) {
|
|
|
393
395
|
async function runFishLoop({ channel, waitForDankMemer, maxRounds = 50, onRound, signal }) {
|
|
394
396
|
LOG.cmd(`${c.white}${c.bold}pls fish catch${c.reset} (loop mode, max ${maxRounds} rounds)`);
|
|
395
397
|
|
|
396
|
-
await channel
|
|
398
|
+
await sendCommand(channel, 'fish catch', { useSlash, prefix });
|
|
397
399
|
let response = await waitForDankMemer(10000);
|
|
398
400
|
if (!response) return { totalRounds: 0, totalCaught: 0, totalMines: 0, results: [] };
|
|
399
401
|
|
|
@@ -437,7 +439,7 @@ async function runFishLoop({ channel, waitForDankMemer, maxRounds = 50, onRound,
|
|
|
437
439
|
await sellAllFish({ channel, waitForDankMemer });
|
|
438
440
|
|
|
439
441
|
// Re-send command to get fresh dashboard after sell
|
|
440
|
-
await channel
|
|
442
|
+
await sendCommand(channel, 'fish catch', { useSlash, prefix });
|
|
441
443
|
let newDash = await waitForDankMemer(8000);
|
|
442
444
|
if (newDash) {
|
|
443
445
|
let freshDash = await refetchMsg(channel, newDash.id);
|
|
@@ -569,7 +571,7 @@ async function runFishLoop({ channel, waitForDankMemer, maxRounds = 50, onRound,
|
|
|
569
571
|
// Approach 2: If Fish Again not found, re-send "pls fish catch" fresh
|
|
570
572
|
if (!fishAgainClicked) {
|
|
571
573
|
LOG.debug('[fish] Fish Again not found, re-sending pls fish catch');
|
|
572
|
-
await channel
|
|
574
|
+
await sendCommand(channel, 'fish catch', { useSlash, prefix });
|
|
573
575
|
let newResp = await waitForDankMemer(8000);
|
|
574
576
|
if (!newResp) { LOG.warn('[fish] No response to re-send'); break; }
|
|
575
577
|
let freshResp = await refetchMsg(channel, newResp.id);
|
package/lib/commands/gamble.js
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
const {
|
|
13
13
|
LOG, c, getFullText, parseCoins, parseNetCoins, getAllButtons, safeClickButton,
|
|
14
14
|
logMsg, isHoldTight, getHoldTightReason, sleep, humanDelay, ensureCV2, checkLevelLock,
|
|
15
|
+
sendCommand,
|
|
15
16
|
} = require('./utils');
|
|
16
17
|
const { EMA, AhoCorasick, SlidingWindowCounter } = require('../structures');
|
|
17
18
|
|
|
@@ -143,10 +144,11 @@ async function clickFast(msg, btn, retries = 2) {
|
|
|
143
144
|
/**
|
|
144
145
|
* Cointoss — CV2 format. Pick Heads/Tails randomly.
|
|
145
146
|
*/
|
|
146
|
-
async function runCointoss({ channel, waitForDankMemer, betAmount = 10000 }) {
|
|
147
|
-
const
|
|
147
|
+
async function runCointoss({ channel, waitForDankMemer, betAmount = 10000, useSlash, prefix = 'pls' }) {
|
|
148
|
+
const cmdName = 'cointoss';
|
|
149
|
+
const cmd = `${prefix} ${cmdName} ${betAmount}`;
|
|
148
150
|
LOG.cmd(`${c.white}${c.bold}${cmd}${c.reset}`);
|
|
149
|
-
await channel
|
|
151
|
+
await sendCommand(channel, cmdName, { useSlash, prefix, args: [betAmount] });
|
|
150
152
|
let response = await waitForDankMemer(12000);
|
|
151
153
|
|
|
152
154
|
await ensureCV2(response);
|
|
@@ -184,12 +186,13 @@ async function runCointoss({ channel, waitForDankMemer, betAmount = 10000 }) {
|
|
|
184
186
|
* Roulette — pick color, click button, wait for result.
|
|
185
187
|
* Strategy: ~47.5% red, ~47.5% black, ~5% green.
|
|
186
188
|
*/
|
|
187
|
-
async function runRoulette({ channel, waitForDankMemer, betAmount = 10000 }) {
|
|
189
|
+
async function runRoulette({ channel, waitForDankMemer, betAmount = 10000, useSlash, prefix = 'pls' }) {
|
|
188
190
|
const roll = Math.random();
|
|
189
191
|
const color = roll < 0.475 ? 'red' : roll < 0.95 ? 'black' : 'green';
|
|
190
|
-
const
|
|
192
|
+
const cmdName = 'roulette';
|
|
193
|
+
const cmd = `${prefix} ${cmdName} ${betAmount} ${color}`;
|
|
191
194
|
LOG.cmd(`${c.white}${c.bold}${cmd}${c.reset}`);
|
|
192
|
-
await channel
|
|
195
|
+
await sendCommand(channel, cmdName, { useSlash, prefix, args: [betAmount, color] });
|
|
193
196
|
let response = await waitForDankMemer(12000);
|
|
194
197
|
|
|
195
198
|
const chk = await commonChecks(response, 'roulette');
|
|
@@ -227,10 +230,11 @@ async function runRoulette({ channel, waitForDankMemer, betAmount = 10000 }) {
|
|
|
227
230
|
/**
|
|
228
231
|
* Slots — auto-spin, wait for animation to finish, parse result.
|
|
229
232
|
*/
|
|
230
|
-
async function runSlots({ channel, waitForDankMemer, betAmount = 10000 }) {
|
|
231
|
-
const
|
|
233
|
+
async function runSlots({ channel, waitForDankMemer, betAmount = 10000, useSlash, prefix = 'pls' }) {
|
|
234
|
+
const cmdName = 'slots';
|
|
235
|
+
const cmd = `${prefix} ${cmdName} ${betAmount}`;
|
|
232
236
|
LOG.cmd(`${c.white}${c.bold}${cmd}${c.reset}`);
|
|
233
|
-
await channel
|
|
237
|
+
await sendCommand(channel, cmdName, { useSlash, prefix, args: [betAmount] });
|
|
234
238
|
let response = await waitForDankMemer(12000);
|
|
235
239
|
|
|
236
240
|
const chk = await commonChecks(response, 'slots');
|
|
@@ -258,10 +262,11 @@ async function runSlots({ channel, waitForDankMemer, betAmount = 10000 }) {
|
|
|
258
262
|
/**
|
|
259
263
|
* Snakeeyes — auto-roll, wait for animation to finish, parse result.
|
|
260
264
|
*/
|
|
261
|
-
async function runSnakeeyes({ channel, waitForDankMemer, betAmount = 10000 }) {
|
|
262
|
-
const
|
|
265
|
+
async function runSnakeeyes({ channel, waitForDankMemer, betAmount = 10000, useSlash, prefix = 'pls' }) {
|
|
266
|
+
const cmdName = 'snakeeyes';
|
|
267
|
+
const cmd = `${prefix} ${cmdName} ${betAmount}`;
|
|
263
268
|
LOG.cmd(`${c.white}${c.bold}${cmd}${c.reset}`);
|
|
264
|
-
await channel
|
|
269
|
+
await sendCommand(channel, cmdName, { useSlash, prefix, args: [betAmount] });
|
|
265
270
|
let response = await waitForDankMemer(12000);
|
|
266
271
|
|
|
267
272
|
const chk = await commonChecks(response, 'snakeeyes');
|
package/lib/commands/generic.js
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
const {
|
|
12
12
|
LOG, c, getFullText, parseCoins, getAllButtons, getAllSelectMenus,
|
|
13
13
|
safeClickButton, logMsg, isHoldTight, getHoldTightReason, sleep, humanDelay, needsItem,
|
|
14
|
-
isCV2, ensureCV2, stripAnsi,
|
|
14
|
+
isCV2, ensureCV2, stripAnsi, sendCommand,
|
|
15
15
|
} = require('./utils');
|
|
16
16
|
const { buyItem } = require('./shop');
|
|
17
17
|
const { AhoCorasick, LRUCache } = require('../structures');
|
|
@@ -50,10 +50,15 @@ async function waitForEditedMessage(channel, messageId, baselineText, timeoutMs
|
|
|
50
50
|
* @param {object} [opts.client]
|
|
51
51
|
* @returns {Promise<{result: string, coins: number}>}
|
|
52
52
|
*/
|
|
53
|
-
async function runGeneric({ channel, waitForDankMemer, cmdString, cmdName, client }) {
|
|
53
|
+
async function runGeneric({ channel, waitForDankMemer, cmdString, cmdName, client, useSlash, prefix = 'pls' }) {
|
|
54
54
|
LOG.cmd(`${c.white}${c.bold}${cmdString}${c.reset}`);
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
// cmdString = "pls farm view" or "/farm view"
|
|
56
|
+
// Build slash command: strip prefix → "farm view" → sendSlash('farm view')
|
|
57
|
+
const slashName = cmdString
|
|
58
|
+
.replace(/^pls\s+/, '')
|
|
59
|
+
.replace(/^\/\s*/, '')
|
|
60
|
+
.trim();
|
|
61
|
+
await sendCommand(channel, slashName, { useSlash, prefix });
|
|
57
62
|
let response = await waitForDankMemer(10000);
|
|
58
63
|
|
|
59
64
|
if (!response) {
|
|
@@ -82,7 +87,7 @@ async function runGeneric({ channel, waitForDankMemer, cmdString, cmdName, clien
|
|
|
82
87
|
if (bought) {
|
|
83
88
|
LOG.success(`[${cmdName}] Bought ${missing}, retrying command...`);
|
|
84
89
|
await sleep(1500);
|
|
85
|
-
await channel
|
|
90
|
+
await sendCommand(channel, cmdName, { useSlash, prefix });
|
|
86
91
|
const r2 = await waitForDankMemer(10000);
|
|
87
92
|
if (r2) {
|
|
88
93
|
logMsg(r2, `${cmdName}-retry`);
|
|
@@ -209,7 +214,7 @@ async function runGeneric({ channel, waitForDankMemer, cmdString, cmdName, clien
|
|
|
209
214
|
async function runAlert({ channel, waitForDankMemer }) {
|
|
210
215
|
LOG.cmd(`${c.white}${c.bold}pls alert${c.reset}`);
|
|
211
216
|
|
|
212
|
-
await channel
|
|
217
|
+
await sendCommand(channel, 'alert', { useSlash, prefix });
|
|
213
218
|
const response = await waitForDankMemer(10000);
|
|
214
219
|
|
|
215
220
|
if (!response) return { result: 'no response', coins: 0 };
|
package/lib/commands/highlow.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
const {
|
|
8
8
|
LOG, c, getFullText, parseCoins, getAllButtons, safeClickButton,
|
|
9
9
|
logMsg, isHoldTight, getHoldTightReason, sleep, checkLevelLock,
|
|
10
|
+
sendCommand,
|
|
10
11
|
} = require('./utils');
|
|
11
12
|
|
|
12
13
|
const RE_HINT_BOLD = /hint.*?\*\*(\d+)\*\*/i;
|
|
@@ -129,7 +130,7 @@ async function playHighLow(response, depth = 0) {
|
|
|
129
130
|
async function runHighLow({ channel, waitForDankMemer }) {
|
|
130
131
|
LOG.cmd(`${c.white}${c.bold}pls hl${c.reset}`);
|
|
131
132
|
|
|
132
|
-
await channel
|
|
133
|
+
await sendCommand(channel, 'hl', { useSlash, prefix });
|
|
133
134
|
const response = await waitForDankMemer(12000);
|
|
134
135
|
|
|
135
136
|
if (!response) {
|
package/lib/commands/hunt.js
CHANGED
|
@@ -8,6 +8,7 @@ const {
|
|
|
8
8
|
LOG, c, getFullText, parseCoins, getAllButtons, safeClickButton,
|
|
9
9
|
logMsg, isHoldTight, getHoldTightReason, sleep, needsItem,
|
|
10
10
|
isCV2, ensureCV2, stripAnsi, checkLevelLock,
|
|
11
|
+
sendCommand,
|
|
11
12
|
} = require('./utils');
|
|
12
13
|
const { buyItem } = require('./shop');
|
|
13
14
|
|
|
@@ -80,7 +81,7 @@ function pickDodgeLane(dragonPos, buttons) {
|
|
|
80
81
|
async function runHunt({ channel, waitForDankMemer, client }) {
|
|
81
82
|
LOG.cmd(`${c.white}${c.bold}pls hunt${c.reset}`);
|
|
82
83
|
|
|
83
|
-
await channel
|
|
84
|
+
await sendCommand(channel, 'hunt', { useSlash, prefix });
|
|
84
85
|
const response = await waitForDankMemer(12000);
|
|
85
86
|
|
|
86
87
|
if (!response) {
|
|
@@ -118,7 +119,7 @@ async function runHunt({ channel, waitForDankMemer, client }) {
|
|
|
118
119
|
LOG.success('[hunt] Rifle bought! Retrying...');
|
|
119
120
|
while (await waitForDankMemer(1500)) {}
|
|
120
121
|
await sleep(1000);
|
|
121
|
-
await channel
|
|
122
|
+
await sendCommand(channel, 'hunt', { useSlash, prefix });
|
|
122
123
|
const r2 = await waitForDankMemer(12000);
|
|
123
124
|
if (r2) {
|
|
124
125
|
if (isCV2(r2)) await ensureCV2(r2);
|
|
@@ -15,6 +15,7 @@ const {
|
|
|
15
15
|
LOG, c, sleep, humanDelay, getFullText, getAllButtons,
|
|
16
16
|
safeClickButton, logMsg, isHoldTight, getHoldTightReason,
|
|
17
17
|
isCV2, ensureCV2,
|
|
18
|
+
sendCommand,
|
|
18
19
|
} = require('./utils');
|
|
19
20
|
const { Trie, LRUCache } = require('../structures');
|
|
20
21
|
|
|
@@ -197,7 +198,7 @@ async function enrichItems(items) {
|
|
|
197
198
|
async function runInventory({ channel, waitForDankMemer, client, accountId, redis, onPageProgress }) {
|
|
198
199
|
LOG.cmd(`${c.white}${c.bold}pls inv${c.reset}`);
|
|
199
200
|
|
|
200
|
-
await channel
|
|
201
|
+
await sendCommand(channel, 'inv', { useSlash, prefix });
|
|
201
202
|
let response = await waitForDankMemer(10000);
|
|
202
203
|
|
|
203
204
|
if (!response) {
|
|
@@ -16,6 +16,7 @@ const {
|
|
|
16
16
|
LOG, c, getFullText, parseCoins, getAllButtons, getAllSelectMenus,
|
|
17
17
|
findButton, safeClickButton, logMsg, isHoldTight, getHoldTightReason,
|
|
18
18
|
sleep, humanDelay, checkLevelLock,
|
|
19
|
+
sendCommand,
|
|
19
20
|
} = require('./utils');
|
|
20
21
|
|
|
21
22
|
const RE_COOLDOWN_MIN = /(\d+)\s*minute/i;
|
|
@@ -37,7 +38,7 @@ async function refetchMsg(channel, msgId) {
|
|
|
37
38
|
async function runPostMemes({ channel, waitForDankMemer }) {
|
|
38
39
|
LOG.cmd(`${c.white}${c.bold}pls pm${c.reset}`);
|
|
39
40
|
|
|
40
|
-
await channel
|
|
41
|
+
await sendCommand(channel, 'pm', { useSlash, prefix });
|
|
41
42
|
let response = await waitForDankMemer(10000);
|
|
42
43
|
|
|
43
44
|
if (!response) {
|
package/lib/commands/profile.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
const {
|
|
9
9
|
LOG, c, getFullText, logMsg, isHoldTight, sleep, stripAnsi,
|
|
10
|
+
sendCommand,
|
|
10
11
|
} = require('./utils');
|
|
11
12
|
|
|
12
13
|
const CACHE_TTL = 10 * 60 * 1000; // 10 minutes
|
|
@@ -175,7 +176,7 @@ async function getPlayerLevel({ channel, waitForDankMemer, accountId = 'default'
|
|
|
175
176
|
}
|
|
176
177
|
} catch {}
|
|
177
178
|
}
|
|
178
|
-
await channel
|
|
179
|
+
await sendCommand(channel, 'profile', { useSlash, prefix });
|
|
179
180
|
const response = await waitForDankMemer(8000);
|
|
180
181
|
if (!response) { LOG.warn('[profile] No response'); return null; }
|
|
181
182
|
if (isHoldTight(response)) { await sleep(5000); return null; }
|
|
@@ -202,7 +203,7 @@ async function getPlayerLevel({ channel, waitForDankMemer, accountId = 'default'
|
|
|
202
203
|
*/
|
|
203
204
|
async function runProfile({ channel, waitForDankMemer, accountId = 'default', redis }) {
|
|
204
205
|
LOG.cmd(`${c.white}${c.bold}pls profile${c.reset}`);
|
|
205
|
-
await channel
|
|
206
|
+
await sendCommand(channel, 'profile', { useSlash, prefix });
|
|
206
207
|
const response = await waitForDankMemer(8000);
|
|
207
208
|
if (!response) {
|
|
208
209
|
LOG.warn('[profile] No response');
|
package/lib/commands/scratch.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
const {
|
|
8
8
|
LOG, c, getFullText, parseCoins, getAllButtons, safeClickButton,
|
|
9
9
|
logMsg, isHoldTight, getHoldTightReason, sleep, humanDelay, checkLevelLock,
|
|
10
|
+
sendCommand,
|
|
10
11
|
} = require('./utils');
|
|
11
12
|
const { meetsLevelRequirement } = require('./profile');
|
|
12
13
|
|
|
@@ -27,7 +28,7 @@ async function runScratch({ channel, waitForDankMemer, accountId, redis }) {
|
|
|
27
28
|
}
|
|
28
29
|
LOG.cmd(`${c.white}${c.bold}pls scratch${c.reset}`);
|
|
29
30
|
|
|
30
|
-
await channel
|
|
31
|
+
await sendCommand(channel, 'scratch', { useSlash, prefix });
|
|
31
32
|
const response = await waitForDankMemer(10000);
|
|
32
33
|
|
|
33
34
|
if (!response) {
|
package/lib/commands/search.js
CHANGED
|
@@ -12,6 +12,7 @@ const {
|
|
|
12
12
|
LOG, c, getFullText, parseCoins, getAllButtons, safeClickButton,
|
|
13
13
|
logMsg, isHoldTight, getHoldTightReason, sleep, humanDelay,
|
|
14
14
|
isCV2, ensureCV2, checkLevelLock,
|
|
15
|
+
sendCommand,
|
|
15
16
|
} = require('./utils');
|
|
16
17
|
const { VoseAlias, Trie, EMA, LRUCache } = require('../structures');
|
|
17
18
|
|
|
@@ -84,7 +85,7 @@ function pickSafeButton(buttons, customSafe) {
|
|
|
84
85
|
async function runSearch({ channel, waitForDankMemer, safeAnswers }) {
|
|
85
86
|
LOG.cmd(`${c.white}${c.bold}pls search${c.reset}`);
|
|
86
87
|
|
|
87
|
-
await channel
|
|
88
|
+
await sendCommand(channel, 'search', { useSlash, prefix });
|
|
88
89
|
const response = await waitForDankMemer(10000);
|
|
89
90
|
|
|
90
91
|
if (!response) {
|
package/lib/commands/shop.js
CHANGED
|
@@ -17,6 +17,7 @@ const {
|
|
|
17
17
|
LOG, c, sleep, humanDelay, getFullText,
|
|
18
18
|
getAllButtons, findSelectMenuOption, getAllSelectMenus, safeClickButton,
|
|
19
19
|
logMsg, isHoldTight, isCV2, ensureCV2, stripAnsi,
|
|
20
|
+
sendCommand,
|
|
20
21
|
} = require('./utils');
|
|
21
22
|
const { LRUCache, Trie } = require('../structures');
|
|
22
23
|
|
|
@@ -135,7 +136,7 @@ function normalizeShopRequest(itemName, quantity = 1) {
|
|
|
135
136
|
}
|
|
136
137
|
|
|
137
138
|
async function openShopView({ channel, waitForDankMemer }) {
|
|
138
|
-
await channel
|
|
139
|
+
await sendCommand(channel, 'shop view', { useSlash, prefix });
|
|
139
140
|
let response = await waitForDankMemer(10000);
|
|
140
141
|
|
|
141
142
|
if (!response) return { ok: false, reason: 'no-response', response: null };
|
package/lib/commands/stream.js
CHANGED
|
@@ -2,6 +2,7 @@ const {
|
|
|
2
2
|
LOG, c, getFullText, parseCoins, getAllButtons, getAllSelectMenus,
|
|
3
3
|
safeClickButton, logMsg, isHoldTight, getHoldTightReason, sleep, humanDelay, needsItem,
|
|
4
4
|
isCV2, ensureCV2, stripAnsi, clickCV2Button, checkLevelLock,
|
|
5
|
+
sendCommand,
|
|
5
6
|
} = require('./utils');
|
|
6
7
|
const { buyItem } = require('./shop');
|
|
7
8
|
|
|
@@ -196,7 +197,7 @@ async function selectRandomStreamOption(msg) {
|
|
|
196
197
|
async function runStream({ channel, waitForDankMemer, client }) {
|
|
197
198
|
LOG.cmd(`${c.white}${c.bold}pls stream${c.reset}`);
|
|
198
199
|
|
|
199
|
-
await channel
|
|
200
|
+
await sendCommand(channel, 'stream', { useSlash, prefix });
|
|
200
201
|
let response = await waitForDankMemer(12000);
|
|
201
202
|
|
|
202
203
|
if (!response) {
|
|
@@ -238,7 +239,7 @@ async function runStream({ channel, waitForDankMemer, client }) {
|
|
|
238
239
|
}
|
|
239
240
|
|
|
240
241
|
await sleep(800);
|
|
241
|
-
await channel
|
|
242
|
+
await sendCommand(channel, 'stream', { useSlash, prefix });
|
|
242
243
|
response = await waitForDankMemer(12000);
|
|
243
244
|
if (!response) return { result: 'no response after buy', coins: 0, nextCooldownSec: 180 };
|
|
244
245
|
await hydrate(response);
|
package/lib/commands/trivia.js
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
const {
|
|
11
11
|
LOG, c, getFullText, parseCoins, getAllButtons, safeClickButton,
|
|
12
12
|
logMsg, isHoldTight, getHoldTightReason, sleep, humanDelay, checkLevelLock,
|
|
13
|
+
sendCommand,
|
|
13
14
|
} = require('./utils');
|
|
14
15
|
|
|
15
16
|
const RE_TRIVIA_MD_BOLD = /\*\*/g;
|
|
@@ -79,7 +80,7 @@ async function learnFromResult(question, correctAnswer, redis) {
|
|
|
79
80
|
async function runTrivia({ channel, waitForDankMemer, redis }) {
|
|
80
81
|
LOG.cmd(`${c.white}${c.bold}pls trivia${c.reset}`);
|
|
81
82
|
|
|
82
|
-
await channel
|
|
83
|
+
await sendCommand(channel, 'trivia', { useSlash, prefix });
|
|
83
84
|
const response = await waitForDankMemer(10000);
|
|
84
85
|
|
|
85
86
|
if (!response) {
|
package/lib/commands/utils.js
CHANGED
|
@@ -54,6 +54,34 @@ const c = {
|
|
|
54
54
|
magenta: '\x1b[35m', white: '\x1b[37m', blue: '\x1b[34m',
|
|
55
55
|
};
|
|
56
56
|
|
|
57
|
+
// ── Slash Command Helper (dmg pattern) ──────────────────────
|
|
58
|
+
// Wraps channel.send for slash commands — uses Discord interaction API
|
|
59
|
+
// when use_slash=true, falls back to text prefix (pls or /) otherwise.
|
|
60
|
+
// Usage: await sendCommand(channel, 'adventure', { useSlash: true, prefix: '/' })
|
|
61
|
+
async function sendCommand(channel, commandName, opts = {}) {
|
|
62
|
+
const {
|
|
63
|
+
useSlash = false,
|
|
64
|
+
prefix = 'pls',
|
|
65
|
+
args = [],
|
|
66
|
+
} = opts;
|
|
67
|
+
|
|
68
|
+
if (useSlash && channel?.sendSlash) {
|
|
69
|
+
try {
|
|
70
|
+
// sendSlash takes botId, commandName, ...args
|
|
71
|
+
await channel.sendSlash(DANK_MEMER_ID, commandName, ...args);
|
|
72
|
+
return;
|
|
73
|
+
} catch (e) {
|
|
74
|
+
LOG.warn(`[sendSlash] ${commandName} failed: ${e.message} — falling back to text`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Fallback: text command
|
|
79
|
+
const textCmd = args.length > 0
|
|
80
|
+
? `${prefix} ${commandName} ${args.join(' ')}`
|
|
81
|
+
: `${prefix} ${commandName}`;
|
|
82
|
+
await channel.send(textCmd);
|
|
83
|
+
}
|
|
84
|
+
|
|
57
85
|
// ── Logging ──────────────────────────────────────────────────
|
|
58
86
|
// When dashboard is active, suppress direct console output from command handlers.
|
|
59
87
|
// grinder.js sets this to true once the live dashboard starts rendering.
|
|
@@ -765,6 +793,7 @@ module.exports = {
|
|
|
765
793
|
getFullText,
|
|
766
794
|
stripAnsi,
|
|
767
795
|
parseCoins,
|
|
796
|
+
sendCommand,
|
|
768
797
|
parseNetCoins,
|
|
769
798
|
parseBalance,
|
|
770
799
|
getAllButtons,
|
package/lib/commands/work.js
CHANGED
|
@@ -19,6 +19,7 @@ const {
|
|
|
19
19
|
LOG, c, getFullText, parseCoins, getAllButtons, safeClickButton,
|
|
20
20
|
logMsg, isHoldTight, getHoldTightReason, sleep, humanDelay,
|
|
21
21
|
isCV2, ensureCV2, stripAnsi, checkLevelLock,
|
|
22
|
+
sendCommand,
|
|
22
23
|
} = require('./utils');
|
|
23
24
|
|
|
24
25
|
const RE_MEMORY_BACKTICK_CHUNK = /`([^`]+)`/g;
|
|
@@ -142,7 +143,7 @@ function parseWorkCooldown(text) {
|
|
|
142
143
|
*/
|
|
143
144
|
async function resignFromJob({ channel, waitForDankMemer }) {
|
|
144
145
|
LOG.info('[work] Resigning from current job...');
|
|
145
|
-
await channel
|
|
146
|
+
await sendCommand(channel, 'work resign', { useSlash, prefix });
|
|
146
147
|
const response = await waitForDankMemer(8000);
|
|
147
148
|
if (!response) { LOG.warn('[work] No response to resign'); return false; }
|
|
148
149
|
logMsg(response, 'work-resign');
|
|
@@ -175,7 +176,7 @@ async function resignFromJob({ channel, waitForDankMemer }) {
|
|
|
175
176
|
*/
|
|
176
177
|
async function autoApplyForJob({ channel, waitForDankMemer }) {
|
|
177
178
|
LOG.info('[work] No job! Applying for Babysitter...');
|
|
178
|
-
await channel
|
|
179
|
+
await sendCommand(channel, 'work apply babysitter', { useSlash, prefix });
|
|
179
180
|
const response = await waitForDankMemer(10000);
|
|
180
181
|
if (!response) {
|
|
181
182
|
LOG.warn('[work] No response to apply');
|
|
@@ -406,7 +407,7 @@ async function handleGenericMinigame({ channel, current, waitForDankMemer }) {
|
|
|
406
407
|
async function runWorkShift({ channel, waitForDankMemer }) {
|
|
407
408
|
LOG.cmd(`${c.white}${c.bold}pls work shift${c.reset}`);
|
|
408
409
|
|
|
409
|
-
await channel
|
|
410
|
+
await sendCommand(channel, 'work shift', { useSlash, prefix });
|
|
410
411
|
let current = await waitForDankMemer(10000);
|
|
411
412
|
|
|
412
413
|
if (!current) {
|
|
@@ -453,7 +454,7 @@ async function runWorkShift({ channel, waitForDankMemer }) {
|
|
|
453
454
|
while (await waitForDankMemer(1500)) {}
|
|
454
455
|
await sleep(500);
|
|
455
456
|
|
|
456
|
-
await channel
|
|
457
|
+
await sendCommand(channel, 'work shift', { useSlash, prefix });
|
|
457
458
|
current = await waitForDankMemer(10000);
|
|
458
459
|
if (!current) return { result: 'no response after apply', coins: 0, nextCooldownSec: 180 };
|
|
459
460
|
if (isCV2(current)) await ensureCV2(current);
|
package/lib/grinder.js
CHANGED
|
@@ -1400,6 +1400,8 @@ class AccountWorker {
|
|
|
1400
1400
|
safeAnswers: cmdName === 'search' ? safeParseJSON(this.account.search_answers, []) :
|
|
1401
1401
|
cmdName === 'crime' ? safeParseJSON(this.account.crime_answers, []) : [],
|
|
1402
1402
|
adventureAnswers: AccountWorker.ADVENTURE_ANSWERS,
|
|
1403
|
+
useSlash: !!this.account.use_slash,
|
|
1404
|
+
prefix: this.account.use_slash ? '/' : 'pls',
|
|
1403
1405
|
betAmount: this._questBetOverride || (['blackjack'].includes(cmdName) ? bjBet : gambBet),
|
|
1404
1406
|
accountId: this.account.id,
|
|
1405
1407
|
redis,
|