120 lines
3.8 KiB
JavaScript
120 lines
3.8 KiB
JavaScript
import * as authlib from './auth/authlib.mjs';
|
|
import mineflayer from 'mineflayer';
|
|
import yargs from 'yargs';
|
|
import { asyncSleep, parseLogin, waitEvent } from 'compass-utils';
|
|
import repl from 'node:repl';
|
|
import 'enhanced-vec3';
|
|
import debug from 'debug';
|
|
import { createLocalRepl, createTcpReplServer } from './repl/index.mjs';
|
|
import { randomBytes } from 'node:crypto';
|
|
|
|
async function main() {
|
|
const args = yargs((await import('yargs/helpers')).hideBin(process.argv))
|
|
.option('protocal', {
|
|
description: 'Minecraft server version',
|
|
type: 'string',
|
|
requiresArg: false,
|
|
}).option('owner', {
|
|
description: 'Bot\'s owner name.',
|
|
type: 'string',
|
|
requiresArg: false,
|
|
}).option('no-local-repl', {
|
|
description: 'Disable bot REPL control in current stdin/stdout.',
|
|
type: "boolean",
|
|
}).option('credentials-lib', {
|
|
description: 'Credentials\' library file.',
|
|
type: "string",
|
|
default: "credentials.json",
|
|
}).option('offline', {
|
|
description: 'Login without credentials.',
|
|
type: 'boolean',
|
|
}).option('enable-tcp-repl', {
|
|
description: 'Enable bot REPL control as a TCP service.',
|
|
type: 'boolean',
|
|
}).option('tcp-repl-port', {
|
|
description: 'Telnet REPL service port.',
|
|
type: 'number',
|
|
default: 2121,
|
|
}).option('remote-repl-passcode-length', {
|
|
description: 'Length of remote REPL passcode in bytes',
|
|
type: 'number',
|
|
default: 8,
|
|
}).usage('Uasge: profile@hostname[:port]').help().alias('help', 'h').argv;
|
|
|
|
let login_info = args._[0];
|
|
if (login_info == null) { return; }
|
|
const [name, hostname, port] = parseLogin(login_info);
|
|
|
|
let session, endpoint = null;
|
|
if (args.offline) {
|
|
session = new authlib.OfflineSession(name);
|
|
} else {
|
|
const credential_info = await authlib.Credentials.fromFile(args.credentialsLib);
|
|
if (credential_info == null) {
|
|
throw new Error(`Cannot load credential ${args.credentialsLib}`);
|
|
}
|
|
session = await credential_info.authProfile(name);
|
|
endpoint = credential_info.endpoint;
|
|
}
|
|
|
|
const bot = mineflayer.createBot({
|
|
host: hostname, port, version: args.protocal,
|
|
...session.mineflayer(endpoint)
|
|
});
|
|
bot.on('error', console.error);
|
|
bot.on('kicked', console.log);
|
|
bot.on('end', () => {
|
|
console.log('Disconnected. Exiting...');
|
|
process.exit(0);
|
|
});
|
|
|
|
await waitEvent(bot, 'inject_allowed');
|
|
bot.loadPlugin((await import('mineflayer-event-promise')).default);
|
|
bot.loadPlugin((await import('mineflayer-control')).default);
|
|
bot.loadPlugin((await import('mineflayer-fly-control')).default);
|
|
await bot.waitEvent('spawn');
|
|
|
|
const context_shared = {};
|
|
async function loadReplContextModules(context) {
|
|
context.lib = {
|
|
utils: await import('compass-utils'),
|
|
control: await import('mineflayer-control'),
|
|
flyctl: await import('mineflayer-fly-control'),
|
|
};
|
|
context.bot = bot;
|
|
context.Vec3 = (await import('vec3')).Vec3;
|
|
context.mineflayer = mineflayer;
|
|
context.owner = () => {
|
|
if (!args.owner) { return null; }
|
|
return bot.players[args.owner];
|
|
};
|
|
|
|
context.PI = Math.PI;
|
|
context.debug = debug;
|
|
context.bb = context_shared;
|
|
context.sc = {};
|
|
context.sc.pos = () => bot.entity.position;
|
|
context.sc.debug_mfc = () => debug.enable('mineflayer-control');
|
|
context.sc.debug_mff = () => debug.enable('mineflayer-fly-control');
|
|
context.sc.sleep = asyncSleep;
|
|
context.sc.tossHeld = () => bot.tossStack(bot.heldItem);
|
|
}
|
|
|
|
if (args.enableTcpRepl) {
|
|
const passcode = randomBytes(args.remoteReplPasscodeLength);
|
|
console.log('Remote REPL Passcode:', passcode.toString('hex'));
|
|
let server = createTcpReplServer(args.tcpReplPort, passcode, loadReplContextModules);
|
|
process.on('exit', () => server.close());
|
|
}
|
|
|
|
if (!args.noLocalRepl) {
|
|
let repl_local = createLocalRepl(loadReplContextModules);
|
|
repl_local.on('exit', () => bot.quit());
|
|
}
|
|
}
|
|
|
|
main().catch(err => {
|
|
console.error(`Error: ${err}`);
|
|
process.exit(1);
|
|
});
|