diff --git a/services/minecraft/src/agents/action/tools.ts b/services/minecraft/src/agents/action/tools.ts index 5d7ea4dc0..75dd5155e 100644 --- a/services/minecraft/src/agents/action/tools.ts +++ b/services/minecraft/src/agents/action/tools.ts @@ -90,7 +90,7 @@ export const actionsList: Action[] = [ // await ctx.actions.stop() // ctx.clearBotLogs() // ctx.actions.cancelResume() - mineflayer.emit('interrupt') // FIXME: this doesn't work! + mineflayer.interrupt('stop tool called') const msg = 'Agent stopped.' // if (mineflayer.self_prompter.on) // msg += ' Self-prompting still active.' diff --git a/services/minecraft/src/libs/mineflayer/core.ts b/services/minecraft/src/libs/mineflayer/core.ts index 6d9d5332c..156eb1dcb 100644 --- a/services/minecraft/src/libs/mineflayer/core.ts +++ b/services/minecraft/src/libs/mineflayer/core.ts @@ -53,6 +53,45 @@ export class Mineflayer extends EventEmitter { }) } + public interrupt(reason?: string) { + this.logger.withFields({ reason }).log('Interrupt requested') + + try { + (this.bot as any).pathfinder?.stop?.() + } + catch { } + + try { + (this.bot as any).pvp?.stop?.() + } + catch { } + + try { + ; (this.bot as any).stopDigging?.() + } + catch { } + + try { + ; (this.bot as any).deactivateItem?.() + } + catch { } + + try { + if (typeof (this.bot as any).clearControlStates === 'function') { + ; (this.bot as any).clearControlStates() + } + else { + ; (['forward', 'back', 'left', 'right', 'jump', 'sprint', 'sneak'] as const).forEach((control) => { + this.bot.setControlState(control as any, false) + }) + } + } + catch { } + + this.logger.withFields({ reason }).log('Interrupted') + this.emit('interrupt') + } + public static async asyncBuild(options: MineflayerOptions) { const mineflayer = new Mineflayer(options)