xincbot
Version:
A flexible QQ bot framework based on NapCat and node-napcat-ts
243 lines • 8.53 kB
JavaScript
;
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