chore: initial commit
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
import type {Socket} from 'socket.io-client';
|
||||
import {bot_config_apply_handler} from '../../utils/bot_config_apply_handler.ts';
|
||||
|
||||
export async function handler(socket: Socket, data: unknown, callback: unknown) {
|
||||
await bot_config_apply_handler(socket, data, callback);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import type {Socket} from "socket.io-client";
|
||||
import {ensure_forward} from "../../bot/forward/manager.ts";
|
||||
|
||||
export async function handler(socket: Socket, data: unknown, callback: unknown) {
|
||||
if (typeof callback !== "function") return;
|
||||
const response = await ensure_forward(socket, data);
|
||||
try { callback(response); } catch { /* Main may have disconnected while the request was pending. */ }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import type {Socket} from 'socket.io-client';
|
||||
import {plugin_event_handler} from '../../utils/plugin_event_handler.ts';
|
||||
|
||||
export async function handler(socket: Socket, data: unknown, callback: unknown) {
|
||||
await plugin_event_handler('inject', socket, data, callback);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import type {Socket} from "socket.io-client";
|
||||
import {bot_config} from "../../types/bot/instance/bot_runtime.ts";
|
||||
import {validate_code_map} from "../../utils/validate_code_map.ts";
|
||||
import {start_bot_context} from "../../bot/instance";
|
||||
|
||||
export async function handler(socket: Socket, data: unknown, callback: unknown) {
|
||||
if (typeof callback !== "function") {
|
||||
socket.emit("error", {
|
||||
error: validate_code_map.web.method_not_allowed
|
||||
});
|
||||
return;
|
||||
}
|
||||
let result_code: number = validate_code_map.web.invalid_parameter;
|
||||
try {
|
||||
if (data && typeof data === "object" && !Array.isArray(data)
|
||||
&& "node_id" in data && typeof data.node_id === "number"
|
||||
&& Number.isSafeInteger(data.node_id) && data.node_id > 0) {
|
||||
result_code = await start_bot_context(socket, data as bot_config & {node_id: number}, data.node_id);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Bot startup request failed", error);
|
||||
result_code = validate_code_map.bot_context.error;
|
||||
}
|
||||
callback({
|
||||
status: result_code === validate_code_map.bot_context.instance_connected
|
||||
|| result_code === validate_code_map.bot_context.instance_connecting
|
||||
|| result_code === validate_code_map.bot_context.context_created ? "success" : "error",
|
||||
data: result_code
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import type {Socket} from "socket.io-client";
|
||||
import {validate_code_map} from "../../utils/validate_code_map.ts";
|
||||
import {stop_bot_context} from "../../bot/instance";
|
||||
|
||||
export async function handler(socket: Socket, data: unknown, callback: unknown) {
|
||||
if (typeof callback !== "function") {
|
||||
socket.emit("error", {
|
||||
error: validate_code_map.web.method_not_allowed
|
||||
});
|
||||
return;
|
||||
}
|
||||
let result_code: number = validate_code_map.web.invalid_parameter;
|
||||
try {
|
||||
if (data && typeof data === "object" && !Array.isArray(data)
|
||||
&& "bot_id" in data && typeof data.bot_id === "number"
|
||||
&& Number.isSafeInteger(data.bot_id) && data.bot_id > 0) {
|
||||
result_code = await stop_bot_context(data.bot_id);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Bot stop request failed", error);
|
||||
result_code = validate_code_map.bot_context.error;
|
||||
}
|
||||
callback({
|
||||
status: result_code === validate_code_map.bot_context.instance_end_by_user ? "success" : "error",
|
||||
data: result_code
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import type {Socket} from 'socket.io-client';
|
||||
import {plugin_event_handler} from '../../utils/plugin_event_handler.ts';
|
||||
|
||||
export async function handler(socket: Socket, data: unknown, callback: unknown) {
|
||||
await plugin_event_handler('uninject', socket, data, callback);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import type {Socket} from 'socket.io-client';
|
||||
import {plugin_event_handler} from '../../utils/plugin_event_handler.ts';
|
||||
|
||||
export async function handler(socket: Socket, data: unknown, callback: unknown) {
|
||||
await plugin_event_handler('update_config', socket, data, callback);
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
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<unknown>;
|
||||
const handler_map = new Map<string, handler>();
|
||||
|
||||
export async function init_event_handler_list(): Promise<void> {
|
||||
try {
|
||||
const next_handlers = new Map<string, handler>();
|
||||
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<void> {
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user