dankgrinder 7.11.0 → 7.12.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/farm.js +32 -1
- package/package.json +1 -1
package/lib/commands/farm.js
CHANGED
|
@@ -1409,6 +1409,7 @@ async function runFarm({ channel, waitForDankMemer, client, redis, accountId, fo
|
|
|
1409
1409
|
let forcedNextAction = null; // When advancing a phase, force the next action check
|
|
1410
1410
|
let lastApplyResp = null; // Track the last apply response for coin/cooldown parsing
|
|
1411
1411
|
let lastRejectedAction = null; // Track last rejected action to break empty-farm loops
|
|
1412
|
+
let lastRejectedAction2 = null; // Track previous rejected action to detect 3-in-a-row loops
|
|
1412
1413
|
|
|
1413
1414
|
while (cycleDepth < 5) {
|
|
1414
1415
|
// Reset per-cycle state
|
|
@@ -1589,6 +1590,30 @@ async function runFarm({ channel, waitForDankMemer, client, redis, accountId, fo
|
|
|
1589
1590
|
const ephem = lastApplyResp?._capturedEphemeral;
|
|
1590
1591
|
const ephemText = (ephem?.cv2Text || ephem?.allText || '').toLowerCase();
|
|
1591
1592
|
|
|
1593
|
+
// Generic "nothing to X" no-op: when an action completes but has nothing to act on,
|
|
1594
|
+
// cascade forward without treating it as a rejection. Also use this as a safety break
|
|
1595
|
+
// when the same action keeps getting rejected (stuck in a loop).
|
|
1596
|
+
if (
|
|
1597
|
+
// "Nothing to water/hoe/plant/harvest" — action succeeded but was a no-op
|
|
1598
|
+
/nothing to (water|hoe|plant|harvest)|no crops? (to |to )?(water|harvest)|0 x [a-z]|nothing to do/i.test(ephemText) ||
|
|
1599
|
+
// Safety: if the same action was rejected 3+ cycles in a row, something is stuck — break
|
|
1600
|
+
(lastRejectedAction === action && lastRejectedAction2 === action)
|
|
1601
|
+
) {
|
|
1602
|
+
LOG.warn(`[farm:cycle:${cycleDepth}:reject] ${action} is a no-op or stuck loop (${ephemText.slice(0, 80)}) — cascading to next phase`);
|
|
1603
|
+
const currentIdx = FARM_PHASE_ORDER.indexOf(action);
|
|
1604
|
+
const nextPhase = FARM_PHASE_ORDER[currentIdx + 1] || null;
|
|
1605
|
+
lastRejectedAction2 = lastRejectedAction;
|
|
1606
|
+
lastRejectedAction = action;
|
|
1607
|
+
forcedNextAction = nextPhase;
|
|
1608
|
+
lastAction = action;
|
|
1609
|
+
justRejected = true;
|
|
1610
|
+
cycleDepth++;
|
|
1611
|
+
if (!nextPhase) { forcedNextAction = null; break; }
|
|
1612
|
+
await reenterManage();
|
|
1613
|
+
await sleep(300);
|
|
1614
|
+
continue;
|
|
1615
|
+
}
|
|
1616
|
+
|
|
1592
1617
|
// Helper: re-enter the manage menu from the farm view so the next
|
|
1593
1618
|
// findNextFarmActionFromManage iteration has buttons to work with.
|
|
1594
1619
|
async function reenterManage() {
|
|
@@ -1614,6 +1639,8 @@ async function runFarm({ channel, waitForDankMemer, client, redis, accountId, fo
|
|
|
1614
1639
|
LOG.warn(`[farm:cycle:${cycleDepth}:reject] Hoe rejected: tiles not empty — cascading to water`);
|
|
1615
1640
|
const currentIdx = FARM_PHASE_ORDER.indexOf(action);
|
|
1616
1641
|
const nextPhase = FARM_PHASE_ORDER[currentIdx + 1] || null;
|
|
1642
|
+
lastRejectedAction2 = lastRejectedAction;
|
|
1643
|
+
lastRejectedAction = action;
|
|
1617
1644
|
forcedNextAction = nextPhase;
|
|
1618
1645
|
lastAction = action;
|
|
1619
1646
|
justRejected = true;
|
|
@@ -1630,11 +1657,13 @@ async function runFarm({ channel, waitForDankMemer, client, redis, accountId, fo
|
|
|
1630
1657
|
LOG.warn(`[farm:cycle:${cycleDepth}:reject] Water rejected (${ephemText.slice(0, 100)}) — cascading to plant`);
|
|
1631
1658
|
const currentIdx = FARM_PHASE_ORDER.indexOf(action);
|
|
1632
1659
|
const nextPhase = FARM_PHASE_ORDER[currentIdx + 1] || null;
|
|
1660
|
+
lastRejectedAction2 = lastRejectedAction;
|
|
1661
|
+
lastRejectedAction = action;
|
|
1633
1662
|
forcedNextAction = nextPhase;
|
|
1634
1663
|
lastAction = action;
|
|
1635
1664
|
justRejected = true;
|
|
1636
1665
|
// Break oscillation guard: if we bounced back here from plant, stop.
|
|
1637
|
-
if (
|
|
1666
|
+
if (lastRejectedAction2 === 'plant' && lastRejectedAction === 'water') {
|
|
1638
1667
|
LOG.warn(`[farm:cycle:${cycleDepth}:reject] hoe→water→plant oscillation detected — breaking`);
|
|
1639
1668
|
break;
|
|
1640
1669
|
}
|
|
@@ -1651,6 +1680,8 @@ async function runFarm({ channel, waitForDankMemer, client, redis, accountId, fo
|
|
|
1651
1680
|
LOG.warn(`[farm:cycle:${cycleDepth}:reject] Plant rejected (${ephemText.slice(0, 100)}) — cascading to harvest`);
|
|
1652
1681
|
const currentIdx = FARM_PHASE_ORDER.indexOf(action);
|
|
1653
1682
|
const nextPhase = FARM_PHASE_ORDER[currentIdx + 1] || null;
|
|
1683
|
+
lastRejectedAction2 = lastRejectedAction;
|
|
1684
|
+
lastRejectedAction = action;
|
|
1654
1685
|
forcedNextAction = nextPhase;
|
|
1655
1686
|
lastAction = action;
|
|
1656
1687
|
justRejected = true;
|