Compare commits
	
		
			No commits in common. "e785aaa6a235e2e5566f014a9bb2e4e8003f198f" and "73a667eeb4b6a014bfae8a2a7ae87939924188fb" have entirely different histories.
		
	
	
		
			e785aaa6a2
			...
			73a667eeb4
		
	
		
| @ -1,5 +1,5 @@ | ||||
| import axios from 'axios'; | ||||
| import { readJsonFile, writeJsonFile } from 'compass-utils'; | ||||
| import { readJsonFile, writeJsonFile } from '../utils/index.mjs'; | ||||
| 
 | ||||
| export class NoCredentialError extends Error { | ||||
| 	constructor(profile) { | ||||
| @ -46,10 +46,6 @@ export class Account { | ||||
| 		return new SessionCache(auth_info.accessToken, auth_info.clientToken | ||||
| 			, auth_info.selectedProfile, auth_info.availableProfiles); | ||||
| 	} | ||||
| 
 | ||||
| 	toString() { | ||||
| 		return this.handle; | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| export class Credentials { | ||||
| @ -181,3 +177,8 @@ export class SessionCache { | ||||
| 		}; | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| export default { | ||||
| 	NoCredentialError, ProfileNotSelectedError, ProfileAlreadySelectedError | ||||
| 	, YggdrasilEndpoint, Account, Credentials, SessionCache | ||||
| }; | ||||
| @ -1,64 +0,0 @@ | ||||
| 
 | ||||
| export class BehaviorTree { | ||||
| 	constructor(root) { | ||||
| 		this.root = root; | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| export class Node { | ||||
| 	constructor() {} | ||||
| }; | ||||
| 
 | ||||
| export class ExecutionNode extends Node { | ||||
| 	constructor() { | ||||
| 		super(); | ||||
| 	} | ||||
| 
 | ||||
| 	isLeaf() { return true; } | ||||
| }; | ||||
| 
 | ||||
| export class ControlNode extends Node { | ||||
| 	constructor() { | ||||
| 		super(); | ||||
| 		this.children = []; | ||||
| 	} | ||||
| 
 | ||||
| 	isLeaf() { return false; } | ||||
| 	appendChild(child) { | ||||
| 		this.children.push(child); | ||||
| 		return this; | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| export class SequenceNode extends ControlNode { | ||||
| 	constructor() { | ||||
| 		super(); | ||||
| 	} | ||||
| 
 | ||||
| 	async tick(blackboard) { | ||||
| 		for (let child of this.children) { | ||||
| 			await child.tick(blackboard); | ||||
| 		} | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| export class FallbackNode extends ControlNode { | ||||
| 	constructor() { super(); } | ||||
| 
 | ||||
| 	async tick(blackboard) { | ||||
| 		for (let i = 0; i < this.children.length; i += 1) { | ||||
| 			try { | ||||
| 				await child.tick(blackboard); | ||||
| 				break; | ||||
| 			} catch(err) { | ||||
| 				if (i == this.children.length - 1) { throw err; } | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| export class ParallelNode extends ControlNode { | ||||
| 	constructor() { super(); } | ||||
| 
 | ||||
| 	async tick(blackboard) {} | ||||
| } | ||||
| @ -1,10 +0,0 @@ | ||||
| { | ||||
| 	"name": "compass-behavior-tree", | ||||
| 	"description": "Behavior Tree Library", | ||||
| 	"type": "module", | ||||
| 	"main": "index.mjs", | ||||
| 	"dependencies": { | ||||
| 		"debug": "^4.3.4", | ||||
| 		"compass-utils": "file:../utils" | ||||
| 	} | ||||
| } | ||||
| @ -1,7 +1,7 @@ | ||||
| import * as authlib from './auth/authlib.mjs'; | ||||
| import authlib from './auth/authlib.mjs'; | ||||
| import mineflayer from 'mineflayer'; | ||||
| import yargs from 'yargs'; | ||||
| import { parseLogin, waitEvent } from 'compass-utils'; | ||||
| import { parseLogin, waitEvent } from './utils/index.mjs'; | ||||
| import repl from 'node:repl'; | ||||
| import vm from 'node:vm'; | ||||
| 
 | ||||
| @ -37,12 +37,9 @@ async function main() { | ||||
| 		host, port, version: args.protocal, | ||||
| 		...session.mineflayer(credential_info.endpoint) | ||||
| 	}); | ||||
| 	bot.on('error', console.error); | ||||
| 	bot.on('kicked', console.log); | ||||
| 
 | ||||
| 	await waitEvent(bot, 'inject_allowed'); | ||||
| 	bot.loadPlugin((await import('mineflayer-event-promise')).default); | ||||
| 	bot.loadPlugin((await import('mineflayer-control')).default); | ||||
| 	await bot.waitEvent('spawn'); | ||||
| 
 | ||||
| 	let context = vm.createContext(); | ||||
|  | ||||
| @ -12,8 +12,6 @@ | ||||
|     "debug": "^4.3.4", | ||||
|     "mineflayer": "^4.14.0", | ||||
|     "mineflayer-event-promise": "file:plugin/event-promise", | ||||
|     "compass-utils": "file:utils", | ||||
|     "mineflayer-control": "file:plugin/control", | ||||
|     "mineflayer-pathfinder": "^2.4.5", | ||||
|     "prismarine-viewer": "^1.25.0", | ||||
|     "yargs": "^17.7.2" | ||||
|  | ||||
| @ -1,180 +0,0 @@ | ||||
| import debug from 'debug'; | ||||
| import { Task } from 'compass-utils'; | ||||
| import { Vec3 } from 'vec3'; | ||||
| const logger = debug('mineflayer-control'); | ||||
| 
 | ||||
| // yaw = axis * Math.PI / 2
 | ||||
| // name = "ZX"[axis % 2]
 | ||||
| export const AXIS = { | ||||
| 	'-Z': 0, | ||||
| 	'-X': 1, | ||||
| 	'+Z': 2, | ||||
| 	'+X': 3, | ||||
| 	NORTH: 0, | ||||
| 	WEST: 1, | ||||
| 	SOUTH: 2, | ||||
| 	EAST: 3, | ||||
| 	0: 0, | ||||
| 	1: 1, | ||||
| 	2: 2, | ||||
| 	3: 3, | ||||
| }; | ||||
| 
 | ||||
| export const AXIS_UNIT = { | ||||
| 	0: new Vec3(0, 0, -1), | ||||
| 	1: new Vec3(-1, 0, 0), | ||||
| 	2: new Vec3(0, 0, 1), | ||||
| 	3: new Vec3(1, 0, 0), | ||||
| }; | ||||
| 
 | ||||
| AXIS_UNIT['-Z'] = AXIS_UNIT['NORTH'] = AXIS_UNIT[0]; | ||||
| AXIS_UNIT['-X'] = AXIS_UNIT['WEST'] = AXIS_UNIT[1]; | ||||
| AXIS_UNIT['+Z'] = AXIS_UNIT['SOUTH'] = AXIS_UNIT[2]; | ||||
| AXIS_UNIT['+X'] = AXIS_UNIT['EAST'] = AXIS_UNIT[3]; | ||||
| 
 | ||||
| export const MOVE_LEVEL = { | ||||
| 	WALK: 1, | ||||
| 	SPRINT: 2, | ||||
| 	// TODO: SPRINT_JUMP
 | ||||
| }; | ||||
| 
 | ||||
| export class ControlState { | ||||
| 	constructor() { | ||||
| 		for (let key of ControlState.CONTROLS) { | ||||
| 			this[key] = false; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	set(cs) { | ||||
| 		for (let key of ControlState.CONTROLS) { | ||||
| 			this[key] = cs[key] || false; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	static from(cs) { | ||||
| 		let res = new ControlState(); | ||||
| 		res.set(cs); | ||||
| 		return res; | ||||
| 	} | ||||
| 
 | ||||
| 	apply(bot) { | ||||
| 		for (let key of ControlState.CONTROLS) { | ||||
| 			bot.setControlState(key, this[key]); | ||||
| 		} | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| ControlState.CONTROLS = ['forward', 'back', 'left', 'right', 'jump', 'sprint', 'sneak']; | ||||
| 
 | ||||
| function adjust05(x) { | ||||
| 	return Math.floor(x) + .5; | ||||
| } | ||||
| 
 | ||||
| function adjustXZ(vec) { | ||||
| 	vec.x = adjust05(vec.x); | ||||
| 	vec.z = adjust05(vec.z); | ||||
| } | ||||
| 
 | ||||
| export class MoveInterferedError extends Error { | ||||
| 	constructor() { super('Move task has been interfered by an external force.'); } | ||||
| }; | ||||
| 
 | ||||
| async function moveAxisTask(bot, task, axis_raw, target_raw, level) { | ||||
| 	const axis = AXIS[axis_raw]; | ||||
| 	const stable_axis = "xz"[axis % 2]; | ||||
| 	const target = target_raw.clone(); | ||||
| 	adjustXZ(target); | ||||
| 
 | ||||
| 	bot.clearControlStates(); | ||||
| 	bot.control.adjustXZ(); | ||||
| 
 | ||||
| 	let pos = bot.entity.position; | ||||
| 	const delta = target.minus(pos); | ||||
| 	let remaining_dis = delta.dot(AXIS_UNIT[axis]); | ||||
| 
 | ||||
| 	logger(`moveAxisTask() source: ${pos}.`); | ||||
| 	logger(`moveAxisTask() target: ${target}.`); | ||||
| 	logger(`moveAxisTask() delta: ${delta}.`); | ||||
| 	logger(`moveAxisTask() distance: ${remaining_dis}.`); | ||||
| 	logger(`moveAxisTask() stable_axis: ${stable_axis}.`); | ||||
| 	logger(`moveAxisTask() Condition: ${delta[stable_axis]} ${delta.y}.`); | ||||
| 	if (Math.abs(delta.y) > Number.EPSILON || Math.abs(delta[stable_axis]) > Number.EPSILON) { | ||||
| 		throw new Error('Invalid Argument: target'); | ||||
| 	} | ||||
| 
 | ||||
| 	if (remaining_dis < 0) { | ||||
| 		throw new Error('Invalid Argument: axis argument should reverse its sign.'); | ||||
| 	} | ||||
| 
 | ||||
| 	const stable_axis_value = target[stable_axis]; | ||||
| 
 | ||||
| 	logger('moveAxisTask() pre adjust look angle'); | ||||
| 	await bot.look(axis * Math.PI / 2, 0); | ||||
| 	logger('moveAxisTask() post adjust look angle'); | ||||
| 	task._interuptableHere(); | ||||
| 
 | ||||
| 	const controls = new ControlState(); | ||||
| 	controls.forward = true; | ||||
| 	if (level >= MOVE_LEVEL.SPRINT) { controls.sprint = true; } | ||||
| 	logger('moveAxisTask() control', controls); | ||||
| 	controls.apply(bot); | ||||
| 	logger('moveAxisTask() started.'); | ||||
| 
 | ||||
| 	let time_used = 0; | ||||
| 	do { | ||||
| 		await bot.waitForTicks(1); | ||||
| 		task._interuptableHere(); | ||||
| 
 | ||||
| 		controls.apply(bot); | ||||
| 		time_used += 1; | ||||
| 		pos = bot.entity.position; | ||||
| 		if (Math.abs(pos[stable_axis] - stable_axis_value) > 1.2) { | ||||
| 			logger('moveAxisTask() stable axis changed.'); | ||||
| 			logger(`moveAxisTask() target.${stable_axis}: ${stable_axis_value}.`); | ||||
| 			logger(`moveAxisTask() pos.${stable_axis}: ${pos[stable_axis]}.`); | ||||
| 			throw new MoveInterferedError(); | ||||
| 		} | ||||
| 		pos[stable_axis] = stable_axis_value; | ||||
| 
 | ||||
| 		delta.update(target.minus(pos)); | ||||
| 		remaining_dis = delta.dot(AXIS_UNIT[axis]); | ||||
| 		if (Math.abs(remaining_dis) <= 0.5) { | ||||
| 			logger('moveAxisTask() very close to target now.'); | ||||
| 			pos.update(target); | ||||
| 			bot.entity.velocity.x = 0; | ||||
| 			bot.entity.velocity.z = 0; | ||||
| 			break; | ||||
| 		} | ||||
| 
 | ||||
| 		if (remaining_dis < -0.5) { | ||||
| 			logger('moveAxisTask() went past target.'); | ||||
| 			throw new MoveInterferedError(); | ||||
| 		} | ||||
| 	} while (true); | ||||
| 	bot.clearControlStates(); | ||||
| 	task._ready(time_used); | ||||
| } | ||||
| 
 | ||||
| export default function inject(bot) { | ||||
| 	bot.control = {}; | ||||
| 	bot.control.getState = () => { return ControlState.from(bot.controlState); }; | ||||
| 	bot.control.adjustXZ = () => { adjustXZ(bot.entity.position); }; | ||||
| 
 | ||||
| 	bot.control.moveAxis = (axis, target, level = MOVE_LEVEL.SPRINT) => { | ||||
| 		let task = new Task(); | ||||
| 		queueMicrotask(() => { | ||||
| 			task._start(); | ||||
| 			moveAxisTask(bot, task, axis, target, level).catch(err => { | ||||
| 				bot.clearControlStates(); | ||||
| 				task._fail(err); | ||||
| 			}); | ||||
| 		}); | ||||
| 		return task; | ||||
| 	}; | ||||
| 
 | ||||
| 	bot.control.jump = async () => { | ||||
| 		bot.setControlState('jump', true); | ||||
| 		await bot.waitForTicks(1); | ||||
| 		bot.setControlState('jump', false); | ||||
| 	}; | ||||
| } | ||||
| @ -1,11 +0,0 @@ | ||||
| { | ||||
| 	"name": "mineflayer-control", | ||||
| 	"description": "High-level & handy API for mineflayer bot movement control.", | ||||
| 	"type": "module", | ||||
| 	"main": "index.mjs", | ||||
| 	"dependencies": { | ||||
| 		"debug": "^4.3.4", | ||||
| 		"vec3": "^0.1.8", | ||||
| 		"compass-utils": "file:../../utils" | ||||
| 	} | ||||
| } | ||||
| @ -1,4 +1,4 @@ | ||||
| export class TaskInteruptedError extends Error { | ||||
| export class TaskInteruptedError { | ||||
| 	constructor() { super('Task has been interupted.'); } | ||||
| }; | ||||
| 
 | ||||
| @ -45,13 +45,6 @@ export class Task { | ||||
| 		this.#notifyFailure(); | ||||
| 	} | ||||
| 
 | ||||
| 	_interuptableHere() { | ||||
| 		if (this._shouldInterupt()) { | ||||
| 			this._confirmInterupt(); | ||||
| 			throw this.error; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	get() { | ||||
| 		if (this.status == Task.STATUS.ready) { return Promise.resolve(this.result); } | ||||
| 		if (this.status == Task.STATUS.failed || this.status == Task.STATUS.interupted) { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user