From 1ac8e3fb28f418c7b59dbbb4f4e976b11e4bd506 Mon Sep 17 00:00:00 2001 From: Rin Date: Fri, 9 Jan 2026 04:38:31 +0800 Subject: [PATCH] fix(minecraft): implement proper interrupt method to stop bot actions - Add `interrupt()` method to Mineflayer class with comprehensive action stopping - Stop pathfinder, pvp, digging, item usage, and control states - Replace non-working `emit('interrupt')` with `interrupt()` call in stop tool - Add logging for interrupt requests and completion - Remove FIXME comment as issue is now resolved --- services/minecraft/src/agents/action/tools.ts | 2 +- .../minecraft/src/libs/mineflayer/core.ts | 39 +++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) 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)