Explorar o código

refactor(plugins): 重构插件文件管理模块并优化代码结构

将 `upload.ts` 重构为 `PluginsFile.ts`,优化了插件和日志管理的代码结构,增强了可维护性和可读性。同时修复了部分命令的逻辑问题,确保功能正常运行。
枫林 hai 3 meses
pai
achega
a1abd7962a
Modificáronse 4 ficheiros con 181 adicións e 172 borrados
  1. 2 1
      .gitignore
  2. 3 3
      src/lib/Permission.ts
  3. 4 3
      src/lib/decorators.ts
  4. 172 165
      src/plugins/PluginsFile.ts

+ 2 - 1
.gitignore

@@ -78,4 +78,5 @@ coverage/
 test/
 
 src/plugins/*
-!src/plugins/upload.ts
+!src/plugins/PluginsFile.ts
+!src/plugins/test.ts

+ 3 - 3
src/lib/Permission.ts

@@ -1,10 +1,10 @@
 import { PermissionConfig, saveConfig } from "./config.js";
 import botlogger from "./logger.js";
-export const IsAdmin = function (id:number){return  PermissionConfig.admins.some((admin: string) => admin === String(id)) }
+export const IsAdmin = async function (id:number){return await PermissionConfig.admins.some((admin: string) => admin === String(id)) }
 export async function IsPermission(id: number, plugin: string, command: string): Promise<boolean> {
     try {
-        // 检查用户是否在白名单中
-        if (PermissionConfig.admins.some((admin: string) => admin === String(id))) {
+        // 检查用户是否在管理员
+        if (await IsAdmin(id)) {
             return true;
         }
         // 获取用户权限配置(带默认回退)

+ 4 - 3
src/lib/decorators.ts

@@ -95,11 +95,13 @@ export function plugins(config: PluginConfig): ClassDecorator {
                     const commands = plugin.commands
                         .filter(cmd => !cmd.cmd.endsWith('help'))
                         .map(cmd => {
-                            const fullCmd = `${CMD_PREFIX}${plugin.id} ${cmd.cmd}`;
+                            let fullCmd = `${CMD_PREFIX}${plugin.id} ${cmd.cmd}`;
                             const aliases = cmd.aliases?.map(alias =>
                                 `${CMD_PREFIX}${plugin.id} ${alias}`
                             ) || [];
-
+                            paramMetadata.get(config.id + '.' + cmd.cmd)?.forEach((param: ParamMetadata) => {
+                                param.optional ? fullCmd += ` [${param.name}]` : fullCmd += ` <${param.name}>`;
+                            })
                             return {
                                 name: cmd.cmd,
                                 fullCmd,
@@ -175,7 +177,6 @@ export function plugins(config: PluginConfig): ClassDecorator {
  * @param desc - 命令描述
  * @param config - 命令配置
  */
