UNPKG

n1cat-discord-script-manager

Version:

A Discord.js plugin for dynamic script management and execution

216 lines (197 loc) 7 kB
const { SlashCommandBuilder, PermissionFlagsBits } = require("discord.js"); const fs = require("fs"); const path = require("path"); const Logger = require("../utils/logger"); // 用於追蹤函式調用的輔助函數 function getCallerInfo() { const stack = new Error().stack; const callerLine = stack.split("\n")[3]; // 跳過 Error 和 getCallerInfo 的堆疊 const match = callerLine.match(/at\s+(.+?)\s+\((.+?):(\d+):(\d+)\)/); if (match) { const [, functionName, file, line, column] = match; return { function: functionName, file: file.split("/").pop(), // 只取檔案名稱 line, column, }; } return { function: "unknown", file: "unknown", line: "unknown", column: "unknown", }; } // 日誌輸出函數 function log(message, isError = false) { const caller = getCallerInfo(); const scriptManager = global.client?.scriptManager; const debugMode = scriptManager?.options?.debug ?? false; // 如果是錯誤或 debug 模式開啟,則輸出詳細日誌 if (isError || debugMode) { console.log(`[${caller.file}:${caller.line}] ${message}`); } } module.exports = { data: new SlashCommandBuilder() .setName("managescript") .setDescription("管理腳本(啟用/停用)") .setDefaultMemberPermissions(PermissionFlagsBits.Administrator) .addStringOption((option) => option .setName("script") .setDescription("要管理的腳本名稱") .setRequired(true) .setAutocomplete(true) ) .addStringOption((option) => option .setName("action") .setDescription("要執行的動作") .setRequired(true) .addChoices( { name: "啟用", value: "enable" }, { name: "停用", value: "disable" } ) ), async autocomplete(interaction) { const logger = Logger.createContextLogger({ module: "ManageScript", debug: interaction.client.config?.debug || false, }); try { logger.log("開始處理自動完成請求"); const scriptManager = interaction.client.scriptManager; if (!scriptManager) { logger.error("找不到腳本管理器"); return await interaction.respond([]); } const focusedValue = interaction.options.getFocused().toLowerCase(); logger.log(`搜尋腳本: ${focusedValue}`); // 獲取所有腳本並轉換為選項 const scripts = Array.from(scriptManager.scripts.entries()) .map(([name, script]) => ({ name: `${name} (${script.enabled === false ? "已停用" : "啟用中"})`, value: name, })) .filter( (script) => script.value.toLowerCase().includes(focusedValue) || script.name.toLowerCase().includes(focusedValue) ); logger.log(`找到的腳本: ${scripts.map((s) => s.value).join(", ")}`); await interaction.respond(scripts.slice(0, 25)); logger.log("自動完成請求處理完成"); } catch (error) { logger.error(`自動完成時出錯: ${error.message}`, { showStack: true }); console.error("詳細錯誤信息:", { error: error.message, code: error.code, interactionId: interaction.id, interactionState: { replied: interaction.replied, deferred: interaction.deferred, }, timestamp: new Date().toISOString(), }); try { await interaction.respond([]); logger.log("已發送空的自動完成回應"); } catch (e) { logger.error(`回應自動完成時出錯: ${e.message}`, { showStack: true }); console.error("發送自動完成回應時的詳細錯誤:", { error: e.message, code: e.code, interactionId: interaction.id, interactionState: { replied: interaction.replied, deferred: interaction.deferred, }, timestamp: new Date().toISOString(), }); } } }, async execute(interaction) { const logger = Logger.createContextLogger({ module: "ManageScript", debug: interaction.client.config?.debug || false, }); logger.log("開始執行 managescript 命令"); try { // 先延遲回應,避免互動超時 await interaction.deferReply({ ephemeral: true }); logger.log("已延遲回應 managescript 命令"); const scriptManager = interaction.client.scriptManager; if (!scriptManager) { logger.error("找不到腳本管理器"); return await interaction.editReply({ content: "❌ 找不到腳本管理器", }); } const scriptName = interaction.options.getString("script"); const action = interaction.options.getString("action"); logger.log( `準備${action === "enable" ? "啟用" : "停用"}腳本: ${scriptName}` ); const script = scriptManager.scripts.get(scriptName); if (!script) { logger.error(`找不到腳本: ${scriptName}`); return await interaction.editReply({ content: `❌ 找不到腳本:${scriptName}`, }); } // 更新腳本狀態 script.enabled = action === "enable"; scriptManager.scripts.set(scriptName, script); logger.log( `已${action === "enable" ? "啟用" : "停用"}腳本: ${scriptName}` ); await interaction.editReply({ content: `✅ 已${ action === "enable" ? "啟用" : "停用" }腳本:${scriptName}`, }); logger.log("命令執行完成"); } catch (error) { logger.error(`管理腳本時出錯: ${error.message}`, { showStack: true }); console.error("詳細錯誤信息:", { error: error.message, code: error.code, interactionId: interaction.id, interactionState: { replied: interaction.replied, deferred: interaction.deferred, }, timestamp: new Date().toISOString(), }); // 只在還沒有回應時才發送錯誤消息 if (!interaction.replied && !interaction.deferred) { try { await interaction.reply({ content: `❌ 執行命令時發生錯誤:${error.message}`, ephemeral: true, }); logger.log("已發送錯誤回應"); } catch (replyError) { logger.error(`發送錯誤回應時出錯: ${replyError.message}`, { showStack: true, }); console.error("發送錯誤回應時的詳細錯誤:", { error: replyError.message, code: replyError.code, interactionId: interaction.id, interactionState: { replied: interaction.replied, deferred: interaction.deferred, }, timestamp: new Date().toISOString(), }); } } else { logger.log("互動已經被回應,跳過錯誤回應"); } } }, };