const Afunction = require('../util/function.js'); module.exports = { inject: function(bot) { const Ypos = Afunction.math.random(-32, -32); // random! bot.task.data.needRefillCore = true; bot.task.data.nbtQueries = {}; bot.task.timeout.commandBlockNeverRepeating = new Map(); bot.task.timeout.nbtQueries = {}; if (bot.task.data.serverName === 'Chipmunk25570') bot.task.data.coreConfig.area.end.y = 0; bot.core = { area: { ...bot.task.data.coreConfig.area }, position: null, currentBlockRelative: { x: 0, y: 0, z: 0 }, move(pos = bot.task.data.position) { if (!pos) return false; bot.core.position = { x: Math.floor(pos.x / 16) * 16, y: Math.floor(Ypos / 16) * 16, z: Math.floor(pos.z / 16) * 16 }; return true }, // Sometime, it wont work. autoRefill() { const { start, end } = bot.core.area; const isCorePosWithinBounds = (pos, corepos) => { return pos.x >= corepos.x + start.x && pos.x <= corepos.x + end.x && pos.y >= corepos.y + start.y && pos.y <= corepos.y + end.y && pos.z >= corepos.z + start.z && pos.z <= corepos.z + end.z; }; const isValidBlockType = (type) => { return Afunction.math.between(type, 8680, 8691) || Afunction.math.between(type, 13540, 13551) || Afunction.math.between(type, 13528, 13539); }; const coreSize = (Math.abs(start.x) + Math.abs(end.x) + 1) * (Math.abs(start.y) + Math.abs(end.y) + 1) * (Math.abs(start.z) + Math.abs(end.z) + 1); bot.on('block_change', (packet) => { if (packet.type === 0 || !isValidBlockType(packet.type)) { const corePos = bot.core.position; if (!corePos) return bot.task.data.needRefillCore = true; if (isCorePosWithinBounds(packet.location, corePos)) { bot.task.data.needRefillCore = true; } } }); bot.on('multi_block_change', (data) => { const corePos = bot.core.position; if (!corePos) return bot.task.data.needRefillCore = true; const packetChunkX = data.chunkCoordinates.x * 16; const packetChunkY = data.chunkCoordinates.y * 16; const packetChunkZ = data.chunkCoordinates.z * 16; if (packetChunkX !== corePos.x || packetChunkY !== corePos.y || packetChunkZ !== corePos.z) return; let count = coreSize; for (const record of data.records) { const pos = { x: packetChunkX + ((record >> 8) & 15), y: packetChunkY + (record & 15), z: packetChunkZ + ((record >> 4) & 15), }; if (isCorePosWithinBounds(pos, corePos) && !isValidBlockType(record >> 12)) { count--; break; } } bot.task.data.needRefillCore = count < coreSize; }); bot.on('map_chunk', (data) => { const chunkX = data.x * 16; const chunkZ = data.z * 16; const corepos = bot.core.position; if (!corepos) return bot.task.data.needRefillCore = true; if (chunkX === corepos.x && chunkZ === corepos.z) { const coreCount = data.blockEntities.filter(BlockEntity => BlockEntity.type === 23).reduce((count, BlockEntity) => { const blockX = chunkX + BlockEntity.x; const blockY = BlockEntity.y; const blockZ = chunkZ + BlockEntity.z; return count + (isCorePosWithinBounds({ x: blockX, y: blockY, z: blockZ }, corepos) ? 1 : 0); }, 0); bot.task.data.needRefillCore = coreCount < coreSize; } }); bot.on('move', (oldPos, newPos) => { bot.core.move(newPos); bot.task.data.needRefillCore = true; }); bot.task.interval.autoRefill = setInterval(() => { if (!bot.core.position) return bot.core.move(); if ( bot.task.data.needRefillCore && bot.task.data.isOperator && bot.task.data.isCreative && (bot.task.data.position.y <= 320 || bot.task.data.position.y > -50) && (bot.task.data.position.world === 'minecraft:overworld' || bot.task.data.position.world === 'minecraft:world_flatlands') && bot.task.data.worldborder.size >= 40 && ( bot.task.data.position.x + 17 < bot.task.data.worldborder.center.x + bot.task.data.worldborder.size && bot.task.data.position.x > 17 + bot.task.data.worldborder.center.x - bot.task.data.worldborder.size && bot.task.data.position.z + 17 < bot.task.data.worldborder.center.z + bot.task.data.worldborder.size && bot.task.data.position.z > 17 + bot.task.data.worldborder.center.z - bot.task.data.worldborder.size ) ) { bot.core.refillCore(); } }, 500); /* bot.task.interval.fiveMinsAutoRefill = setInterval(() => { bot.task.data.needRefillCore = true; }, 300000) */ }, refillCore() { // hard code ! const pos = bot.core.position; if (!pos) return bot.task.data.needRefillCore = true; bot.write('look', { yaw: 0, pitch: -90, flags: { yaw: false, pitch: false }}); const { start, end } = bot.core.area; const refillCmd = `/fill ${pos.x + start.x} ${pos.y + start.y} ${pos.z + start.z} ${pos.x + end.x} ${pos.y + end.y} ${pos.z + end.z} chain_command_block[facing=down]{CustomName:'${bot.task.data.coreConfig.name}'} replace`; const locationOfmaxCommandChainLength = { x: Math.floor(bot.task.data.position.x), y: Math.floor(bot.task.data.position.y) - 1, z: Math.floor(bot.task.data.position.z) }; const locationOfcommandModificationBlockLimit = { x: Math.floor(bot.task.data.position.x), y: Math.floor(bot.task.data.position.y) - 2, z: Math.floor(bot.task.data.position.z) }; const locationOfRefill = { x: Math.floor(bot.task.data.position.x), y: Math.floor(bot.task.data.position.y) - 3, z: Math.floor(bot.task.data.position.z) }; bot.write('block_dig', { status: 0, location: locationOfmaxCommandChainLength, face: 1 }); bot.write('block_dig', { status: 0, location: locationOfcommandModificationBlockLimit, face: 1 }); bot.write('block_dig', { status: 0, location: locationOfRefill, face: 1 }); bot.write('set_creative_slot', { "stateId": 0, "slot": 36, "item": { "itemCount": 1, "itemId": 418, "addedComponentCount": 1, "removedComponentCount": 0, "components": [ { "type": "block_entity_data", "data": { "type": "compound", "value": { "id": { "type": "string", "value": "command_block" }, "Command": { "type": "string", "value": "gamerule maxCommandChainLength 2084" }, "auto": { "type": "byte", "value": 1 } } } } ], "removeComponents": [] } }) bot.write('block_place', { location: locationOfmaxCommandChainLength, direction: 1, // Top face hand: 0, cursorX: 0.5, // Center of the block cursorY: 0.5, cursorZ: 0.5, insideBlock: false, // Not inside the block }); bot.write('set_creative_slot', { "stateId": 0, "slot": 36, "item": { "itemCount": 1, "itemId": 538, "addedComponentCount": 1, "removedComponentCount": 0, "components": [ { "type": "block_entity_data", "data": { "type": "compound", "value": { "id": { "type": "string", "value": "command_block" }, "Command": { "type": "string", "value": "gamerule commandModificationBlockLimit 2048" // - amyavi }, "auto": { "type": "byte", "value": 1 } } } } ], "removeComponents": [] } }); bot.write('block_place', { location: locationOfcommandModificationBlockLimit, direction: 1, // Top face hand: 0, cursorX: 0.5, // Center of the block cursorY: 0.5, cursorZ: 0.5, insideBlock: false, // Not inside the block }); bot.write('set_creative_slot', { "stateId": 0, "slot": 36, "item": { "itemCount": 1, "itemId": 538, "addedComponentCount": 1, "removedComponentCount": 0, "components": [ { "type": "block_entity_data", "data": { "type": "compound", "value": { "id": { "type": "string", "value": "command_block" }, "Command": { "type": "string", "value": refillCmd }, "auto": { "type": "byte", "value": 1 } } } } ], "removeComponents": [] } }); bot.write('block_place', { location: locationOfRefill, direction: 1, hand: 0, cursorX: 0.5, cursorY: 0.5, cursorZ: 0.5, insideBlock: false, }); bot.task.timeout.BreakPlaceBlock = setTimeout(() => { bot.write('block_dig', { status: 0, location: locationOfmaxCommandChainLength, face: 1 }); bot.write('block_dig', { status: 0, location: locationOfcommandModificationBlockLimit, face: 1 }); bot.write('block_dig', { status: 0, location: locationOfRefill, face: 1 }); }, 500); }, run(command, output = false, timeout = 5000) { if (!command || command === '' || command.length > 32767) return Promise.resolve(undefined); // Command too long OR nothing const corePos = bot.core.position; if (!corePos) { bot.core.needRefillCore = true; return Promise.resolve(undefined); } const { start, end } = bot.core.area; let relativePosition = bot.core.currentBlockRelative; relativePosition.x++; relativePosition.x > end.x && (relativePosition.x = start.x, relativePosition.z++); relativePosition.z > end.z && (relativePosition.z = start.z, relativePosition.y++); relativePosition.y > end.y && (relativePosition.x = start.x, relativePosition.y = start.y, relativePosition.z = start.z); const CommandBlockLocation = { x: relativePosition.x + corePos.x, y: relativePosition.y + corePos.y, z: relativePosition.z + corePos.z } bot.write("update_command_block", { command: command, location: CommandBlockLocation, mode: 1, flags: 5 }); if (bot.task.timeout.commandBlockNeverRepeating !== undefined) { clearTimeout(bot.task.timeout.commandBlockNeverRepeating.get(CommandBlockLocation)); bot.task.timeout.commandBlockNeverRepeating.set(CommandBlockLocation, setTimeout(() => { bot.write("update_command_block", { command: "", location: CommandBlockLocation, mode: 0, flags: 1 }); bot.task.timeout.commandBlockNeverRepeating.delete(CommandBlockLocation); }, 10000)); } if (!output) return Promise.resolve(undefined); let outputRelativePosition = JSON.parse(JSON.stringify(CommandBlockLocation)); // prevent relativePosition change pos return new Promise((resolve) => { if (!bot?.task?.timeout?.nbtQueries) return resolve(undefined); const secretString = Afunction.generateRandomString(30, 1, 2, 3); bot.task.data.nbtQueries[secretString] = { resolve }; bot.core.run(`minecraft:tellraw @a[name="${bot.username}"] {"translate":"NilBot_CommandBlock_Output %s %s","with":["${secretString}",{"nbt":"LastOutput","block":"${CommandBlockLocation.x} ${CommandBlockLocation.y} ${CommandBlockLocation.z}","interpret":true}]}`); bot.task.timeout.nbtQueries[secretString] = setTimeout(() => { resolve(undefined); delete bot.task.data.nbtQueries[secretString]; delete bot.task.timeout.nbtQueries[secretString]; }, timeout); }); } } // bot.task.data.core = bot.core; // end core bot.on("custom_systemChat", (_, systemChat) => { let jsonMsg = systemChat.jsonMsg.message; if (jsonMsg.translate === 'NilBot_CommandBlock_Output %s %s' && typeof jsonMsg.with?.[0]?.text === "string" && typeof jsonMsg.with?.[1] === "object") { const secretString = jsonMsg.with[0].text; if (bot?.task?.timeout?.nbtQueries?.[secretString]) { clearTimeout(bot.task.timeout.nbtQueries[secretString]) delete bot.task.timeout.nbtQueries[secretString] bot.task.data.nbtQueries[secretString].resolve(jsonMsg.with[1]); delete bot.task.data.nbtQueries[secretString]; } } }); bot.core.autoRefill(); } }