import {readdir} from 'node:fs/promises'; import {console_print} from '../utils/console_print.ts'; import type {Socket} from "socket.io-client"; type handler = (socket: Socket, ...args: any[]) => unknown | Promise; const handler_map = new Map(); export async function init_event_handler_list(): Promise { try { const next_handlers = new Map(); const directories = [new URL('./', import.meta.url)]; for (const directory of directories) { const entries = await readdir(directory, {withFileTypes: true}); entries.sort((a, b) => a.name.localeCompare(b.name)); for (const entry of entries) { const url = new URL(encodeURIComponent(entry.name), directory); if (entry.isDirectory()) { directories.push(new URL(`${url.href}/`)); continue; } if (!entry.isFile() || !/^[a-zA-Z0-9_-]+\.ts$/.test(entry.name) || url.pathname === new URL(import.meta.url).pathname) { continue; } const event = entry.name.slice(0, -3); if (next_handlers.has(event)) { throw new Error(`事件 ${event} 的处理器重复定义`); } try { url.searchParams.set('t', `${Date.now()}-${process.hrtime.bigint()}`); const module = await import(url.href); if (typeof module.handler !== 'function') { throw new Error('模块必须导出 handler 函数'); } next_handlers.set(event, module.handler); } catch (error) { throw new Error(`事件处理器 ${url.href} 加载失败: ${error instanceof Error ? error.message : String(error)}`); } } } // 全部加载成功后再替换,避免失败时留下不完整的事件表。 handler_map.clear(); for (const [event, callback] of next_handlers) { handler_map.set(event, callback); } } catch (error) { console_print.log(console_print.error(error instanceof Error ? error.message : String(error))); throw error; } } export async function event_handler(socket: Socket, event: string, ...args: any[]): Promise { if (event.startsWith('forward_') && event !== 'forward_bot') { return; } const callback = handler_map.get(event); if (!callback) { console_print.log(console_print.warning(`未找到事件 ${event} 的处理器`)); return; } try { await callback(socket, ...args); } catch (error) { const handler_error = new Error(`事件 ${event} 处理失败: ${error instanceof Error ? error.message : String(error)}`); console_print.log(console_print.error(handler_error.message)); throw handler_error; } }