dankgrinder 4.9.2 → 4.9.3
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 +9 -4
- package/lib/commands/crime.js +11 -4
- package/lib/commands/search.js +11 -4
- package/lib/grinder.js +16 -6
- package/package.json +1 -1
|
@@ -349,10 +349,15 @@ async function runAdventure({ channel, waitForDankMemer, client }) {
|
|
|
349
349
|
|
|
350
350
|
const menu = response.components[menuRowIdx]?.components[0];
|
|
351
351
|
const options = menu?.options || [];
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
352
|
+
const PREFERRED = ['space', 'out west'];
|
|
353
|
+
const preferred = options.filter(o =>
|
|
354
|
+
PREFERRED.some(kw => (o.label || '').toLowerCase().includes(kw) || (o.value || '').toLowerCase().includes(kw))
|
|
355
|
+
);
|
|
356
|
+
const pool = preferred.length > 0 ? preferred : options;
|
|
357
|
+
|
|
358
|
+
if (pool.length > 0 && menuRowIdx >= 0) {
|
|
359
|
+
const opt = pool[Math.floor(Math.random() * pool.length)];
|
|
360
|
+
LOG.info(`[adventure] Selecting: "${opt.label}" (from ${pool.length} options)`);
|
|
356
361
|
try {
|
|
357
362
|
const selectResult = await response.selectMenu(menuRowIdx, [opt.value]);
|
|
358
363
|
if (selectResult) {
|
package/lib/commands/crime.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
const {
|
|
7
7
|
LOG, c, getFullText, parseCoins, getAllButtons, safeClickButton,
|
|
8
8
|
logMsg, isHoldTight, getHoldTightReason, sleep, humanDelay,
|
|
9
|
+
isCV2, ensureCV2,
|
|
9
10
|
} = require('./utils');
|
|
10
11
|
|
|
11
12
|
const SAFE_CRIME_OPTIONS = [
|
|
@@ -71,8 +72,9 @@ async function runCrime({ channel, waitForDankMemer, safeAnswers }) {
|
|
|
71
72
|
return { result: `hold tight (${reason || 'unknown'})`, coins: 0, holdTightReason: reason };
|
|
72
73
|
}
|
|
73
74
|
|
|
75
|
+
if (isCV2(response)) await ensureCV2(response);
|
|
74
76
|
logMsg(response, 'crime');
|
|
75
|
-
|
|
77
|
+
let buttons = getAllButtons(response);
|
|
76
78
|
|
|
77
79
|
if (buttons.length === 0) {
|
|
78
80
|
const text = getFullText(response);
|
|
@@ -80,10 +82,15 @@ async function runCrime({ channel, waitForDankMemer, safeAnswers }) {
|
|
|
80
82
|
return { result: text.substring(0, 60), coins: 0 };
|
|
81
83
|
}
|
|
82
84
|
|
|
83
|
-
|
|
85
|
+
let btn = pickSafeButton(buttons, safeAnswers);
|
|
84
86
|
if (!btn) {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
+
const clickable = buttons.filter(b => !b.disabled);
|
|
88
|
+
btn = clickable.length > 0 ? clickable[Math.floor(Math.random() * clickable.length)] : null;
|
|
89
|
+
if (!btn) {
|
|
90
|
+
LOG.warn('[crime] No clickable button found');
|
|
91
|
+
return { result: 'no clickable option', coins: 0 };
|
|
92
|
+
}
|
|
93
|
+
LOG.info(`[crime] No safe match — picking random: "${btn.label}"`);
|
|
87
94
|
}
|
|
88
95
|
|
|
89
96
|
LOG.info(`[crime] Picking: "${btn.label}"`);
|
package/lib/commands/search.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
const {
|
|
7
7
|
LOG, c, getFullText, parseCoins, getAllButtons, safeClickButton,
|
|
8
8
|
logMsg, isHoldTight, getHoldTightReason, sleep, humanDelay,
|
|
9
|
+
isCV2, ensureCV2,
|
|
9
10
|
} = require('./utils');
|
|
10
11
|
|
|
11
12
|
const SAFE_SEARCH_LOCATIONS = [
|
|
@@ -74,8 +75,9 @@ async function runSearch({ channel, waitForDankMemer, safeAnswers }) {
|
|
|
74
75
|
return { result: `hold tight (${reason || 'unknown'})`, coins: 0, holdTightReason: reason };
|
|
75
76
|
}
|
|
76
77
|
|
|
78
|
+
if (isCV2(response)) await ensureCV2(response);
|
|
77
79
|
logMsg(response, 'search');
|
|
78
|
-
|
|
80
|
+
let buttons = getAllButtons(response);
|
|
79
81
|
|
|
80
82
|
if (buttons.length === 0) {
|
|
81
83
|
const text = getFullText(response);
|
|
@@ -83,10 +85,15 @@ async function runSearch({ channel, waitForDankMemer, safeAnswers }) {
|
|
|
83
85
|
return { result: text.substring(0, 60), coins: 0 };
|
|
84
86
|
}
|
|
85
87
|
|
|
86
|
-
|
|
88
|
+
let btn = pickSafeButton(buttons, safeAnswers);
|
|
87
89
|
if (!btn) {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
+
const clickable = buttons.filter(b => !b.disabled);
|
|
91
|
+
btn = clickable.length > 0 ? clickable[Math.floor(Math.random() * clickable.length)] : null;
|
|
92
|
+
if (!btn) {
|
|
93
|
+
LOG.warn('[search] No clickable button found');
|
|
94
|
+
return { result: 'no clickable option', coins: 0 };
|
|
95
|
+
}
|
|
96
|
+
LOG.info(`[search] No safe match — picking random: "${btn.label}"`);
|
|
90
97
|
}
|
|
91
98
|
|
|
92
99
|
LOG.info(`[search] Picking: "${btn.label}"`);
|
package/lib/grinder.js
CHANGED
|
@@ -835,6 +835,7 @@ class AccountWorker {
|
|
|
835
835
|
|
|
836
836
|
let wallet = 0;
|
|
837
837
|
let bank = 0;
|
|
838
|
+
let matched = '';
|
|
838
839
|
|
|
839
840
|
// CV2 format: <:Coin:ID> 3,272,896 and <:Bank:ID> 275,000 / 275,000
|
|
840
841
|
const coinMatch = text.match(/<[a:]?:Coin:\d+>\s*([\d,]+)/i);
|
|
@@ -844,15 +845,18 @@ class AccountWorker {
|
|
|
844
845
|
const walletMatch = text.match(/wallet[:\s]*\*{0,2}\s*[⏣💰]?\s*\*{0,2}\s*([\d,]+)/i);
|
|
845
846
|
const bankTextMatch = text.match(/bank[:\s]*\*{0,2}\s*[⏣💰]?\s*\*{0,2}\s*([\d,]+)/i);
|
|
846
847
|
|
|
847
|
-
// Fallback:
|
|
848
|
-
const
|
|
848
|
+
// Fallback: any numbers near ⏣ or just plain numbers in CV2 text
|
|
849
|
+
const allNums = [...text.matchAll(/(?:⏣\s*)?(\d[\d,]*\d)/g)].map(m => parseInt(m[1].replace(/,/g, ''), 10)).filter(n => n > 0);
|
|
849
850
|
|
|
850
851
|
if (coinMatch) {
|
|
851
852
|
wallet = parseInt(coinMatch[1].replace(/,/g, ''), 10);
|
|
853
|
+
matched = 'cv2-emoji';
|
|
852
854
|
} else if (walletMatch) {
|
|
853
855
|
wallet = parseInt(walletMatch[1].replace(/,/g, ''), 10);
|
|
854
|
-
|
|
855
|
-
|
|
856
|
+
matched = 'legacy-wallet';
|
|
857
|
+
} else if (allNums.length > 0) {
|
|
858
|
+
wallet = Math.max(...allNums);
|
|
859
|
+
matched = 'fallback-nums';
|
|
856
860
|
}
|
|
857
861
|
|
|
858
862
|
if (bankEmojiMatch) {
|
|
@@ -861,9 +865,15 @@ class AccountWorker {
|
|
|
861
865
|
bank = parseInt(bankTextMatch[1].replace(/,/g, ''), 10);
|
|
862
866
|
}
|
|
863
867
|
|
|
868
|
+
if (wallet === 0 && bank === 0) {
|
|
869
|
+
this.log('warn', `Balance parse returned 0 — raw text: "${text.substring(0, 200)}"`);
|
|
870
|
+
// Don't overwrite a known-good balance with 0
|
|
871
|
+
if (this.stats.balance > 0 || this.stats.bankBalance > 0) return;
|
|
872
|
+
}
|
|
873
|
+
|
|
864
874
|
this.stats.balance = wallet;
|
|
865
875
|
this.stats.bankBalance = bank;
|
|
866
|
-
this.log('bal', `Wallet: ${c.bold}${c.green}⏣ ${wallet.toLocaleString()}${c.reset} Bank: ${c.bold}${c.cyan}⏣ ${bank.toLocaleString()}${c.reset}`);
|
|
876
|
+
this.log('bal', `Wallet: ${c.bold}${c.green}⏣ ${wallet.toLocaleString()}${c.reset} Bank: ${c.bold}${c.cyan}⏣ ${bank.toLocaleString()}${c.reset} ${c.dim}(${matched || 'none'})${c.reset}`);
|
|
867
877
|
|
|
868
878
|
// Store in Redis for persistence
|
|
869
879
|
if (redis) {
|
|
@@ -901,7 +911,7 @@ class AccountWorker {
|
|
|
901
911
|
case 'with max': cmdString = `${prefix} with max`; break;
|
|
902
912
|
case 'blackjack': cmdString = `${prefix} bj ${bjBet}`; break;
|
|
903
913
|
case 'cointoss': cmdString = `${prefix} cointoss ${gambBet}`; break;
|
|
904
|
-
case 'roulette': cmdString = `${prefix} roulette ${gambBet} red`; break;
|
|
914
|
+
case 'roulette': cmdString = `${prefix} roulette ${gambBet} ${Math.random() < 0.5 ? 'red' : 'black'}`; break;
|
|
905
915
|
case 'slots': cmdString = `${prefix} slots ${gambBet}`; break;
|
|
906
916
|
case 'snakeeyes': cmdString = `${prefix} snakeeyes ${gambBet}`; break;
|
|
907
917
|
case 'work shift': cmdString = `${prefix} work shift`; break;
|