UNPKG

xincbot

Version:

A flexible QQ bot framework based on NapCat and node-napcat-ts

243 lines 8.53 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.PluginManager = void 0; const path_1 = __importDefault(require("path")); const fs_1 = __importDefault(require("fs")); const logger_1 = require("./logger"); const config_1 = require("./config"); // 导入内置的 cmd 插件 const cmd_1 = __importDefault(require("../plugins/cmd")); class PluginManager { plugins = new Map(); pluginsDir; configDir; client; context; builtinPlugins = new Map(); constructor(client, dataDir, configDir) { this.client = client; this.pluginsDir = path_1.default.join(process.cwd(), 'plugins'); this.configDir = configDir; // 创建插件目录(如果不存在) if (!fs_1.default.existsSync(this.pluginsDir)) { fs_1.default.mkdirSync(this.pluginsDir, { recursive: true }); } // 创建插件上下文 this.context = this.createPluginContext(); // 注册内置插件 this.registerBuiltinPlugins(); } createPluginContext() { // 创建插件上下文,包含各种API方法 return { wsSend: (action, params) => this.client.send(action, params), // 添加其他上下文方法... handle: (event, handler) => { // 处理事件注册 this.client.on(event, handler); }, // 其他上下文方法... }; // 临时使用 any 类型,实际应该定义完整的类型 } /** * 注册内置插件 */ registerBuiltinPlugins() { // 注册 cmd 插件 this.builtinPlugins.set('cmd', cmd_1.default); logger_1.logger.info('内置插件已注册: cmd'); } /** * 加载所有启用的插件 */ async loadAllPlugins() { // 首先加载内置插件 await this.loadBuiltinPlugins(); // 然后加载配置中的插件 const config = config_1.configManager.getConfig(); await this.loadPlugins(config.plugins); } /** * 加载内置插件 */ async loadBuiltinPlugins() { logger_1.logger.info('正在加载内置插件...'); for (const [name, plugin] of this.builtinPlugins.entries()) { try { if (plugin && typeof plugin.setup === 'function') { // 初始化插件 plugin.setup(this.context); // 存储插件实例 this.plugins.set(name, plugin); logger_1.logger.info(`内置插件已加载: ${plugin.name} v${plugin.version || '1.0.0'}`); } else { logger_1.logger.error(`无效的内置插件结构: ${name}`); } } catch (error) { logger_1.logger.error(`加载内置插件 ${name} 失败: ${error}`); } } } /** * 加载指定的插件 * @param pluginNames 插件名称数组 */ async loadPlugins(pluginNames) { // 不再需要确保 cmd 插件被加载,因为它是内置的 for (const name of pluginNames) { // 跳过内置插件,因为它们已经加载了 if (this.builtinPlugins.has(name)) { continue; } try { await this.loadPlugin(name); } catch (error) { logger_1.logger.error(`Failed to load plugin ${name}: ${error}`); } } } /** * 加载单个插件 * @param pluginName 插件名称 */ async loadPlugin(pluginName) { try { // 检查是否是内置插件 if (this.builtinPlugins.has(pluginName)) { logger_1.logger.info(`${pluginName} is a built-in plugin, skipping external loading`); return; } // 检查插件是否已加载 if (this.plugins.has(pluginName)) { logger_1.logger.warn(`Plugin ${pluginName} is already loaded`); return; } // 构建插件路径 const pluginPath = path_1.default.join(this.pluginsDir, pluginName); // 检查插件目录是否存在 if (!fs_1.default.existsSync(pluginPath)) { throw new Error(`Plugin directory not found: ${pluginPath}`); } // 加载插件 const indexPath = path_1.default.join(pluginPath, 'index.js'); if (!fs_1.default.existsSync(indexPath)) { throw new Error(`Plugin index file not found: ${indexPath}`); } // 清除缓存以支持热重载 delete require.cache[require.resolve(indexPath)]; // 导入插件 const plugin = require(indexPath).default; // 验证插件结构 if (!plugin || !plugin.name || typeof plugin.setup !== 'function') { throw new Error(`Invalid plugin structure for ${pluginName}`); } // 使用类型断言确保 TypeScript 知道 setup 存在 plugin.setup(this.context); // 存储插件实例 this.plugins.set(pluginName, plugin); logger_1.logger.info(`Plugin loaded: ${plugin.name} v${plugin.version || '1.0.0'}`); } catch (error) { logger_1.logger.error(`Failed to load plugin ${pluginName}: ${error}`); throw error; } } /** * 卸载插件 * @param pluginName 插件名称 */ unloadPlugin(pluginName) { // 检查是否是内置插件 if (this.builtinPlugins.has(pluginName)) { logger_1.logger.warn(`Cannot unload built-in plugin: ${pluginName}`); return false; } // 检查插件是否已加载 if (!this.plugins.has(pluginName)) { logger_1.logger.warn(`Plugin ${pluginName} is not loaded`); return false; } // 从插件列表中移除 this.plugins.delete(pluginName); logger_1.logger.info(`Plugin unloaded: ${pluginName}`); return true; } /** * 重新加载插件 * @param pluginName 插件名称 */ async reloadPlugin(pluginName) { // 检查是否是内置插件 if (this.builtinPlugins.has(pluginName)) { logger_1.logger.warn(`Cannot reload built-in plugin: ${pluginName}`); return false; } this.unloadPlugin(pluginName); try { await this.loadPlugin(pluginName); return true; } catch (error) { logger_1.logger.error(`Failed to reload plugin ${pluginName}: ${error}`); return false; } } /** * 禁用插件 * @param pluginName 插件名称 */ disablePlugin(pluginName) { // 检查是否是内置插件 if (this.builtinPlugins.has(pluginName)) { logger_1.logger.warn(`Cannot disable built-in plugin: ${pluginName}`); return false; } // 卸载插件 const unloaded = this.unloadPlugin(pluginName); // 从配置中移除 if (unloaded) { config_1.configManager.updatePlugins('remove', pluginName); } return unloaded; } /** * 启用插件 * @param pluginName 插件名称 */ async enablePlugin(pluginName) { // 检查是否是内置插件 if (this.builtinPlugins.has(pluginName)) { logger_1.logger.info(`${pluginName} is a built-in plugin, already enabled`); return true; } try { await this.loadPlugin(pluginName); config_1.configManager.updatePlugins('add', pluginName); return true; } catch (error) { logger_1.logger.error(`Failed to enable plugin ${pluginName}: ${error}`); return false; } } /** * 获取所有已加载的插件 */ getLoadedPlugins() { return Array.from(this.plugins.values()); } /** * 获取所有内置插件 */ getBuiltinPlugins() { return Array.from(this.builtinPlugins.values()); } } exports.PluginManager = PluginManager; //# sourceMappingURL=plugin-manager.js.map