dankgrinder 4.9.0 → 4.9.2
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/generic.js +2 -0
- package/lib/grinder.js +92 -43
- package/package.json +1 -1
package/lib/commands/generic.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
const {
|
|
8
8
|
LOG, c, getFullText, parseCoins, getAllButtons, getAllSelectMenus,
|
|
9
9
|
safeClickButton, logMsg, isHoldTight, getHoldTightReason, sleep, humanDelay, needsItem,
|
|
10
|
+
isCV2, ensureCV2,
|
|
10
11
|
} = require('./utils');
|
|
11
12
|
const { buyItem } = require('./shop');
|
|
12
13
|
|
|
@@ -37,6 +38,7 @@ async function runGeneric({ channel, waitForDankMemer, cmdString, cmdName, clien
|
|
|
37
38
|
return { result: `hold tight (${reason || 'unknown'})`, coins: 0, holdTightReason: reason };
|
|
38
39
|
}
|
|
39
40
|
|
|
41
|
+
if (isCV2(response)) await ensureCV2(response);
|
|
40
42
|
logMsg(response, cmdName);
|
|
41
43
|
const text = getFullText(response);
|
|
42
44
|
const coins = parseCoins(text);
|
package/lib/grinder.js
CHANGED
|
@@ -791,6 +791,11 @@ class AccountWorker {
|
|
|
791
791
|
|
|
792
792
|
// ── Check Balance ───────────────────────────────────────────
|
|
793
793
|
async checkInventory() {
|
|
794
|
+
if (this._invRunning) return;
|
|
795
|
+
if (this._lastInvCheck && Date.now() - this._lastInvCheck < 300_000) return;
|
|
796
|
+
this._invRunning = true;
|
|
797
|
+
this._lastInvCheck = Date.now();
|
|
798
|
+
this.busy = true;
|
|
794
799
|
try {
|
|
795
800
|
this.log('info', 'Checking inventory...');
|
|
796
801
|
const result = await commands.runInventory({
|
|
@@ -800,23 +805,23 @@ class AccountWorker {
|
|
|
800
805
|
accountId: this.account.id,
|
|
801
806
|
redis,
|
|
802
807
|
});
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
});
|
|
816
|
-
} catch {}
|
|
817
|
-
}
|
|
808
|
+
this.log('success', `Inventory: ${result.items?.length || 0} items, ⏣ ${(result.totalValue || 0).toLocaleString()} net`);
|
|
809
|
+
try {
|
|
810
|
+
await fetch(`${API_URL}/api/grinder/inventory`, {
|
|
811
|
+
method: 'POST',
|
|
812
|
+
headers: { Authorization: `Bearer ${API_KEY}`, 'Content-Type': 'application/json' },
|
|
813
|
+
body: JSON.stringify({
|
|
814
|
+
account_id: this.account.id,
|
|
815
|
+
items: result.items || [],
|
|
816
|
+
totalValue: result.totalValue || 0,
|
|
817
|
+
}),
|
|
818
|
+
});
|
|
819
|
+
} catch {}
|
|
818
820
|
} catch (e) {
|
|
819
821
|
this.log('error', `Inventory check failed: ${e.message}`);
|
|
822
|
+
} finally {
|
|
823
|
+
this._invRunning = false;
|
|
824
|
+
this.busy = false;
|
|
820
825
|
}
|
|
821
826
|
}
|
|
822
827
|
|
|
@@ -856,23 +861,30 @@ class AccountWorker {
|
|
|
856
861
|
bank = parseInt(bankTextMatch[1].replace(/,/g, ''), 10);
|
|
857
862
|
}
|
|
858
863
|
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
864
|
+
this.stats.balance = wallet;
|
|
865
|
+
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}`);
|
|
867
|
+
|
|
868
|
+
// Store in Redis for persistence
|
|
869
|
+
if (redis) {
|
|
863
870
|
try {
|
|
864
|
-
await
|
|
865
|
-
|
|
866
|
-
headers: { Authorization: `Bearer ${API_KEY}`, 'Content-Type': 'application/json' },
|
|
867
|
-
body: JSON.stringify({
|
|
868
|
-
account_id: this.account.id,
|
|
869
|
-
balance: wallet,
|
|
870
|
-
bank_balance: bank,
|
|
871
|
-
total_balance: wallet + bank,
|
|
872
|
-
}),
|
|
873
|
-
});
|
|
874
|
-
} catch { /* silent */ }
|
|
871
|
+
await redis.set(`dkg:bal:${this.account.id}`, JSON.stringify({ wallet, bank, ts: Date.now() }));
|
|
872
|
+
} catch {}
|
|
875
873
|
}
|
|
874
|
+
|
|
875
|
+
// Always report to dashboard API
|
|
876
|
+
try {
|
|
877
|
+
await fetch(`${API_URL}/api/grinder/status`, {
|
|
878
|
+
method: 'POST',
|
|
879
|
+
headers: { Authorization: `Bearer ${API_KEY}`, 'Content-Type': 'application/json' },
|
|
880
|
+
body: JSON.stringify({
|
|
881
|
+
account_id: this.account.id,
|
|
882
|
+
balance: wallet,
|
|
883
|
+
bank_balance: bank,
|
|
884
|
+
total_balance: wallet + bank,
|
|
885
|
+
}),
|
|
886
|
+
});
|
|
887
|
+
} catch { /* silent */ }
|
|
876
888
|
}
|
|
877
889
|
}
|
|
878
890
|
|
|
@@ -881,16 +893,17 @@ class AccountWorker {
|
|
|
881
893
|
// handles Hold Tight / cooldowns / item-buying internally.
|
|
882
894
|
async runCommand(cmdName, prefix) {
|
|
883
895
|
let cmdString;
|
|
884
|
-
const
|
|
896
|
+
const bjBet = Math.max(5000, this.account.bet_amount || 5000);
|
|
897
|
+
const gambBet = Math.max(10000, this.account.bet_amount || 10000);
|
|
885
898
|
|
|
886
899
|
switch (cmdName) {
|
|
887
900
|
case 'dep max': cmdString = `${prefix} dep max`; break;
|
|
888
901
|
case 'with max': cmdString = `${prefix} with max`; break;
|
|
889
|
-
case 'blackjack': cmdString = `${prefix} bj ${
|
|
890
|
-
case 'cointoss': cmdString = `${prefix} cointoss ${
|
|
891
|
-
case 'roulette': cmdString = `${prefix} roulette ${
|
|
892
|
-
case 'slots': cmdString = `${prefix} slots ${
|
|
893
|
-
case 'snakeeyes': cmdString = `${prefix} snakeeyes ${
|
|
902
|
+
case 'blackjack': cmdString = `${prefix} bj ${bjBet}`; break;
|
|
903
|
+
case 'cointoss': cmdString = `${prefix} cointoss ${gambBet}`; break;
|
|
904
|
+
case 'roulette': cmdString = `${prefix} roulette ${gambBet} red`; break;
|
|
905
|
+
case 'slots': cmdString = `${prefix} slots ${gambBet}`; break;
|
|
906
|
+
case 'snakeeyes': cmdString = `${prefix} snakeeyes ${gambBet}`; break;
|
|
894
907
|
case 'work shift': cmdString = `${prefix} work shift`; break;
|
|
895
908
|
case 'weekly': cmdString = `${prefix} weekly`; break;
|
|
896
909
|
case 'monthly': cmdString = `${prefix} monthly`; break;
|
|
@@ -906,7 +919,7 @@ class AccountWorker {
|
|
|
906
919
|
client: this.client,
|
|
907
920
|
safeAnswers: cmdName === 'search' ? safeParseJSON(this.account.search_answers, []) :
|
|
908
921
|
cmdName === 'crime' ? safeParseJSON(this.account.crime_answers, []) : [],
|
|
909
|
-
betAmount,
|
|
922
|
+
betAmount: ['blackjack'].includes(cmdName) ? bjBet : gambBet,
|
|
910
923
|
accountId: this.account.id,
|
|
911
924
|
redis,
|
|
912
925
|
};
|
|
@@ -1042,7 +1055,10 @@ class AccountWorker {
|
|
|
1042
1055
|
const earned = Math.max(0, cmdResult.coins || 0);
|
|
1043
1056
|
const spent = Math.max(0, cmdResult.lost || 0);
|
|
1044
1057
|
if (earned > 0) this.stats.coins += earned;
|
|
1045
|
-
if (cmdResult.nextCooldownSec)
|
|
1058
|
+
if (cmdResult.nextCooldownSec) {
|
|
1059
|
+
await this.setCooldown(cmdName, cmdResult.nextCooldownSec);
|
|
1060
|
+
this._lastCooldownOverride = cmdResult.nextCooldownSec;
|
|
1061
|
+
}
|
|
1046
1062
|
|
|
1047
1063
|
// Mark time-gated commands as done so we don't re-run this session
|
|
1048
1064
|
const doneExpiries = { daily: 86400, weekly: 604800, monthly: 2592000, drops: 86400 };
|
|
@@ -1065,12 +1081,12 @@ class AccountWorker {
|
|
|
1065
1081
|
this.stats.successes++;
|
|
1066
1082
|
const shortResult = result.substring(0, 30).replace(/\n/g, ' ');
|
|
1067
1083
|
this.setStatus(`${cmdName} → ${shortResult}`);
|
|
1068
|
-
await sendLog(this.username,
|
|
1084
|
+
await sendLog(this.username, cmdName, result, 'success');
|
|
1069
1085
|
reportEarnings(this.account.id, this.username, earned, spent, cmdName);
|
|
1070
1086
|
} catch (err) {
|
|
1071
1087
|
this.stats.errors++;
|
|
1072
1088
|
this.log('error', `${cmdString} failed: ${err.message}`);
|
|
1073
|
-
await sendLog(this.username,
|
|
1089
|
+
await sendLog(this.username, cmdName, err.message, 'error');
|
|
1074
1090
|
}
|
|
1075
1091
|
}
|
|
1076
1092
|
|
|
@@ -1351,7 +1367,9 @@ class AccountWorker {
|
|
|
1351
1367
|
const backoffMultiplier = this.failStreak > 5 ? Math.min(this.failStreak - 4, 5) : 1;
|
|
1352
1368
|
|
|
1353
1369
|
if (this.commandQueue && this.running && !shutdownCalled) {
|
|
1354
|
-
|
|
1370
|
+
const effectiveWait = this._lastCooldownOverride || totalWait;
|
|
1371
|
+
this._lastCooldownOverride = null;
|
|
1372
|
+
item.nextRunAt = Date.now() + effectiveWait * 1000 * backoffMultiplier;
|
|
1355
1373
|
this.commandQueue.push(item);
|
|
1356
1374
|
}
|
|
1357
1375
|
|
|
@@ -1371,7 +1389,7 @@ class AccountWorker {
|
|
|
1371
1389
|
this.cycleCount++;
|
|
1372
1390
|
|
|
1373
1391
|
if (this.cycleCount > 0 && this.cycleCount % 10 === 0) this.printStats();
|
|
1374
|
-
if (this.cycleCount > 0 && this.cycleCount %
|
|
1392
|
+
if (this.cycleCount > 0 && this.cycleCount % 5 === 0) {
|
|
1375
1393
|
this.busy = true;
|
|
1376
1394
|
await this.checkBalance();
|
|
1377
1395
|
this.busy = false;
|
|
@@ -1522,8 +1540,39 @@ class AccountWorker {
|
|
|
1522
1540
|
this.log('success', `#${chName} · ${enabledCmds.length} cmds`);
|
|
1523
1541
|
this.setStatus('starting...');
|
|
1524
1542
|
|
|
1543
|
+
// Load daily/weekly/monthly done state from Redis
|
|
1544
|
+
if (redis) {
|
|
1545
|
+
for (const cmd of ['daily', 'weekly', 'monthly', 'drops']) {
|
|
1546
|
+
try {
|
|
1547
|
+
const val = await redis.get(`dkg:done:${this.account.id}:${cmd}`);
|
|
1548
|
+
if (val) {
|
|
1549
|
+
const ttlSec = await redis.ttl(`dkg:done:${this.account.id}:${cmd}`);
|
|
1550
|
+
if (ttlSec > 0) {
|
|
1551
|
+
this.doneToday.set(cmd, Date.now() + ttlSec * 1000);
|
|
1552
|
+
this.log('info', `${cmd} already claimed (${Math.round(ttlSec / 3600)}h remaining)`);
|
|
1553
|
+
}
|
|
1554
|
+
}
|
|
1555
|
+
} catch {}
|
|
1556
|
+
}
|
|
1557
|
+
// Load cached balance from Redis
|
|
1558
|
+
try {
|
|
1559
|
+
const balData = await redis.get(`dkg:bal:${this.account.id}`);
|
|
1560
|
+
if (balData) {
|
|
1561
|
+
const { wallet, bank } = JSON.parse(balData);
|
|
1562
|
+
if (wallet > 0 || bank > 0) {
|
|
1563
|
+
this.stats.balance = wallet;
|
|
1564
|
+
this.stats.bankBalance = bank;
|
|
1565
|
+
await fetch(`${API_URL}/api/grinder/status`, {
|
|
1566
|
+
method: 'POST',
|
|
1567
|
+
headers: { Authorization: `Bearer ${API_KEY}`, 'Content-Type': 'application/json' },
|
|
1568
|
+
body: JSON.stringify({ account_id: this.account.id, balance: wallet, bank_balance: bank, total_balance: wallet + bank }),
|
|
1569
|
+
}).catch(() => {});
|
|
1570
|
+
}
|
|
1571
|
+
}
|
|
1572
|
+
} catch {}
|
|
1573
|
+
}
|
|
1574
|
+
|
|
1525
1575
|
await this.checkBalance();
|
|
1526
|
-
// Check inventory on startup
|
|
1527
1576
|
this.checkInventory().catch(() => {});
|
|
1528
1577
|
this.grindLoop();
|
|
1529
1578
|
resolve();
|