-//权限
 export function runcod(cmd: string | string[], desc: string, config: CommandConfig = {}, IsTest = false): MethodDecorator {
     return function (target: any, propertyKey: string | symbol, descriptor: PropertyDescriptor) {
         // 延迟执行命令注册

+ 172 - 165
src/plugins/upload.ts → src/plugins/PluginsFile.ts

@@ -1,166 +1,173 @@
-import { param, plugins, runcod } from '../lib/decorators.js';
-import path from 'path';
-import 'reflect-metadata';
-import { fileURLToPath } from 'node:url';
-import { GroupMessage, PrivateFriendMessage, PrivateGroupMessage } from 'node-napcat-ts';
-import botlogger from '../lib/logger.js';
-import fs from 'fs/promises';
-import { qqBot } from '../app.js';
-import { ParamType } from '../interface/plugin.js';
-
-@plugins({
-    id: "downloadPlugins", //插件ID,必须唯一,不能重复
-    name: "下载插件", //插件名称,用于显示在菜单中
-    version: "1.0.0", //插件版本号,用于显示在菜单中
-    describe: "在服务器下载一个插件", //插件描述,用于显示在菜单中
-    author: "枫叶秋林",//插件作者,用于显示在菜单中
-    help: { //插件帮助信息,用于显示在菜单中
-        enabled: true, //是否启用帮助信息
-        description: "显示帮助信息" //帮助信息描述
-    }
-})
-export class downloadPlugins {
-    @runcod(["download", "下载插件"], "下载插件")//命令装饰器,用于注册命令
-    async param(
-        @param("插件名称", ParamType.String) pluName: string,
-        context: PrivateFriendMessage | PrivateGroupMessage | GroupMessage
-    ): Promise<any> {
-        // pluName += ".ts"
-        const __dirname = path.dirname(fileURLToPath(import.meta.url));
-        // 查找插件目录下的文件
-        const pluginsDir = path.join(__dirname, '..', 'plugins');
-        try {
-            const files = await fs.readdir(pluginsDir);
-            const foundFiles = files.filter(file =>
-                (file.endsWith('.ts') || file.endsWith('.js')) &&
-                file !== 'index.ts'
-            );
-
-            // 在服务器日志中输出找到的文件列表
-            botlogger.info(`找到插件文件:${foundFiles.join(', ')}`);
-
-            // 根据文件名查找具体插件
-            const targetFile = foundFiles.find((file: string) =>
-                path.parse(file).name.toLowerCase() === pluName.toLowerCase()
-            );
-
-            if (!targetFile) {
-                return `未找到名为 ${pluName} 的插件`;
-            }
-
-            // 返回文件完整路径
-            const fullPath = path.join(pluginsDir, targetFile);
-            //.toString('base64'
-
-            const file = Buffer.from(await fs.readFile(fullPath, { encoding: "utf-8" })).toString('base64')
-            const isGroupMessage = context.message_type === 'group';
-            if (isGroupMessage && context.group_id) {
-                await qqBot.upload_group_file({
-                    group_id: Number(context.group_id),
-                    file: 'data:file;base64,' + file,
-                    name: pluName
-                })
-
-            } else {
-                await qqBot.upload_private_file({
-                    user_id: Number(context.sender.user_id),
-                    file: 'data:file;base64,' + file,
-                    name: pluName
-                })
-            }
-
-            return '上传成功';
-        } catch (error) {
-            botlogger.error('文件查找失败:', error);
-            return '插件查找服务暂不可用';
-        }
-    }
-    @runcod(["plugins", "插件列表"], "查看插件文件")//命令装饰器,用于注册命令
-    async plugins(
-        context: PrivateFriendMessage | PrivateGroupMessage | GroupMessage
-    ): Promise<any> {
-        // pluName += ".ts"
-        const __dirname = path.dirname(fileURLToPath(import.meta.url));
-        // 查找插件目录下的文件
-        const pluginsDir = path.join(__dirname, '..', 'plugins');
-        try {
-            const files = await fs.readdir(pluginsDir);
-            const foundFiles = files.filter(file =>
-                (file.endsWith('.ts') || file.endsWith('.js')) &&
-                file !== 'index.ts'
-            );
-            return `找到日志文件:${foundFiles.join(', ')}`;
-        } catch (error) {
-            botlogger.error('文件查找失败:', error);
-            return '插件查找服务暂不可用';
-        }
-    }
-    @runcod(["logs", "日志"], "获取日志")
-    async getloglist() {
-        // pluName += ".ts"
-        const __dirname = path.dirname(fileURLToPath(import.meta.url));
-        // 查找插件目录下的文件
-        const pluginsDir = path.join(__dirname, '..', '..','logs');
-        try {
-            const files = await fs.readdir(pluginsDir);
-            const foundFiles = files.filter(file =>
-                (file.endsWith('.log'))
-            );
-            return `找到插件文件:${foundFiles.join(', ')}`;
-        } catch (error) {
-            botlogger.error('文件查找失败:', error);
-            return '插件查找服务暂不可用';
-        }
-    }
-    @runcod(["downloadlog", "getlog"], "下载日志")//命令装饰器,用于注册命令
-    async getlogs(
-        @param("日志名称", ParamType.String) pluName: string,
-        context: PrivateFriendMessage | PrivateGroupMessage | GroupMessage
-    ): Promise<any> {
-        // pluName += ".ts"
-        const __dirname = path.dirname(fileURLToPath(import.meta.url));
-        // 查找插件目录下的文件
-        const pluginsDir = path.join(__dirname, '..', '..','logs');
-        try {
-            const files = await fs.readdir(pluginsDir);
-            const foundFiles = files.filter(file =>
-                (file.endsWith('.log'))
-            );
-
-            // 根据文件名查找具体插件
-            const targetFile = foundFiles.find((file: string) =>
-                path.parse(file).name.toLowerCase() === pluName.toLowerCase()
-            );
-
-            if (!targetFile) {
-                return `未找到名为 ${pluName} 的日志`;
-            }
-
-            // 返回文件完整路径
-            const fullPath = path.join(pluginsDir, targetFile);
-            //.toString('base64'
-
-            const file = Buffer.from(await fs.readFile(fullPath, { encoding: "utf-8" })).toString('base64')
-            const isGroupMessage = context.message_type === 'group';
-            if (isGroupMessage && context.group_id) {
-                await qqBot.upload_group_file({
-                    group_id: Number(context.group_id),
-                    file: 'data:file;base64,' + file,
-                    name: pluName
-                })
-
-            } else {
-                await qqBot.upload_private_file({
-                    user_id: Number(context.sender.user_id),
-                    file: 'data:file;base64,' + file,
-                    name: pluName
-                })
-            }
-
-            return '上传成功';
-        } catch (error) {
-            botlogger.error('文件查找失败:', error);
-            return '插件查找服务暂不可用';
-        }
-    }
+import { param, plugins, runcod } from '../lib/decorators.js';
+import path from 'path';
+import 'reflect-metadata';
+import { fileURLToPath } from 'node:url';
+import { GroupMessage, PrivateFriendMessage, PrivateGroupMessage } from 'node-napcat-ts';
+import botlogger from '../lib/logger.js';
+import fs from 'fs/promises';
+import { qqBot } from '../app.js';
+import { ParamType } from '../interface/plugin.js';
+
+@plugins({
+    id: "PluginsFile", //插件ID,必须类名一致
+    name: "插件文件管理", //插件名称,用于显示在菜单中
+    version: "1.0.1", //插件版本号,用于显示在菜单中
+    describe: "可以查看服务器的插件/日志,可以上传插件到群内", 
+    author: "枫叶秋林",//插件作者,用于显示在菜单中
+    help: { //插件帮助信息,用于显示在菜单中
+        enabled: true, //是否启用帮助信息
+        description: "显示帮助信息" //帮助信息描述
+    }
+})
+export class PluginsFile {
+    @runcod(["download", "下载插件"], "下载插件")
+    async download(
+        @param("插件名称", ParamType.String) pluName: string,
+        context: PrivateFriendMessage | PrivateGroupMessage | GroupMessage
+    ): Promise<any> {
+        const __dirname = path.dirname(fileURLToPath(import.meta.url));
+        // 查找插件目录下的文件
+        const pluginsDir = path.join(__dirname, '..', 'plugins');
+        try {
+            const files = await fs.readdir(pluginsDir);
+            const foundFiles = files.filter(file =>
+                (file.endsWith('.ts') || file.endsWith('.js')) &&
+                file !== 'index.ts'
+            );
+            // 在服务器日志中输出找到的文件列表
+            botlogger.info(`找到插件文件:${foundFiles.join(', ')}`);
+
+            // 根据文件名查找具体插件
+            const targetFile = foundFiles.find((file: string) =>
+                path.parse(file).name.toLowerCase() === pluName.toLowerCase()
+            );
+
+            if (!targetFile) {
+                return `未找到名为 ${pluName} 的插件`;
+            }
+
+            // 返回文件完整路径
+            const fullPath = path.join(pluginsDir, targetFile);
+            //.toString('base64'
+
+            const file = Buffer.from(await fs.readFile(fullPath, { encoding: "utf-8" })).toString('base64')
+            const isGroupMessage = context.message_type === 'group';
+            if (isGroupMessage && context.group_id) {
+                await qqBot.upload_group_file({
+                    group_id: Number(context.group_id),
+                    file: 'data:file;base64,' + file,
+                    name: pluName + '.ts'
+                })
+
+            } else {
+                await qqBot.upload_private_file({
+                    user_id: Number(context.sender.user_id),
+                    file: 'data:file;base64,' + file,
+                    name: pluName + '.ts'
+                })
+            }
+
+            return '上传成功';
+        } catch (error) {
+            botlogger.error('文件查找失败:', error);
+            return '插件查找服务暂不可用';
+        }
+    }
+
+    @runcod(["plugins", "插件列表"], "查看插件文件")
+    async plugins(
+        context: PrivateFriendMessage | PrivateGroupMessage | GroupMessage
+    ): Promise<any> {
+        // pluName += ".ts"
+        const __dirname = path.dirname(fileURLToPath(import.meta.url));
+        // 查找插件目录下的文件
+        const pluginsDir = path.join(__dirname, '..', 'plugins');
+        try {
+            const files = await fs.readdir(pluginsDir);
+            const foundFiles = files.filter(file =>
+                (file.endsWith('.ts') || file.endsWith('.js')) &&
+                file !== 'index.ts'
+            );
+            foundFiles.forEach((file, index) => {
+                foundFiles[index] = path.parse(file).name;
+            })
+            return `找到插件文件:${foundFiles.join(', ')}`;
+        } catch (error) {
+            botlogger.error('文件查找失败:', error);
+            return '插件查找服务暂不可用';
+        }
+    }
+
+    @runcod(["logs", "日志"], "获取日志")
+    async getloglist() {
+        // pluName += ".ts"
+        const __dirname = path.dirname(fileURLToPath(import.meta.url));
+        // 查找插件目录下的文件
+        const pluginsDir = path.join(__dirname, '..', '..','logs');
+        try {
+            const files = await fs.readdir(pluginsDir);
+            const foundFiles = files.filter(file =>
+                (file.endsWith('.log'))
+            );
+            foundFiles.forEach((file, index) => {
+                foundFiles[index] = path.parse(file).name;
+            })
+            return `找到插件文件:${foundFiles.join(', ')}`;
+        } catch (error) {
+            botlogger.error('文件查找失败:', error);
+            return '插件查找服务暂不可用';
+        }
+    }
+
+    @runcod(["downloadlog", "getlog"], "下载日志")
+    async getlogs(
+        @param("日志名称", ParamType.String) pluName: string,
+        context: PrivateFriendMessage | PrivateGroupMessage | GroupMessage
+    ): Promise<any> {
+        // pluName += ".ts"
+        const __dirname = path.dirname(fileURLToPath(import.meta.url));
+        // 查找插件目录下的文件
+        const pluginsDir = path.join(__dirname, '..', '..','logs');
+        try {
+            const files = await fs.readdir(pluginsDir);
+            const foundFiles = files.filter(file =>
+                (file.endsWith('.log'))
+            );
+
+            // 根据文件名查找具体插件
+            const targetFile = foundFiles.find((file: string) =>
+                path.parse(file).name.toLowerCase() === pluName.toLowerCase()
+            );
+
+            if (!targetFile) {
+                return `未找到名为 ${pluName} 的日志`;
+            }
+
+            // 返回文件完整路径
+            const fullPath = path.join(pluginsDir, targetFile);
+            //.toString('base64'
+
+            const file = Buffer.from(await fs.readFile(fullPath, { encoding: "utf-8" })).toString('base64')
+            const isGroupMessage = context.message_type === 'group';
+            if (isGroupMessage && context.group_id) {
+                await qqBot.upload_group_file({
+                    group_id: Number(context.group_id),
+                    file: 'data:file;base64,' + file,
+                    name: pluName+'.log'
+                })
+
+            } else {
+                await qqBot.upload_private_file({
+                    user_id: Number(context.sender.user_id),
+                    file: 'data:file;base64,' + file,
+                    name: pluName+'.log'
+                })
+            }
+
+            return '上传成功';
+        } catch (error) {
+            botlogger.error('文件查找失败:', error);
+            return '插件查找服务暂不可用';
+        }
+    }
 }