From 8381f2da08c4d9f23667fc80639461aa6a841fd4 Mon Sep 17 00:00:00 2001 From: RainbowBird Date: Thu, 9 Jan 2025 13:14:39 +0800 Subject: [PATCH] refactor: EventEmitter3 --- .../minecraft/src/libs/mineflayer/index.ts | 21 +++++-------------- .../minecraft/src/libs/mineflayer/ticker.ts | 21 +++++++------------ 2 files changed, 13 insertions(+), 29 deletions(-) diff --git a/services/minecraft/src/libs/mineflayer/index.ts b/services/minecraft/src/libs/mineflayer/index.ts index 1f482096e..1e146cc62 100644 --- a/services/minecraft/src/libs/mineflayer/index.ts +++ b/services/minecraft/src/libs/mineflayer/index.ts @@ -3,6 +3,7 @@ import type { Message } from 'neuri/openai' import type { z } from 'zod' import type { MineflayerPlugin } from './plugin' import { useLogg } from '@guiiai/logg' +import EventEmitter from 'eventemitter3' import mineflayer from 'mineflayer' import { type CommandContext, parseCommand } from './command' import { formBotChat } from './message' @@ -26,16 +27,6 @@ export type EventsHandler = EventHandlers[K] export type Handler = (ctx: Context) => void | Promise -function createEventHandlers(): Record>> { - return { - 'command': [], - 'time:sunrise': [], - 'time:noon': [], - 'time:sunset': [], - 'time:midnight': [], - } -} - export class Health { public value: number public lastDamageTime?: number @@ -133,7 +124,7 @@ export interface MineflayerOptions { plugins?: Array } -export class Mineflayer { +export class Mineflayer extends EventEmitter { public bot: Bot public username: string public health: Health = new Health() @@ -149,10 +140,10 @@ export class Mineflayer { private options: MineflayerOptions private logger: ReturnType private commands: Map> = new Map() - private eventHandlers = createEventHandlers() private ticker: Ticker = new Ticker() constructor(options: MineflayerOptions) { + super() this.options = options this.bot = mineflayer.createBot(options.botConfig) this.username = options.botConfig.username @@ -277,10 +268,7 @@ export class Mineflayer { } public emit(event: E, ...args: Parameters>) { - const handlers = this.eventHandlers[event] - for (const handler of handlers) { - handler(args[0]) - } + return super.emit(event, ...args) } public async stop() { @@ -292,6 +280,7 @@ export class Mineflayer { this.components.cleanup() this.bot.removeListener('chat', this.handleCommand()) this.bot.end() + this.removeAllListeners() } private handleCommand() { diff --git a/services/minecraft/src/libs/mineflayer/ticker.ts b/services/minecraft/src/libs/mineflayer/ticker.ts index 8f95372e9..87f3f884b 100644 --- a/services/minecraft/src/libs/mineflayer/ticker.ts +++ b/services/minecraft/src/libs/mineflayer/ticker.ts @@ -1,3 +1,5 @@ +import EventEmitter from 'eventemitter3' + export interface TickContext { delta: number nextTick: () => Promise @@ -11,29 +13,23 @@ export type TickEvents = keyof TickEventHandlers export type TickEventsHandler = TickEventHandlers[K] // This update loop ensures that each update() is called one at a time, even if it takes longer than the interval -export class Ticker { - private tickingCbs: Record> = { - tick: [], - } - +export class Ticker extends EventEmitter { constructor(options?: { interval?: number }) { + super() const { interval = 300 } = options ?? { interval: 300 } let last = Date.now() - const tickingCbs: Record> = { - tick: [], - } setTimeout(async () => { while (true) { const start = Date.now() const nextTickPromise = new Promise((resolve) => { - // Schedule nextTick resolution for after all callbacks complete + // Schedule nextTick resolution for after all callbacks complete setImmediate(resolve) }) // Run all callbacks without awaiting them - const callbackPromises = tickingCbs.tick.map(cb => cb({ + const callbackPromises = this.listeners('tick').map(cb => cb({ delta: start - last, nextTick: () => nextTickPromise, })) @@ -47,9 +43,8 @@ export class Ticker { ]) const remaining = interval - (Date.now() - start) - if (remaining > 0) { + if (remaining > 0) await new Promise(resolve => setTimeout(resolve, remaining)) - } last = start } @@ -57,6 +52,6 @@ export class Ticker { } on(event: K, cb: TickEventsHandler) { - this.tickingCbs[event].push(cb) + return super.on(event, cb) } }