diff --git a/index.js b/index.js index 749f5c8..cca23a4 100644 --- a/index.js +++ b/index.js @@ -268,8 +268,17 @@ async function triggerSecurityShutdown(reason) { const spawnerDestroyed = await breakSpawnerUntilGone(); const status = spawnerDestroyed ? "spawner removed" : "spawner not removed"; + await sleep(600); + const stashResult = await stashSpawnerDropsInEnderChest(); + const stashStatus = stashResult.attempted + ? stashResult.remaining === 0 + ? `spawners stashed (moved=${stashResult.moved})` + : `stash incomplete (moved=${stashResult.moved}, remaining=${stashResult.remaining})` + : "no spawner items to stash"; - await sendDiscordWebhook(`MCBOT ALERT: ${reason} | ${status}`); + await sendDiscordWebhook( + `MCBOT ALERT: ${reason} | ${status} | ${stashStatus}`, + ); try { bot.quit("security shutdown"); @@ -571,6 +580,141 @@ function countItemByName(items, name) { .reduce((sum, item) => sum + (item.count || 0), 0); } +function isSpawnerItem(item) { + if (!item) return false; + return ["spawner", "mob_spawner", "trial_spawner"].includes( + String(item.name || "").toLowerCase(), + ); +} + +function countSpawnerItemsInInventory() { + if (!bot || !bot.inventory) return 0; + return bot.inventory + .items() + .filter((item) => isSpawnerItem(item)) + .reduce((sum, item) => sum + (item.count || 0), 0); +} + +function findNearbyEnderChest(maxDistance = 6) { + const blockDef = bot?.registry?.blocksByName?.ender_chest; + if (!blockDef) return null; + + return bot.findBlock({ + matching: blockDef.id, + maxDistance, + }); +} + +function getInventorySpawnerSlotsInCurrentWindow() { + if (!bot.currentWindow || !Array.isArray(bot.currentWindow.slots)) return []; + + const slots = bot.currentWindow.slots; + const inventoryStart = getInventoryStart(bot.currentWindow); + const result = []; + + for (let i = inventoryStart; i < slots.length; i += 1) { + const item = slots[i]; + if (!isSpawnerItem(item)) continue; + result.push(i); + } + + return result; +} + +async function moveAllInventorySpawnersToCurrentWindow() { + if (!bot.currentWindow) return 0; + + let moved = 0; + let safety = 0; + while (safety < 120) { + safety += 1; + + const before = countSpawnerItemsInInventory(); + if (before === 0) break; + + const spawnerSlots = getInventorySpawnerSlotsInCurrentWindow(); + if (spawnerSlots.length === 0) break; + + let clicked = false; + for (const slot of spawnerSlots) { + try { + // mode=1 is shift-click, which moves the stack to the open container. + await bot.clickWindow(slot, 0, 1); + clicked = true; + await sleep(120); + } catch (err) { + debugLog( + `moveAllInventorySpawnersToCurrentWindow: raw shift slot=${slot} failed: ${err.message}`, + ); + } + } + + const after = countSpawnerItemsInInventory(); + if (after < before) { + moved += before - after; + continue; + } + + if (!clicked) break; + break; + } + + pushLog(`moved spawners from inventory: ${moved}`); + return moved; +} + +async function stashSpawnerDropsInEnderChest() { + const before = countSpawnerItemsInInventory(); + if (before === 0) { + pushLog("no spawner items in inventory to stash"); + return { attempted: false, moved: 0, remaining: 0 }; + } + + const enderChest = findNearbyEnderChest(6); + if (!enderChest) { + pushLog("no nearby ender chest found for stashing spawners"); + return { attempted: true, moved: 0, remaining: before }; + } + + try { + await bot.lookAt(enderChest.position.offset(0.5, 0.5, 0.5), true); + const openPromise = waitForWindowOpen(5000); + closeCurrentWindow(); + await bot.activateBlock(enderChest); + + const opened = await openPromise; + if (!opened || !bot.currentWindow) { + pushLog("ender chest did not open"); + return { + attempted: true, + moved: 0, + remaining: countSpawnerItemsInInventory(), + }; + } + + await sleep(150); + const moved = await moveAllInventorySpawnersToCurrentWindow(); + closeCurrentWindow(); + + const remaining = countSpawnerItemsInInventory(); + if (remaining === 0) { + pushLog("all spawner items stashed in ender chest"); + } else { + pushLog(`spawner stash incomplete, remaining in inventory: ${remaining}`); + } + + return { attempted: true, moved, remaining }; + } catch (err) { + pushLog(`failed stashing spawners in ender chest: ${err.message}`); + closeCurrentWindow(); + return { + attempted: true, + moved: 0, + remaining: countSpawnerItemsInInventory(), + }; + } +} + function normalizeLabel(value) { return String(value || "") .toLowerCase()