dankgrinder 5.9.0 → 5.11.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/dig.js +1 -1
- package/lib/commands/hunt.js +1 -1
- package/lib/commands/shop.js +11 -3
- package/lib/commands/utils.js +8 -2
- package/lib/commands/work.js +27 -5
- package/package.json +1 -1
package/lib/commands/dig.js
CHANGED
|
@@ -42,7 +42,7 @@ async function runDig({ channel, waitForDankMemer, client }) {
|
|
|
42
42
|
const missing = needsItem(cleanText);
|
|
43
43
|
|
|
44
44
|
const shovelMissing = missing === 'shovel'
|
|
45
|
-
|| /(?:don't have|do not have|need|needs|requires?|missing|must have|you need|lack)\s+(?:a\s+)?shovel/.test(textLower)
|
|
45
|
+
|| /(?:don['’]?t have|do not have|need|needs|requires?|missing|must have|you need|lack)\s+(?:a\s+)?shovel/.test(textLower)
|
|
46
46
|
|| (textLower.includes('following items') && textLower.includes('shovel'));
|
|
47
47
|
|
|
48
48
|
// Check if we need a shovel
|
package/lib/commands/hunt.js
CHANGED
|
@@ -42,7 +42,7 @@ async function runHunt({ channel, waitForDankMemer, client }) {
|
|
|
42
42
|
const missing = needsItem(cleanText);
|
|
43
43
|
|
|
44
44
|
const rifleMissing = missing === 'hunting rifle'
|
|
45
|
-
|| /(?:don't have|do not have|need|needs|requires?|missing|must have|you need|lack)\s+(?:a\s+)?(?:hunting\s+)?rifle/.test(textLower)
|
|
45
|
+
|| /(?:don['’]?t have|do not have|need|needs|requires?|missing|must have|you need|lack)\s+(?:a\s+)?(?:hunting\s+)?rifle/.test(textLower)
|
|
46
46
|
|| ((textLower.includes('following items') || textLower.includes('missing items')) && textLower.includes('rifle'));
|
|
47
47
|
|
|
48
48
|
// Check if we need a rifle
|
package/lib/commands/shop.js
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
const {
|
|
17
17
|
LOG, c, sleep, humanDelay, getFullText,
|
|
18
18
|
getAllButtons, findSelectMenuOption,
|
|
19
|
-
logMsg, isHoldTight,
|
|
19
|
+
logMsg, isHoldTight, isCV2, ensureCV2,
|
|
20
20
|
} = require('./utils');
|
|
21
21
|
const { LRUCache, Trie } = require('../structures');
|
|
22
22
|
|
|
@@ -100,6 +100,8 @@ async function buyItem({ channel, waitForDankMemer, itemName, quantity = 1, clie
|
|
|
100
100
|
return false;
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
+
if (isCV2(response)) await ensureCV2(response);
|
|
104
|
+
|
|
103
105
|
logMsg(response, 'shop');
|
|
104
106
|
|
|
105
107
|
// Step 2: Switch shop tab if needed (e.g. Fishing Shop for fishing pole)
|
|
@@ -129,6 +131,7 @@ async function buyItem({ channel, waitForDankMemer, itemName, quantity = 1, clie
|
|
|
129
131
|
);
|
|
130
132
|
if (result) {
|
|
131
133
|
response = result;
|
|
134
|
+
if (isCV2(response)) await ensureCV2(response);
|
|
132
135
|
LOG.success(`Switched to ${targetTab}`);
|
|
133
136
|
}
|
|
134
137
|
await sleep(300);
|
|
@@ -141,9 +144,14 @@ async function buyItem({ channel, waitForDankMemer, itemName, quantity = 1, clie
|
|
|
141
144
|
|
|
142
145
|
// Step 3: Find the Buy button for our item
|
|
143
146
|
const allBtns = getAllButtons(response);
|
|
147
|
+
const normalizedSearch = String(searchTerm || '').toLowerCase().replace(/\s+/g, '');
|
|
148
|
+
const normalizedKey = String(key || '').toLowerCase().replace(/\s+/g, '');
|
|
144
149
|
const buyBtn = allBtns.find(b => {
|
|
145
|
-
|
|
146
|
-
|
|
150
|
+
const label = String(b.label || '').toLowerCase();
|
|
151
|
+
const id = String(b.customId || b.custom_id || '').toLowerCase().replace(/\s+/g, '');
|
|
152
|
+
return label.includes(searchTerm)
|
|
153
|
+
|| (normalizedSearch && id.includes(normalizedSearch))
|
|
154
|
+
|| (normalizedKey && id.includes(normalizedKey));
|
|
147
155
|
});
|
|
148
156
|
|
|
149
157
|
if (!buyBtn) {
|
package/lib/commands/utils.js
CHANGED
|
@@ -529,10 +529,16 @@ itemDetector.addPattern('missing items', '__multi__');
|
|
|
529
529
|
itemDetector.build();
|
|
530
530
|
|
|
531
531
|
function needsItem(text) {
|
|
532
|
-
const
|
|
532
|
+
const normalized = String(text || '')
|
|
533
|
+
.toLowerCase()
|
|
534
|
+
.normalize('NFKC')
|
|
535
|
+
.replace(/[’‘`´]/g, "'")
|
|
536
|
+
.replace(/\bdon'?t\b/g, "don't");
|
|
537
|
+
|
|
538
|
+
const match = itemDetector.hasAny(normalized);
|
|
533
539
|
if (!match) return null;
|
|
534
540
|
if (match === '__multi__') {
|
|
535
|
-
const lower =
|
|
541
|
+
const lower = normalized;
|
|
536
542
|
if (lower.includes('shovel')) return 'shovel';
|
|
537
543
|
if (lower.includes('fishing pole') || lower.includes('fishing')) return 'fishing pole';
|
|
538
544
|
if (lower.includes('hunting rifle') || lower.includes('rifle')) return 'hunting rifle';
|
package/lib/commands/work.js
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
const {
|
|
19
19
|
LOG, c, getFullText, parseCoins, getAllButtons, safeClickButton,
|
|
20
20
|
logMsg, isHoldTight, getHoldTightReason, sleep, humanDelay,
|
|
21
|
+
isCV2, ensureCV2, stripAnsi,
|
|
21
22
|
} = require('./utils');
|
|
22
23
|
|
|
23
24
|
const RE_MEMORY_BACKTICK_CHUNK = /`([^`]+)`/g;
|
|
@@ -26,6 +27,24 @@ const RE_WORK_COOLDOWN_TS = /<t:(\d+):R>/;
|
|
|
26
27
|
const RE_WORK_COOLDOWN_MINUTES = /(\d+)\s*minute/i;
|
|
27
28
|
const RE_WORK_COOLDOWN_HOURS = /(\d+)\s*hour/i;
|
|
28
29
|
|
|
30
|
+
function normalizeLower(text) {
|
|
31
|
+
return String(text || '')
|
|
32
|
+
.normalize('NFKC')
|
|
33
|
+
.replace(/[’‘`´]/g, "'")
|
|
34
|
+
.replace(/\bdon'?t\b/gi, "don't")
|
|
35
|
+
.toLowerCase();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function isNoJobText(text) {
|
|
39
|
+
const t = normalizeLower(stripAnsi(text)).replace(/\s+/g, ' ').trim();
|
|
40
|
+
return t.includes("don't currently have a job")
|
|
41
|
+
|| t.includes("don't have a job")
|
|
42
|
+
|| t.includes('no job to work at')
|
|
43
|
+
|| t.includes('you need a job')
|
|
44
|
+
|| t.includes('/work list')
|
|
45
|
+
|| (t.includes('work list') && t.includes('available jobs'));
|
|
46
|
+
}
|
|
47
|
+
|
|
29
48
|
// Job progression list (order matters — first is easiest to get)
|
|
30
49
|
const JOBS = Object.freeze([
|
|
31
50
|
'babysitter', 'dog walker', 'fast food worker', 'youtuber',
|
|
@@ -114,14 +133,15 @@ async function resignFromJob({ channel, waitForDankMemer }) {
|
|
|
114
133
|
async function autoApplyForJob({ channel, waitForDankMemer }) {
|
|
115
134
|
LOG.info('[work] No job! Applying for Babysitter...');
|
|
116
135
|
await channel.send('pls work apply babysitter');
|
|
117
|
-
const response = await waitForDankMemer(
|
|
136
|
+
const response = await waitForDankMemer(10000);
|
|
118
137
|
if (!response) {
|
|
119
138
|
LOG.warn('[work] No response to apply');
|
|
120
139
|
return { applied: false };
|
|
121
140
|
}
|
|
141
|
+
if (isCV2(response)) await ensureCV2(response);
|
|
122
142
|
logMsg(response, 'work-apply');
|
|
123
143
|
const text = getFullText(response);
|
|
124
|
-
const tl = text.
|
|
144
|
+
const tl = normalizeLower(stripAnsi(text)).replace(/\s+/g, ' ').trim();
|
|
125
145
|
if (tl.includes('congratulations') || tl.includes('now working')) {
|
|
126
146
|
LOG.success('[work] Applied for Babysitter!');
|
|
127
147
|
return { applied: true };
|
|
@@ -301,6 +321,8 @@ async function runWorkShift({ channel, waitForDankMemer }) {
|
|
|
301
321
|
return { result: `hold tight (${reason || 'unknown'})`, coins: 0, holdTightReason: reason };
|
|
302
322
|
}
|
|
303
323
|
|
|
324
|
+
if (isCV2(current)) await ensureCV2(current);
|
|
325
|
+
|
|
304
326
|
logMsg(current, 'work');
|
|
305
327
|
let text = getFullText(current);
|
|
306
328
|
|
|
@@ -314,11 +336,10 @@ async function runWorkShift({ channel, waitForDankMemer }) {
|
|
|
314
336
|
return { result: `work cooldown (${Math.ceil(cooldownSec / 60)}m)`, coins: 0, nextCooldownSec: cooldownSec };
|
|
315
337
|
}
|
|
316
338
|
|
|
317
|
-
const textLower = text.
|
|
339
|
+
const textLower = normalizeLower(stripAnsi(text)).replace(/\s+/g, ' ').trim();
|
|
318
340
|
|
|
319
341
|
// ── No job? Auto-apply ─────────────────────────────────────
|
|
320
|
-
if (
|
|
321
|
-
textLower.includes('you need a job') || textLower.includes('work list')) {
|
|
342
|
+
if (isNoJobText(textLower)) {
|
|
322
343
|
const applyResult = await autoApplyForJob({ channel, waitForDankMemer });
|
|
323
344
|
if (!applyResult.applied) {
|
|
324
345
|
return { result: 'no job (apply failed)', coins: 0, nextCooldownSec: applyResult.cooldownSec || 600 };
|
|
@@ -331,6 +352,7 @@ async function runWorkShift({ channel, waitForDankMemer }) {
|
|
|
331
352
|
await channel.send('pls work shift');
|
|
332
353
|
current = await waitForDankMemer(10000);
|
|
333
354
|
if (!current) return { result: 'no response after apply', coins: 0 };
|
|
355
|
+
if (isCV2(current)) await ensureCV2(current);
|
|
334
356
|
logMsg(current, 'work-after-apply');
|
|
335
357
|
text = getFullText(current);
|
|
336
358
|
}
|