mc-term
Version:
Play Minecraft and configure bots from the terminal
1,093 lines (1,092 loc) • 40.3 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.PluginExports = exports.PluginExportsBefore = exports.setbotMain = exports.setBot = exports.bot = exports.commands = exports.nonVanillaCommands = exports.scriptOnlyCommands = exports.reservedCommandNames = exports.events = void 0;
exports.print = print;
exports.info = info;
exports.warn = warn;
exports.error = error;
exports.success = success;
exports.setConfig = setConfig;
const tslib_1 = require("tslib");
const utils_js_1 = require("./utils/other/utils.js");
const mcUtils = tslib_1.__importStar(require("./utils/other/mineflayer-utils.js"));
const parseCoords_js_1 = require("./utils/strings/parseCoords.js");
const mineflayer_pathfinder_1 = require("mineflayer-pathfinder");
const fs_1 = require("fs");
const translatable_js_1 = require("../lang/translatable.js");
const index_js_1 = require("./utils/numbers/index.js");
const index_js_2 = require("./utils/strings/index.js");
const tabulate_js_1 = require("./utils/strings/tabulate.js");
const settings_js_1 = require("../config/settings.js");
const package_js_1 = require("./helpers/package.js");
const prismarine_registry_1 = tslib_1.__importDefault(require("prismarine-registry"));
const taskQueue_js_1 = require("./utils/other/taskQueue.js");
const prismarine_chat_1 = tslib_1.__importDefault(require("prismarine-chat"));
const node_events_1 = require("node:events");
const sleep_js_1 = require("./helpers/sleep.js");
const vec3_js_1 = require("./vec3.js");
const logger = tslib_1.__importStar(require("./log.js"));
const ansi = tslib_1.__importStar(require("easy-ansi"));
const pointsInBetween_js_1 = require("./utils/other/pointsInBetween.js");
let pRegistry = (0, prismarine_registry_1.default)('1.12.2');
let ChatMessage = (0, prismarine_chat_1.default)(pRegistry);
exports.events = new node_events_1.EventEmitter();
function print(msg, resetCursor = true) {
exports.events.emit('msg', msg, resetCursor);
}
function info(msg, resetCursor = true) {
exports.events.emit('msg_info', msg, resetCursor);
}
function warn(msg, resetCursor = true) {
exports.events.emit('msg_warn', msg, resetCursor);
}
function error(msg, resetCursor = true, err) {
exports.events.emit('msg_error', msg, resetCursor, err);
}
function success(msg, resetCursor = true) {
exports.events.emit('msg_success', msg, resetCursor);
}
let settings = {
settings: new settings_js_1.Settings(),
options: {}
};
function setConfig(conf) {
settings = conf;
}
const botLookPriorityCache = {
priority: 0,
cooldown: 0
};
exports.reservedCommandNames = [
'interpret',
'cmd',
'tmp',
'tasks'
];
exports.scriptOnlyCommands = [
'wait',
'async',
'print',
'success',
'info',
'warn',
'error'
];
exports.nonVanillaCommands = [
'smartfollow',
'unfollow',
'pathfind',
'attack',
'stopattack'
];
class Commands {
tmp = {
variables: {},
botMoving: false,
botLooking: false,
botAttacking: false,
botDigging: false
};
commands = {};
async interpret(str, options = {}) {
const trimmedStr = str.trim();
if (!trimmedStr || trimmedStr.startsWith('#'))
return;
const { type } = options;
const interpretLine = async (line) => {
const [command, ...args] = this.parseInput(line.trim());
const func = this.getCaseInsens(this.convertAlias(command), this.commands);
if (!func || exports.reservedCommandNames.includes(command)) {
warn(translatable_js_1.currentLang.data.infoMessages.invalidCmd(command));
return;
}
if (!settings.settings.config.config.config.commands.enableNonVanillaCMD && exports.nonVanillaCommands.includes(command)) {
warn(translatable_js_1.currentLang.data.infoMessages.nonVanillaCmd);
return;
}
if (type !== 'script' && exports.scriptOnlyCommands.includes(command)) {
warn(translatable_js_1.currentLang.data.infoMessages.scriptOnlyCmd);
return;
}
await func(...args);
};
const lines = trimmedStr.split(/[\n;]{2}/);
for (const line of lines) {
await interpretLine(line);
}
}
async runTasks(tasks) {
for (const [name, cmd] of Object.entries(tasks)) {
const [times, eventName] = name.split('_');
if (['on', 'once'].includes(times) && typeof cmd === 'string' && cmd !== '' && eventName) {
exports.bot[times](eventName, async () => {
await exports.commands.interpret(cmd);
});
}
}
}
parseInput(str) {
let out = str.trim();
out = (0, parseCoords_js_1.parseCoords)(str, exports.bot.entity.position, 3);
out = (0, utils_js_1.parseVar)(out, this.tmp.variables, {
varPrefix: '%',
varSuffix: '%',
undefinedVar: 'undefined'
});
let outt = (0, index_js_2.getQuotedStrings)(out);
const t = outt.shift();
outt = utils_js_1.parseStr.parseArr(outt);
outt.unshift(t);
return outt;
}
getCaseInsens(key, obj) {
const aliasKeys = (0, utils_js_1.toLowerCaseArr)(Object.keys(obj));
const indexOf = aliasKeys.indexOf(key.toLowerCase());
if (indexOf !== -1) {
return Object.values(obj)[indexOf];
}
}
convertAlias(alias) {
if (!alias) {
return;
}
const commandAliases = settings.settings.config.config.config.commands.commandAliases;
return this.getCaseInsens(alias, commandAliases) || alias.toLowerCase();
}
}
exports.commands = new Commands();
let botSet = false;
const setBot = async (Bot) => {
if (botSet) {
return;
}
botSet = true;
exports.bot = Bot;
mcUtils.setup(exports.bot, botLookPriorityCache);
pRegistry = (0, prismarine_registry_1.default)(exports.bot.version);
ChatMessage = (0, prismarine_chat_1.default)(pRegistry);
exports.bot.loadPlugin(mineflayer_pathfinder_1.pathfinder);
exports.bot.on('windowOpen', () => {
info('Container #1 opened\nUse ".inventory 1" to interact with it');
});
};
exports.setBot = setBot;
const setbotMain = async (_botmain) => {
};
exports.setbotMain = setbotMain;
class PluginExportsBefore {
settings = settings;
ansi = ansi;
print = print;
info = info;
warn = warn;
error = error;
success = success;
}
exports.PluginExportsBefore = PluginExportsBefore;
class PluginExports {
sleep = sleep_js_1.sleep;
commands = exports.commands;
pRegistry = pRegistry;
reservedCommandNames = exports.reservedCommandNames;
settings = settings;
nonVanillaCommands = exports.nonVanillaCommands;
Vec3 = vec3_js_1.Vec3;
mcUtils = mcUtils;
parseCoords = parseCoords_js_1.parseCoords;
parseStr = utils_js_1.parseStr;
distance = index_js_1.distance;
bot = exports.bot;
ansi = ansi;
print = print;
info = info;
warn = warn;
error = error;
success = success;
currentLang = translatable_js_1.currentLang;
}
exports.PluginExports = PluginExports;
exports.commands.commands.exit = () => {
exports.bot.quit();
return true;
};
exports.commands.commands.reco = async () => {
warn('Use .exit instead');
return false;
};
function getCmdInfo(cmd, info = 'usage') {
const cmdArr = cmd.split('.');
let langCmd = translatable_js_1.currentLang.data.commands[cmdArr[0]];
for (let i = 1; i < cmdArr.length && langCmd; i++) {
langCmd = langCmd.subCommands?.[cmdArr[i]];
}
return langCmd?.[info] ?? '';
}
exports.commands.commands.send = (...msg) => {
const out = msg.join(' ');
if (!out) {
info(getCmdInfo('send'));
return;
}
exports.bot.chat(out);
};
exports.commands.commands.position = () => {
const pos = exports.bot.entity.position;
info(`Position: ${Number(pos.x.toFixed(3))}, ${Number(pos.y.toFixed(3))}, ${Number(pos.z.toFixed(3))}`);
};
exports.commands.commands.distance = (x1, y1, z1, x2, y2, z2) => {
if (!(0, index_js_1.isNumber)(x1) || !(0, index_js_1.isNumber)(y1) || !(0, index_js_1.isNumber)(z1) || !(0, index_js_1.isNumber)(x2) || !(0, index_js_1.isNumber)(y2) || !(0, index_js_1.isNumber)(z2)) {
info(getCmdInfo('distance'));
return;
}
const point1 = (0, vec3_js_1.v)(x1, y1, z1);
const point2 = (0, vec3_js_1.v)(x2, y2, z2);
info(`Distance: ${Number((0, index_js_1.distance)(point1, point2).toFixed(3))}`);
};
exports.commands.commands.list = () => {
let out = '';
for (const player in exports.bot.players) {
if (Object.hasOwnProperty.call(exports.bot.players, player)) {
const playerInfo = exports.bot.players[player];
out = `${out} ${playerInfo.username} [${playerInfo.ping}]`;
}
}
info(`Player list:${out}`);
};
exports.commands.commands.blocks = async (range, count, filter) => {
if ((!(0, index_js_1.isNumber)(range) || range <= 0) || (!(0, index_js_1.isNumber)(count) && count !== undefined)) {
info(getCmdInfo('blocks'));
return;
}
const blocksCoords = exports.bot.findBlocks({
matching: (block) => {
if (block.type !== pRegistry.blocksByName.air.id) {
return true;
}
return false;
},
maxDistance: range,
count: count ?? Infinity
});
let blockCount = 0;
const regex = new RegExp(filter, 'i');
for (const blockPos of blocksCoords) {
const block = exports.bot.blockAt(blockPos);
if ((block?.displayName?.match(regex) == null)) {
continue;
}
print(` ${logger.info.color}${block.position.x}, ${block.position.y} ${block.position.z} ${block.displayName}: ${String(block.diggable)}${ansi.color.reset}`);
blockCount++;
}
info('Count: ' + String(blockCount));
};
async function botDig(pos, forceLook, type, silent = true) {
if (exports.commands.tmp.botDigging || exports.commands.tmp.botLooking || exports.commands.tmp.botAttacking) {
return;
}
const block = exports.bot.blockAt(pos);
if (block === null || !block.diggable) {
if (!silent)
warn('Block is undiggable');
return false;
}
try {
await exports.bot.dig(block, forceLook, type);
}
catch (err) {
if (!silent)
warn(translatable_js_1.currentLang.data.infoMessages.cantDigBlockAt(pos.x, pos.y, pos.z, err));
return false;
}
return true;
}
exports.commands.commands.dig = async (x, y, z) => {
if (!(0, index_js_1.isNumber)(x) || !(0, index_js_1.isNumber)(y) || !(0, index_js_1.isNumber)(z)) {
info(getCmdInfo('dig'));
return;
}
if (exports.commands.tmp.botDigging || exports.commands.tmp.botLooking || exports.commands.tmp.botAttacking) {
warn(translatable_js_1.currentLang.data.infoMessages.botLookingOrAttackingErr);
return true;
}
const botDigPromise = botDig((0, vec3_js_1.v)(x, y, z), true, 'raycast');
exports.commands.tmp.botLooking = true;
exports.commands.tmp.botDigging = true;
if (await botDigPromise) {
success(`Dug block at ${x}, ${y}, ${z}`);
}
exports.commands.tmp.botLooking = false;
exports.commands.tmp.botDigging = false;
};
exports.commands.commands.stopDig = () => {
exports.bot.stopDigging();
success('Stopped digging');
};
const digQueue = new taskQueue_js_1.TaskQueue();
const digMapAddedCoordinates = [];
exports.commands.commands.digMap = async (subCmd, ...args) => {
if (!['add', 'remove', 'clear', 'addspace', 'show'].includes(subCmd?.toLowerCase())) {
info(getCmdInfo('digMap'));
return;
}
const subCommands = {
add(x, y, z) {
if (!(0, index_js_1.isNumber)(x) || !(0, index_js_1.isNumber)(y) || !(0, index_js_1.isNumber)(z)) {
info(getCmdInfo('digMap.add'));
return;
}
const coords = `${x}, ${y}, ${z}`;
if (digMapAddedCoordinates.includes(coords)) {
return;
}
exports.commands.commands.digMap.onBlockUpdate(undefined, exports.bot.blockAt((0, vec3_js_1.v)(x, y, z)));
exports.bot.on(`blockUpdate:(${coords})`, exports.commands.commands.digMap.onBlockUpdate);
digMapAddedCoordinates.push(coords);
},
remove(x, y, z) {
if (!(0, index_js_1.isNumber)(x) || !(0, index_js_1.isNumber)(y) || !(0, index_js_1.isNumber)(z)) {
info(getCmdInfo('digMap.remove'));
return;
}
const coords = `${x}, ${y}, ${z}`;
const index = digMapAddedCoordinates.indexOf(coords);
if (index === -1) {
return;
}
exports.bot.off(`blockUpdate:(${coords})`, exports.commands.commands.digMap.onBlockUpdate);
digMapAddedCoordinates.splice(index, 1);
},
clear() {
while (digMapAddedCoordinates.length !== 0) {
const coords = digMapAddedCoordinates.shift();
exports.bot.off(`blockUpdate:(${coords})`, exports.commands.commands.digMap.onBlockUpdate);
}
},
addspace(x1, y1, z1, x2, y2, z2) {
if (!(0, index_js_1.isNumber)(x1) || !(0, index_js_1.isNumber)(y1) || !(0, index_js_1.isNumber)(z1) || !(0, index_js_1.isNumber)(x2) || !(0, index_js_1.isNumber)(y2) || !(0, index_js_1.isNumber)(z2)) {
info(getCmdInfo('digMap.addspace'));
return;
}
const points = (0, pointsInBetween_js_1.pointsInBetween)((0, vec3_js_1.v)(x1, y1, z1), (0, vec3_js_1.v)(x2, y2, z2));
for (const vec of points) {
this.add(vec.x, vec.y, vec.z);
}
},
show() {
info('Added blocks:\n' + digMapAddedCoordinates.join('\n'));
}
};
await subCommands[subCmd.toLowerCase()](...args);
};
exports.commands.commands.digMap.onBlockUpdate = (oldBlock, newBlock) => {
if (!newBlock.diggable) {
return;
}
const addTask = (currentDepth) => {
if (exports.commands.tmp.botDigging || exports.commands.tmp.botLooking || exports.commands.tmp.botAttacking) {
return;
}
void digQueue.add(async () => {
const digSuccess = await botDig(newBlock.position, true, 'raycast', true);
if (!digSuccess) {
if (currentDepth >= 3) {
if (currentDepth < 8) {
await (0, sleep_js_1.sleep)(250);
}
else if (currentDepth < 15) {
await (0, sleep_js_1.sleep)(600);
}
else {
return;
}
}
addTask(currentDepth + 1);
}
});
};
addTask(0);
};
exports.commands.commands.place = async (x, y, z) => {
if (exports.commands.tmp.botLooking || exports.commands.tmp.botAttacking) {
warn(translatable_js_1.currentLang.data.infoMessages.botLookingOrAttackingErr);
return true;
}
if (!(0, index_js_1.isNumber)(x) || !(0, index_js_1.isNumber)(y) || !(0, index_js_1.isNumber)(z)) {
info(getCmdInfo('place'));
return;
}
exports.commands.tmp.botLooking = true;
try {
const position = (0, vec3_js_1.v)(x, y, z);
await mcUtils.placeBlock(position);
}
catch (e) {
const err = e;
switch (err.message) {
case 'x, y and z must be numbers':
info(getCmdInfo('place'));
break;
case 'Block is not empty':
warn(translatable_js_1.currentLang.data.infoMessages.alreadyBlockThere);
break;
case 'There are no valid blocks next to there':
warn(translatable_js_1.currentLang.data.infoMessages.blockPlaceAdjErr);
break;
case 'Impossible to place block from this angle':
warn(err.message);
break;
default:
error(`Could not place block.\n${err.message}`, true, err);
break;
}
return;
}
finally {
exports.commands.tmp.botLooking = false;
}
success('Successfully placed block');
};
exports.commands.commands.moveTo = async (X, Z, mustBeUndefined) => {
if (!(0, index_js_1.isNumber)(X) || !(0, index_js_1.isNumber)(Z) || mustBeUndefined !== undefined) {
info(getCmdInfo('moveTo'));
return;
}
info(`Attempting to move to ${X}, ${Z}`);
try {
await mcUtils.moveXZ(X, Z);
}
catch (err) {
error('Bot got stuck and couldn\'t reach its destination', true, err);
return;
}
success(`Moved to ${X}, ${Z}`);
};
exports.commands.commands.move = async (direction, distance) => {
if (!direction || (distance !== undefined && distance <= 0)) {
info(getCmdInfo('move'));
return;
}
if (exports.commands.tmp.botMoving) {
warn(translatable_js_1.currentLang.data.infoMessages.botMovingErr);
return;
}
distance = distance || 1;
let x = 0;
let z = 0;
switch (direction) {
case 'north':
z = -distance;
break;
case 'south':
z = distance;
break;
case 'east':
x = distance;
break;
case 'west':
x = -distance;
break;
default:
info('Usage: .move <Direction:north|south|east|west> <distance?>. Distance > 0');
return;
}
if (!Number.isInteger(distance)) {
warn('Distance must be an integer');
return;
}
exports.commands.tmp.botMoving = true;
let unit;
if (distance === 1)
unit = 'block';
else
unit = 'blocks';
info(`Attempting to move ${direction} for ${distance} ${unit}`);
const position = exports.bot.entity?.position;
try {
await mcUtils.moveXZ(position.x + x, position.z + z, 0, Infinity);
}
catch (e) {
const err = e;
warn(`${err.message}.\nStopped moving`);
return;
}
finally {
exports.commands.tmp.botMoving = false;
}
success(`Moved ${direction} for ${distance} ${unit}`);
};
async function botFollow(matchesStr, range) {
if (exports.commands.tmp.botMoving) {
return;
}
const sprintState = exports.bot.getControlState('sprint');
const jumpState = exports.bot.getControlState('jump');
exports.commands.tmp.botMoving = true;
while (exports.commands.tmp.botMoving) {
await (0, sleep_js_1.sleep)(150);
const entity = exports.bot.nearestEntity((entity) => {
try {
return (0, utils_js_1.matchEq)(matchesStr, entity);
}
catch {
if (!err)
err = true;
}
});
if (!entity) {
continue;
}
await mcUtils.followEntityWithJump(entity, range);
}
exports.bot.setControlState('sprint', sprintState);
exports.bot.setControlState('jump', jumpState);
}
exports.commands.commands.follow = async (matchesStr, range) => {
if (exports.commands.tmp.botMoving) {
warn(translatable_js_1.currentLang.data.infoMessages.botMovingErr);
return;
}
if (!['string', 'boolean'].includes(typeof matchesStr) || !(0, index_js_1.isNumber)(range) || range <= 0) {
info(getCmdInfo('follow'));
return;
}
try {
(0, utils_js_1.matchEq)(matchesStr, {});
}
catch {
info(getCmdInfo('follow'));
return;
}
let unit;
if (range === 1)
unit = 'block';
else
unit = 'blocks';
success(`Following nearest entity if ${matchesStr} with a range of ${range} ${unit}`);
void botFollow(matchesStr, range);
exports.commands.tmp.botMoving = true;
};
exports.commands.commands.pathfind = async (X, ZOrY, Z) => {
if (!(0, index_js_1.isNumber)(X) || !(0, index_js_1.isNumber)(ZOrY) || (!(0, index_js_1.isNumber)(Z) && Z !== undefined)) {
info(getCmdInfo('pathfind'));
return;
}
if (exports.commands.tmp.botMoving) {
warn(translatable_js_1.currentLang.data.infoMessages.botMovingErr);
return;
}
let goal;
let ZAndYStr;
if (Z) {
goal = new mineflayer_pathfinder_1.goals.GoalBlock(X, ZOrY, Z);
ZAndYStr = `${ZOrY}, ${Z}`;
}
else {
goal = new mineflayer_pathfinder_1.goals.GoalXZ(X, ZOrY);
ZAndYStr = String(ZOrY);
}
exports.commands.tmp.botMoving = true;
info(`Attempting to move to ${X}, ${ZAndYStr}`);
await exports.bot.pathfinder.goto(goal)
.catch((e) => {
const err = e;
error(`Could not move to ${X}, ${ZAndYStr}.\n${err.message}`, true, err);
exports.commands.tmp.botMoving = false;
});
success(`Moved to ${X}, ${ZAndYStr}`);
exports.commands.tmp.botMoving = false;
};
exports.commands.commands.forceMove = async (direction, time) => {
if ((direction === 'up' || direction === 'forward' || direction === 'back' || direction === 'left' || direction === 'right' || direction === 'sprint') && (0, index_js_1.isNumber)(time)) {
info(`Moving ${direction} for ${time} seconds`);
if (direction === 'up')
direction = 'jump';
exports.bot.setControlState(direction, true);
await (0, sleep_js_1.sleep)(time * 1000);
exports.bot.setControlState(direction, false);
success(`Moved ${direction} for ${time} seconds`);
}
else
info(getCmdInfo('forceMove'));
};
exports.commands.commands.control = (control, state) => {
if (['forward', 'back', 'left', 'right', 'jump', 'sprint', 'sneak'].includes(control) && typeof state === 'boolean') {
exports.bot.setControlState(control, state);
success(`Set control state ${control} to ${String(state)}`);
return;
}
if (control === 'clearall') {
exports.bot.clearControlStates();
success('Cleared all control states');
return;
}
info(getCmdInfo('control'));
};
async function botSmartFollow(matchesStr, range) {
if (!matchesStr || !range) {
return;
}
(0, utils_js_1.matchEq)(matchesStr, {});
while (exports.commands.tmp.botMoving) {
const entity = exports.bot.nearestEntity((entity) => {
try {
return entity ? (0, utils_js_1.matchEq)(matchesStr, entity) : false;
}
catch { }
});
if (((entity?.position) == null) || !exports.bot.entity?.position) {
await (0, sleep_js_1.sleep)(150);
continue;
}
const dist = (0, index_js_1.distance)(exports.bot.entity.position, entity.position) - 0.67;
if (dist < range) {
await (0, sleep_js_1.sleep)(150);
continue;
}
const goal = new mineflayer_pathfinder_1.goals.GoalFollow(entity, range);
try {
await exports.bot.pathfinder.goto(goal);
}
catch {
await (0, sleep_js_1.sleep)(1400);
}
}
}
exports.commands.commands.smartFollow = async (matchesStr, range) => {
if (exports.commands.tmp.botMoving) {
warn(translatable_js_1.currentLang.data.infoMessages.botMovingErr);
return;
}
if (!['string', 'boolean'].includes(typeof matchesStr) || !(0, index_js_1.isNumber)(range) || range <= 0) {
info(getCmdInfo('smartFollow'));
return;
}
try {
(0, utils_js_1.matchEq)(matchesStr, {});
}
catch {
info(getCmdInfo('smartFollow'));
return;
}
let unit;
if (range === 1)
unit = 'block';
else
unit = 'blocks';
success(`Following nearest entity if ${matchesStr} with a range of ${range} ${unit}`);
exports.commands.tmp.botMoving = true;
void botSmartFollow(matchesStr, range);
};
function botUnfollow() {
exports.commands.tmp.botMoving = false;
}
exports.commands.commands.unFollow = () => {
botUnfollow();
success('Not following anyone');
};
exports.commands.commands.attack = (matchesStr, cps, reach, minreach, force = true) => {
if (exports.commands.tmp.botAttacking) {
warn('Player is already attacking someone. Use ".stopattack"');
return;
}
if (exports.commands.tmp.botLooking) {
warn('Player is looking at someone. Use ".stoplook"');
return;
}
const usage = getCmdInfo('attack');
if (!['string', 'boolean'].includes(typeof matchesStr) || !(0, index_js_1.isNumber)(cps) || !(0, index_js_1.isNumber)(reach) || !(0, index_js_1.isNumber)(minreach) || cps <= 0 || reach <= 0 || reach < minreach) {
info(usage);
return;
}
try {
(0, utils_js_1.matchEq)(matchesStr, {});
}
catch {
info(usage);
return;
}
exports.commands.tmp.botLooking = true;
exports.commands.tmp.botAttacking = true;
success(`Attacking nearest entity with ${cps}CPS if ${matchesStr} and MinReach(${minreach}) < distance < MaxReach(${reach})`);
const yaw = exports.bot.entity.yaw;
const pitch = exports.bot.entity.pitch;
void (async () => {
while (exports.commands.tmp.botAttacking) {
await (0, sleep_js_1.sleep)(1000 / cps);
let err = false;
await mcUtils.botAttack(minreach, reach, exports.bot.nearestEntity((entity) => {
try {
if ((0, utils_js_1.matchEq)(matchesStr, entity) && (entity.type === 'player' || entity.type === 'mob' || entity.type === 'animal')) {
return true;
}
}
catch {
err = true;
}
}), force);
if (err) {
exports.commands.tmp.botAttacking = false;
exports.commands.tmp.botLooking = false;
error('Invalid EntityMatches');
}
}
await exports.bot.look(yaw, pitch, true);
})();
};
exports.commands.commands.stopAttack = () => {
if (exports.commands.tmp.botLooking && !exports.commands.tmp.botAttacking) {
warn('Cannot use ".stopattack" because player is looking at someone\nConsider ".stoplook"');
return;
}
exports.commands.tmp.botAttacking = false;
exports.commands.tmp.botLooking = false;
success('Not attacking anyone');
};
exports.commands.commands.look = async (directionOrYaw, pitchOrForce, force) => {
const isDirection = (0, index_js_2.isString)(directionOrYaw) && Object.keys(mcUtils.directionToYaw).includes(directionOrYaw);
const yaw = isDirection ? mcUtils.directionToYaw[directionOrYaw] : directionOrYaw;
const pitch = isDirection ? undefined : pitchOrForce;
force = isDirection ? pitchOrForce : force;
if (!((0, index_js_1.isNumber)(yaw) || yaw === undefined) || !((0, index_js_1.isNumber)(pitch) || pitch === undefined) || (yaw === undefined && pitch === undefined)) {
info(translatable_js_1.currentLang.data.commands.look.usage);
return;
}
await mcUtils.look(yaw, pitch, force);
success(`Set ${yaw !== undefined ? `Yaw to ${yaw}` : ''}` +
`${yaw !== undefined && pitch !== undefined ? ' and ' : ''}` +
`${pitch !== undefined ? `Pitch to ${pitch}` : ''}`);
};
exports.commands.commands.lookAt = (playerName, maxReach, minReach = maxReach, force) => {
if (!playerName || maxReach <= 0 || maxReach <= minReach) {
info(getCmdInfo('lookAt'));
return;
}
if (exports.commands.tmp.botLooking || exports.commands.tmp.botAttacking) {
warn(translatable_js_1.currentLang.data.infoMessages.botLookingOrAttackingErr);
return true;
}
exports.commands.tmp.botLooking = true;
if (force === 'yes' || force === 'y') {
force = true;
}
else {
force = false;
}
void (async () => {
while (exports.commands.tmp.botLooking) {
if (exports.bot.players[playerName]?.entity?.position) {
const dist = (0, index_js_1.distance)(exports.bot.players[playerName]?.entity?.position, exports.bot.entity.position);
if (dist < maxReach && dist > minReach) {
await mcUtils.lookAtVecMaxReach(exports.bot.players[playerName].entity.position, exports.bot.players[playerName].entity.height, exports.bot.players[playerName].entity.width, force);
}
}
await (0, sleep_js_1.sleep)(100);
}
})();
let withForce = 'without';
if (force) {
withForce = 'with';
}
success(`Looking at ${playerName} if MinReach(${minReach}) < distance < MaxReach(${maxReach}) ${withForce} force`);
};
exports.commands.commands.stopLook = () => {
if (exports.commands.tmp.botAttacking) {
warn('Cannot use ".stoplook" because player is attacking someone\nConsider ".stopattack"');
return;
}
exports.commands.tmp.botLooking = false;
info('Not looking at anyone');
};
const parseItemName = (item) => {
const name = item?.nbt?.value?.display?.value?.Name ??
item?.displayName ??
item?.name ??
'unknown_name (bug)';
let out = name;
try {
out = new ChatMessage(JSON.parse(name)).toMotd();
}
catch { }
return out?.value ?? out;
};
function renderWindow(window, options) {
const inventoryItems = mcUtils.getItems(window);
const a = (items) => {
if (items.length < 1) {
return 'Empty';
}
const make = (item, itemName, d = '') => {
let a = exports.bot.inventory.inventoryStart;
if (item.slot > exports.bot.inventory.inventoryEnd) {
a = -a;
}
let hotBarNum = a - (exports.bot.inventory.inventoryEnd - item.slot);
if (!(0, index_js_1.isNumber)(hotBarNum) || hotBarNum < 0) {
hotBarNum = ' ';
}
out = `${out + d + String(hotBarNum)} | #${item.slot}: x${item.count} ${itemName}`;
};
let out = '';
const itemm = items?.[0];
const itemNamee = parseItemName(itemm);
make(itemm, itemNamee);
for (let i = 1; i < items.length; i++) {
const item = items[i];
const itemName = parseItemName(item);
make(item, itemName, '\n');
}
return out;
};
info(a(inventoryItems) +
'\n' +
`\nCrafting result slot: ${window.craftingResultSlot}` +
`\nInventory start: ${window.inventoryStart}` +
`\nInventory end: ${window.inventoryEnd}` +
`\nHotbar start: ${window.hotbarStart}` +
`\nSelected slot: ${exports.bot.quickBarSlot}`);
}
exports.commands.commands.inventory = async (windowID, subCommand, ...args) => {
if (![0, 1, 'inventory', 'container'].includes(windowID)) {
info(getCmdInfo('inventory'));
return;
}
const isContainer = [1, 'container'].includes(windowID);
if (isContainer && !exports.bot.currentWindow) {
info(translatable_js_1.currentLang.data.infoMessages.noContainerOpenRN);
return;
}
const currentWindow = (isContainer && exports.bot.currentWindow) ? exports.bot.currentWindow : exports.bot.inventory;
const runSubCommand = async (cmd, args) => {
const checkIfSlotIsValid = (slotID) => {
if (typeof slotID !== 'number') {
return false;
}
if (slotID < currentWindow?.inventoryStart || slotID >= currentWindow.inventoryEnd) {
return false;
}
return true;
};
const close = () => {
if (!isContainer) {
warn('There is nothing to close');
return;
}
info(`Closing window #${windowID}`);
exports.bot.closeWindow(exports.bot.currentWindow);
};
const click = async (slotID, buttonIDName = 'left', buttonModeName) => {
if (checkIfSlotIsValid(slotID) || !(0, index_js_2.isString)(buttonIDName)) {
info(getCmdInfo('inventory.click'));
return;
}
const buttonID = buttonIDName === 'right' ? 1 : 0;
const buttonMode = 0;
info(`${buttonIDName} clicking slot ${String(slotID)} in window #${windowID}`);
await exports.bot.clickWindow(slotID, buttonID, buttonMode);
};
const swap = async (slot1ID, slotDestID) => {
if (!checkIfSlotIsValid(slot1ID) || !checkIfSlotIsValid(slotDestID)) {
info(getCmdInfo('inventory.swap'));
return;
}
info(`Swapping item at slot ${slot1ID} with item at slot ${slotDestID} in window #${windowID}`);
await exports.bot.clickWindow(inventoryStartOffset + slot1ID, 0, 0);
await (0, sleep_js_1.sleep)(20);
await exports.bot.clickWindow(inventoryStartOffset + slotDestID, 0, 0);
await (0, sleep_js_1.sleep)(20);
await exports.bot.clickWindow(inventoryStartOffset + slot1ID, 0, 0);
};
const drop = async (slotIDs) => {
if (slotIDs.length === 0) {
info(getCmdInfo('inventory.drop'));
return;
}
for (const slotID of slotIDs) {
if (!checkIfSlotIsValid(slotID)) {
info(translatable_js_1.currentLang.data.commands.inventory?.subCommands?.drop?.usage);
return;
}
}
info(`Dropping items in slots ${slotIDs.join(', ')} in window #${windowID}`);
for (const slotID of slotIDs) {
await exports.bot.clickWindow(inventoryStartOffset + slotID, 0, 0);
await (0, sleep_js_1.sleep)(10);
await exports.bot.clickWindow(-999, 0, 0);
}
};
const dropall = async () => {
const items = isContainer
? mcUtils.getItems(exports.bot.currentWindow, exports.bot.inventory.inventoryEnd)
: exports.bot.inventory.items();
info(`Dropping all items in window #${windowID}`);
for (let i = 0; i < items.length; i++) {
await exports.bot.clickWindow(inventoryStartOffset + items[i].slot, 0, 0);
await (0, sleep_js_1.sleep)(10);
await exports.bot.clickWindow(-999, 0, 0);
}
};
const inventoryStartOffset = (!isContainer && exports.bot.currentWindow?.inventoryEnd && exports.bot.inventory?.inventoryEnd)
? exports.bot.currentWindow.inventoryEnd - exports.bot.inventory.inventoryEnd
: 0;
cmd = cmd.toLowerCase();
args = (0, utils_js_1.toLowerCaseArr)(args);
switch (cmd) {
case 'close':
close();
return;
case 'click':
await click(...args);
return;
case 'swap':
await swap(...args);
return;
case 'drop':
await drop(args);
return;
case 'dropall':
await dropall();
return;
default:
info(getCmdInfo('inventory'));
}
};
if (subCommand !== undefined) {
if (typeof subCommand === 'string') {
await runSubCommand(subCommand, args);
return;
}
info(getCmdInfo('inventory'));
return;
}
renderWindow(currentWindow);
};
exports.commands.commands.open = async (x, y, z) => {
if (!(0, index_js_1.isNumber)(x) || !(0, index_js_1.isNumber)(y) || !(0, index_js_1.isNumber)(z)) {
info(getCmdInfo('open'));
return;
}
if (exports.commands.tmp.botLooking || exports.commands.tmp.botAttacking) {
warn(translatable_js_1.currentLang.data.infoMessages.botLookingOrAttackingErr);
return true;
}
const blockPos = (0, vec3_js_1.v)(x, y, z);
const block = exports.bot.blockAt(blockPos);
info('Attempting to open container');
await exports.bot.openContainer(block)
.then(() => {
success('Opened the container');
})
.catch((err) => {
error(err.message, true, err);
});
};
exports.commands.commands.changeSlot = (slot) => {
if ((0, index_js_1.isNumber)(slot) && slot > -1 && slot < 9) {
exports.bot.setQuickBarSlot(slot);
info(`Changed slot to ${slot}`);
}
else
info(getCmdInfo('changeSlot'));
};
exports.commands.commands.useItem = async (sec) => {
if (sec > 3) {
info(`Using an item for ${sec ?? 0.1}s`);
}
exports.bot.activateItem();
await (0, sleep_js_1.sleep)(sec * 1000);
exports.bot.deactivateItem();
success(`Used an item for ${sec}s`);
};
exports.commands.commands.set = (key, value) => {
if (key === undefined) {
info(getCmdInfo('set'));
return;
}
exports.commands.tmp.variables[key] = value;
success(`Set %${key}% to ${String(value)}`);
};
exports.commands.commands.unset = (key) => {
if (key === undefined) {
info(getCmdInfo('unset'));
return;
}
delete exports.commands.tmp.variables[key];
success(`Deleted %${key}%`);
};
exports.commands.commands.value = (key) => {
if (key === undefined) {
info(getCmdInfo('value'));
return;
}
info(`${key}: ${String(exports.commands.tmp.variables[key])}`);
};
exports.commands.commands.variables = () => {
const values = Object.values(exports.commands.tmp.variables);
const keys = Object.keys(exports.commands.tmp.variables);
let out = '';
if (keys[0] !== undefined)
out = `${keys[0]}: ${String(values[0])}`;
for (let i = 1; i < values.length; i++) {
if (keys[i] === undefined)
continue;
out = `${out}\n${keys[i]}: ${String(values[i])}`;
}
info('Values:\n' + out);
};
exports.commands.commands.script = async (pathToSrc) => {
if (!pathToSrc) {
info(getCmdInfo('script'));
return;
}
try {
(0, fs_1.accessSync)(pathToSrc, fs_1.constants.F_OK);
}
catch (err) {
info('Unable to access file');
return;
}
const data = (0, fs_1.readFileSync)(pathToSrc, { encoding: 'UTF8' });
for (const line of data.split(/[\n;]/)) {
await exports.commands.interpret(line, { type: 'script' });
}
};
exports.commands.commands.version = () => {
info(`${package_js_1._package.name} version: ${package_js_1._package.version}\nNode version: ${process.version}`);
};
exports.commands.commands.wait = async (sec) => {
await (0, sleep_js_1.sleep)(sec * 1000);
};
exports.commands.commands.async = async (...input) => {
if (!input[0]) {
warn('No command provided');
return;
}
void exports.commands.interpret(input.join(' '), { type: 'script' });
};
exports.commands.commands.print = print;
exports.commands.commands.success = success;
exports.commands.commands.info = info;
exports.commands.commands.warn = warn;
exports.commands.commands.error = error;
exports.commands.commands.help = () => {
const getCmdDesc = (cmd) => {
if (exports.reservedCommandNames.includes(cmd)) {
return null;
}
return getCmdInfo(cmd, 'description');
};
let out = '';
const commandNames = Object.keys(exports.commands.commands);
for (let a = 0; a < commandNames.length; a++) {
const command = commandNames[a];
if (exports.reservedCommandNames.includes(command)) {
continue;
}
let end = '\n';
if (a === commandNames.length - 2) {
end = '';
}
out += '.' + (0, tabulate_js_1.tab)(command, getCmdDesc(command) ?? '', 15) + end;
}
info(out);
};
;