From fb62c03c024c35dbeab01860d5fe6f76cada8f0a Mon Sep 17 00:00:00 2001 From: SMGoro <72185434+SMGoro@users.noreply.github.com> Date: Tue, 13 Jan 2026 04:21:35 +0800 Subject: [PATCH 001/256] feat: implement soft shutdown for non-Docker instances and enhance exit handling --- daemon/src/app.ts | 42 +++++++++++++++------ daemon/src/service/system_instance.ts | 53 +++++++++++++++++++++++++++ languages/en_US.json | 5 +++ languages/zh_CN.json | 7 ++++ 4 files changed, 96 insertions(+), 11 deletions(-) diff --git a/daemon/src/app.ts b/daemon/src/app.ts index bacb6270a..1c88d1d9c 100755 --- a/daemon/src/app.ts +++ b/daemon/src/app.ts @@ -1,8 +1,8 @@ import fs from "fs-extra"; -import path from "path"; import http from "http"; import https from "https"; import { removeTrail } from "mcsmanager-common"; +import path from "path"; import { Server, Socket } from "socket.io"; import { GOLANG_ZIP_PATH, LOCAL_PRESET_LANG_PATH, PTY_PATH } from "./const"; import { globalConfiguration } from "./entity/config"; @@ -146,7 +146,7 @@ process.on("unhandledRejection", (reason, p) => { logger.info("----------------------------"); logger.info($t("TXT_CODE_app.started")); logger.info($t("TXT_CODE_app.doc")); -let appHost = $t("TXT_CODE_app.host", { port: config.port }) +let appHost = $t("TXT_CODE_app.host", { port: config.port }); if (config.ssl) appHost = appHost.replace("http", "https"); logger.info(appHost); logger.info($t("TXT_CODE_app.configPathTip", { path: "" })); @@ -157,18 +157,38 @@ logger.info("----------------------------"); console.log(""); let isExiting = false; +let isSoftExit = false; async function listenExitSig(signal: string, isForce = true) { - if (isExiting) { + if (isExiting && !isForce) { logger.warn($t("TXT_CODE_6f862823")); return; } + try { - logger.warn($t("TXT_CODE_4ffdc91d", { signal })); - isExiting = true; - await InstanceSubsystem.exit(isForce); - await uploadManager.exit(); - logger.info($t("TXT_CODE_dff680b7")); - process.exit(0); + if (isExiting) { + // User interrupted the process, now force exit + logger.warn($t("TXT_CODE_4ffdc91d", { signal })); + logger.info($t("TXT_CODE_app.forcedShutdown")); + await InstanceSubsystem.exit(true); // Force close all instances + await uploadManager.exit(); + logger.info($t("TXT_CODE_dff680b7")); + process.exit(0); + } else { + logger.warn($t("TXT_CODE_4ffdc91d", { signal })); + isExiting = true; + + if (isForce) { + // If force signal is received from the start, just kill everything + await InstanceSubsystem.exit(true); + } else { + // Soft shutdown: skip Docker instances, soft close general instances + await InstanceSubsystem.softExit(); + } + + await uploadManager.exit(); + logger.info($t("TXT_CODE_dff680b7")); + process.exit(0); + } } catch (err) { logger.error(err); process.exit(-1); @@ -178,11 +198,11 @@ async function listenExitSig(signal: string, isForce = true) { // Listen for close process signals ["SIGTERM", "SIGINT", "SIGQUIT"].forEach(function (sig) { process.on(sig, async () => { - await listenExitSig(sig); + await listenExitSig(sig, false); // Use soft exit by default }); }); process.stdin.on("data", (v) => { const command = v.toString().replace("\n", "").replace("\r", "").trim().toLowerCase(); - if (command === "exit") listenExitSig("exit"); + if (command === "exit") listenExitSig("exit", false); // Use soft exit }); diff --git a/daemon/src/service/system_instance.ts b/daemon/src/service/system_instance.ts index c9df39dd6..e2284d761 100755 --- a/daemon/src/service/system_instance.ts +++ b/daemon/src/service/system_instance.ts @@ -314,6 +314,59 @@ class InstanceSubsystem extends EventEmitter { }); } + // Soft exit: don't close Docker instances, soft close general instances only + softExit() { + const promises: Promise[] = []; + for (const iterator of this.instances) { + const instance = iterator[1]; + if (instance.status() !== Instance.STATUS_STOP) { + // Skip Docker instances during soft exit + if (instance.config.processType === "docker") { + logger.info( + `Skipping Docker instance ${instance.config.nickname} (${instance.instanceUuid}) during soft shutdown...` + ); + continue; + } else { + // Soft close general instances (don't force kill) + promises.push(this.exitInstance(instance, false)); + } + } + } + Promise.all(promises); + + return new Promise((resolve) => { + let checkCount = 0; + const checkTask = setInterval(() => { + let count = 0; + checkCount++; + for (const [_, instance] of this.instances) { + if ( + instance.config.processType !== "docker" && + instance.status() !== Instance.STATUS_STOP + ) { + count++; + if (checkCount > 10) { + logger.info( + $t("TXT_CODE_eadac3c2", { + instance: instance.config.nickname + }) + ); + // If it takes too long, force close non-Docker instances + this.exitInstance(instance, true); + } + } + } + if (count === 0) { + logger.info($t("TXT_CODE_187bb567")); + clearInterval(checkTask); + resolve(); + } else { + logger.info($t("TXT_CODE_6f23ce93", { count })); + } + }, 1000); + }); + } + getInstances() { let newArr = new Array(); this.instances.forEach((instance) => { diff --git a/languages/en_US.json b/languages/en_US.json index 88bb681b2..fd9897fdf 100644 --- a/languages/en_US.json +++ b/languages/en_US.json @@ -1842,6 +1842,11 @@ "TXT_CODE_app.developInfo": "Unable to start, this project is intended for MCSManager developers and cannot be run by regular users.\nPlease visit https://mcsmanager.com/ for the latest installation instructions.\nIf you intend to run in developer mode, create directory 'public' and 'src/public' along with frontend static files before running again.", "TXT_CODE_app.doc": "Reference Documentation: https://docs.mcsmanager.com/", "TXT_CODE_app.exitTip": "You can use the Ctrl+C shortcut to close the program", + "TXT_CODE_app.softShutdownStart": "Received %s, starting soft shutdown: Docker instances will be left running; stopping non-Docker instances and waiting for them to stop.", + "TXT_CODE_app.softShutdownComplete": "Soft shutdown complete: all non-Docker instances have stopped.", + "TXT_CODE_app.escalationStart": "Second interrupt received; escalating to forced shutdown for remaining non-Docker instances...", + "TXT_CODE_app.escalationComplete": "Forced non-Docker shutdown complete; proceeding to exit.", + "TXT_CODE_app.forceShutdownAllStart": "Force shutdown requested: terminating all instances (including Docker).", "TXT_CODE_app.host": "Access URL: http://localhost:{{port}}", "TXT_CODE_app.httpSetupError": "HTTP/Socket service startup error, possibly due to port occupation, insufficient permissions, or unavailable network device.", "TXT_CODE_app.instanceLoad": "All {{n}} instances have been loaded.", diff --git a/languages/zh_CN.json b/languages/zh_CN.json index 41d90f5d4..5f9dd3e70 100644 --- a/languages/zh_CN.json +++ b/languages/zh_CN.json @@ -1815,9 +1815,16 @@ "TXT_CODE_app.developInfo": "无法启动,此项目是 MCSManager 开发人员所用项目,普通用户不可直接运行。\n请前往 https://mcsmanager.com/ 了解最新的安装方式。\n如果您要以开发模式运行,请创建 public,src/public 目录并放置前端静态文件再重新运行。", "TXT_CODE_app.doc": "参考文档:https://docs.mcsmanager.com/", "TXT_CODE_app.exitTip": "你可以使用 Ctrl+C 快捷键即可关闭程序", + "TXT_CODE_app.softShutdownStart": "收到 %s,开始软关闭:Docker 实例将保持运行;正在停止其余非 Docker 实例并等待其停止。", + "TXT_CODE_app.softShutdownComplete": "软关闭完成:所有非 Docker 实例已停止。", + "TXT_CODE_app.escalationStart": "再次接收到中断,升级为对剩余非 Docker 实例的强制关闭...", + "TXT_CODE_app.escalationComplete": "强制非 Docker 关闭完成;继续退出。", + "TXT_CODE_app.forceShutdownAllStart": "请求强制关闭:正在终止所有实例(包含 Docker)。", "TXT_CODE_app.host": "访问地址: http://localhost:{{port}}", "TXT_CODE_app.httpSetupError": "HTTP/Socket 服务启动错误,可能是端口被占用,权限不足或网卡设备不可用。", "TXT_CODE_app.instanceLoad": "所有应用实例已加载,总计 {{n}} 个", + "TXT_CODE_system_instance.skippingDocker": "软关闭期间跳过 Docker 实例 %s (%s)...", + "TXT_CODE_system_instance.forcingNonDocker": "由于用户升级或超时,正在强制停止非 Docker 实例 %s (%s)。", "TXT_CODE_app.instanceLoadError": "读取本地实例文件失败:", "TXT_CODE_app.panelStarted": "控制面板端已启动", "TXT_CODE_app.password": "访问密钥:{{key}}", From d842e2b6a753dbf4e4daa4e1d07361beeaf52eef Mon Sep 17 00:00:00 2001 From: SMGoro <72185434+SMGoro@users.noreply.github.com> Date: Tue, 13 Jan 2026 08:10:18 +0800 Subject: [PATCH 002/256] feat: implement soft exit functionality for non-Docker instances --- daemon/src/app.ts | 42 +++++++++++++++------ daemon/src/service/system_instance.ts | 53 +++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 11 deletions(-) diff --git a/daemon/src/app.ts b/daemon/src/app.ts index bacb6270a..1c88d1d9c 100755 --- a/daemon/src/app.ts +++ b/daemon/src/app.ts @@ -1,8 +1,8 @@ import fs from "fs-extra"; -import path from "path"; import http from "http"; import https from "https"; import { removeTrail } from "mcsmanager-common"; +import path from "path"; import { Server, Socket } from "socket.io"; import { GOLANG_ZIP_PATH, LOCAL_PRESET_LANG_PATH, PTY_PATH } from "./const"; import { globalConfiguration } from "./entity/config"; @@ -146,7 +146,7 @@ process.on("unhandledRejection", (reason, p) => { logger.info("----------------------------"); logger.info($t("TXT_CODE_app.started")); logger.info($t("TXT_CODE_app.doc")); -let appHost = $t("TXT_CODE_app.host", { port: config.port }) +let appHost = $t("TXT_CODE_app.host", { port: config.port }); if (config.ssl) appHost = appHost.replace("http", "https"); logger.info(appHost); logger.info($t("TXT_CODE_app.configPathTip", { path: "" })); @@ -157,18 +157,38 @@ logger.info("----------------------------"); console.log(""); let isExiting = false; +let isSoftExit = false; async function listenExitSig(signal: string, isForce = true) { - if (isExiting) { + if (isExiting && !isForce) { logger.warn($t("TXT_CODE_6f862823")); return; } + try { - logger.warn($t("TXT_CODE_4ffdc91d", { signal })); - isExiting = true; - await InstanceSubsystem.exit(isForce); - await uploadManager.exit(); - logger.info($t("TXT_CODE_dff680b7")); - process.exit(0); + if (isExiting) { + // User interrupted the process, now force exit + logger.warn($t("TXT_CODE_4ffdc91d", { signal })); + logger.info($t("TXT_CODE_app.forcedShutdown")); + await InstanceSubsystem.exit(true); // Force close all instances + await uploadManager.exit(); + logger.info($t("TXT_CODE_dff680b7")); + process.exit(0); + } else { + logger.warn($t("TXT_CODE_4ffdc91d", { signal })); + isExiting = true; + + if (isForce) { + // If force signal is received from the start, just kill everything + await InstanceSubsystem.exit(true); + } else { + // Soft shutdown: skip Docker instances, soft close general instances + await InstanceSubsystem.softExit(); + } + + await uploadManager.exit(); + logger.info($t("TXT_CODE_dff680b7")); + process.exit(0); + } } catch (err) { logger.error(err); process.exit(-1); @@ -178,11 +198,11 @@ async function listenExitSig(signal: string, isForce = true) { // Listen for close process signals ["SIGTERM", "SIGINT", "SIGQUIT"].forEach(function (sig) { process.on(sig, async () => { - await listenExitSig(sig); + await listenExitSig(sig, false); // Use soft exit by default }); }); process.stdin.on("data", (v) => { const command = v.toString().replace("\n", "").replace("\r", "").trim().toLowerCase(); - if (command === "exit") listenExitSig("exit"); + if (command === "exit") listenExitSig("exit", false); // Use soft exit }); diff --git a/daemon/src/service/system_instance.ts b/daemon/src/service/system_instance.ts index c9df39dd6..e2284d761 100755 --- a/daemon/src/service/system_instance.ts +++ b/daemon/src/service/system_instance.ts @@ -314,6 +314,59 @@ class InstanceSubsystem extends EventEmitter { }); } + // Soft exit: don't close Docker instances, soft close general instances only + softExit() { + const promises: Promise[] = []; + for (const iterator of this.instances) { + const instance = iterator[1]; + if (instance.status() !== Instance.STATUS_STOP) { + // Skip Docker instances during soft exit + if (instance.config.processType === "docker") { + logger.info( + `Skipping Docker instance ${instance.config.nickname} (${instance.instanceUuid}) during soft shutdown...` + ); + continue; + } else { + // Soft close general instances (don't force kill) + promises.push(this.exitInstance(instance, false)); + } + } + } + Promise.all(promises); + + return new Promise((resolve) => { + let checkCount = 0; + const checkTask = setInterval(() => { + let count = 0; + checkCount++; + for (const [_, instance] of this.instances) { + if ( + instance.config.processType !== "docker" && + instance.status() !== Instance.STATUS_STOP + ) { + count++; + if (checkCount > 10) { + logger.info( + $t("TXT_CODE_eadac3c2", { + instance: instance.config.nickname + }) + ); + // If it takes too long, force close non-Docker instances + this.exitInstance(instance, true); + } + } + } + if (count === 0) { + logger.info($t("TXT_CODE_187bb567")); + clearInterval(checkTask); + resolve(); + } else { + logger.info($t("TXT_CODE_6f23ce93", { count })); + } + }, 1000); + }); + } + getInstances() { let newArr = new Array(); this.instances.forEach((instance) => { From 9d63484190d7302427b70d69db3e8268c7137daf Mon Sep 17 00:00:00 2001 From: SMGoro <72185434+SMGoro@users.noreply.github.com> Date: Tue, 13 Jan 2026 08:17:27 +0800 Subject: [PATCH 003/256] feat: remove soft shutdown and escalation messages from language files --- languages/en_US.json | 5 ----- languages/zh_CN.json | 7 ------- 2 files changed, 12 deletions(-) diff --git a/languages/en_US.json b/languages/en_US.json index fd9897fdf..88bb681b2 100644 --- a/languages/en_US.json +++ b/languages/en_US.json @@ -1842,11 +1842,6 @@ "TXT_CODE_app.developInfo": "Unable to start, this project is intended for MCSManager developers and cannot be run by regular users.\nPlease visit https://mcsmanager.com/ for the latest installation instructions.\nIf you intend to run in developer mode, create directory 'public' and 'src/public' along with frontend static files before running again.", "TXT_CODE_app.doc": "Reference Documentation: https://docs.mcsmanager.com/", "TXT_CODE_app.exitTip": "You can use the Ctrl+C shortcut to close the program", - "TXT_CODE_app.softShutdownStart": "Received %s, starting soft shutdown: Docker instances will be left running; stopping non-Docker instances and waiting for them to stop.", - "TXT_CODE_app.softShutdownComplete": "Soft shutdown complete: all non-Docker instances have stopped.", - "TXT_CODE_app.escalationStart": "Second interrupt received; escalating to forced shutdown for remaining non-Docker instances...", - "TXT_CODE_app.escalationComplete": "Forced non-Docker shutdown complete; proceeding to exit.", - "TXT_CODE_app.forceShutdownAllStart": "Force shutdown requested: terminating all instances (including Docker).", "TXT_CODE_app.host": "Access URL: http://localhost:{{port}}", "TXT_CODE_app.httpSetupError": "HTTP/Socket service startup error, possibly due to port occupation, insufficient permissions, or unavailable network device.", "TXT_CODE_app.instanceLoad": "All {{n}} instances have been loaded.", diff --git a/languages/zh_CN.json b/languages/zh_CN.json index 5f9dd3e70..41d90f5d4 100644 --- a/languages/zh_CN.json +++ b/languages/zh_CN.json @@ -1815,16 +1815,9 @@ "TXT_CODE_app.developInfo": "无法启动,此项目是 MCSManager 开发人员所用项目,普通用户不可直接运行。\n请前往 https://mcsmanager.com/ 了解最新的安装方式。\n如果您要以开发模式运行,请创建 public,src/public 目录并放置前端静态文件再重新运行。", "TXT_CODE_app.doc": "参考文档:https://docs.mcsmanager.com/", "TXT_CODE_app.exitTip": "你可以使用 Ctrl+C 快捷键即可关闭程序", - "TXT_CODE_app.softShutdownStart": "收到 %s,开始软关闭:Docker 实例将保持运行;正在停止其余非 Docker 实例并等待其停止。", - "TXT_CODE_app.softShutdownComplete": "软关闭完成:所有非 Docker 实例已停止。", - "TXT_CODE_app.escalationStart": "再次接收到中断,升级为对剩余非 Docker 实例的强制关闭...", - "TXT_CODE_app.escalationComplete": "强制非 Docker 关闭完成;继续退出。", - "TXT_CODE_app.forceShutdownAllStart": "请求强制关闭:正在终止所有实例(包含 Docker)。", "TXT_CODE_app.host": "访问地址: http://localhost:{{port}}", "TXT_CODE_app.httpSetupError": "HTTP/Socket 服务启动错误,可能是端口被占用,权限不足或网卡设备不可用。", "TXT_CODE_app.instanceLoad": "所有应用实例已加载,总计 {{n}} 个", - "TXT_CODE_system_instance.skippingDocker": "软关闭期间跳过 Docker 实例 %s (%s)...", - "TXT_CODE_system_instance.forcingNonDocker": "由于用户升级或超时,正在强制停止非 Docker 实例 %s (%s)。", "TXT_CODE_app.instanceLoadError": "读取本地实例文件失败:", "TXT_CODE_app.panelStarted": "控制面板端已启动", "TXT_CODE_app.password": "访问密钥:{{key}}", From efcc54e9dd4fe8861e4e34ec5349ccfe0b89eb7d Mon Sep 17 00:00:00 2001 From: xxtg666 <1747433912@qq.com> Date: Sun, 22 Feb 2026 03:14:34 +0000 Subject: [PATCH 004/256] feat: add output buffer size configuration to terminal options --- common/global.d.ts | 1 + daemon/src/entity/instance/Instance_config.ts | 3 ++- daemon/src/entity/instance/instance.ts | 21 ++++++++++++++++++- frontend/src/services/apis/instance.ts | 1 + .../widgets/instance/dialogs/TermConfig.vue | 17 +++++++++++++++ languages/de_DE.json | 4 +++- languages/en_US.json | 4 +++- languages/es_ES.json | 4 +++- languages/fr_FR.json | 4 +++- languages/ja_JP.json | 4 +++- languages/ko_KR.json | 4 +++- languages/pt_BR.json | 4 +++- languages/ru_RU.json | 4 +++- languages/th_TH.json | 4 +++- languages/tr_TR.json | 4 +++- languages/zh_CN.json | 4 +++- languages/zh_TW.json | 4 +++- .../app/routers/instance_operate_router.ts | 3 ++- 18 files changed, 79 insertions(+), 15 deletions(-) diff --git a/common/global.d.ts b/common/global.d.ts index 8797496e9..f0b89fc90 100644 --- a/common/global.d.ts +++ b/common/global.d.ts @@ -35,6 +35,7 @@ declare global { pty: boolean; ptyWindowCol: number; ptyWindowRow: number; + outputBufferSize: number; }; eventTask: { autoStart: boolean; diff --git a/daemon/src/entity/instance/Instance_config.ts b/daemon/src/entity/instance/Instance_config.ts index bd204a73a..23f2cffe3 100755 --- a/daemon/src/entity/instance/Instance_config.ts +++ b/daemon/src/entity/instance/Instance_config.ts @@ -41,7 +41,8 @@ export default class InstanceConfig implements IGlobalInstanceConfig { haveColor: false, pty: true, ptyWindowCol: 164, - ptyWindowRow: 40 + ptyWindowRow: 40, + outputBufferSize: 256 }; // Event task diff --git a/daemon/src/entity/instance/instance.ts b/daemon/src/entity/instance/instance.ts index 573769a05..47c569ed9 100755 --- a/daemon/src/entity/instance/instance.ts +++ b/daemon/src/entity/instance/instance.ts @@ -105,7 +105,7 @@ export default class Instance extends EventEmitter { public process?: IInstanceProcess; private outputLoopTask?: NodeJS.Timeout; - private outputBuffer = new CircularBuffer(256); + private outputBuffer: CircularBuffer; // When initializing an instance, the instance must be initialized through uuid and configuration class, otherwise the instance will be unavailable constructor(instanceUuid: string, config: InstanceConfig) { @@ -122,6 +122,10 @@ export default class Instance extends EventEmitter { this.config = config; + this.outputBuffer = new CircularBuffer( + config.terminalOption.outputBufferSize || 256 + ); + this.process = undefined; this.startCount = 0; } @@ -251,6 +255,21 @@ export default class Instance extends EventEmitter { configureEntityParams(this.config.terminalOption, cfg.terminalOption, "haveColor", Boolean); } + if (cfg?.terminalOption?.outputBufferSize != null) { + const newSize = Number(cfg.terminalOption.outputBufferSize); + if (newSize > 0 && newSize !== this.config.terminalOption.outputBufferSize) { + configureEntityParams( + this.config.terminalOption, + cfg.terminalOption, + "outputBufferSize", + Number + ); + if (this.isStoppedOrBusy()) { + this.outputBuffer = new CircularBuffer(newSize); + } + } + } + if (cfg.startCommand && commandStringToArray(cfg.startCommand)[0] != "{mcsm_java}") { this.config.java.id = ""; } else if (cfg.java) { diff --git a/frontend/src/services/apis/instance.ts b/frontend/src/services/apis/instance.ts index 1c292cebe..91fc6ba82 100644 --- a/frontend/src/services/apis/instance.ts +++ b/frontend/src/services/apis/instance.ts @@ -141,6 +141,7 @@ export const updateInstanceConfig = useDefineApi< terminalOption?: { haveColor: boolean; pty: boolean; + outputBufferSize?: number; }; crlf?: number; ie?: string; diff --git a/frontend/src/widgets/instance/dialogs/TermConfig.vue b/frontend/src/widgets/instance/dialogs/TermConfig.vue index de19b0bec..687db423c 100644 --- a/frontend/src/widgets/instance/dialogs/TermConfig.vue +++ b/frontend/src/widgets/instance/dialogs/TermConfig.vue @@ -91,6 +91,23 @@ defineExpose({ + + {{ + t("TXT_CODE_OUTPUT_BUFFER_SIZE") + }} + + + {{ t("TXT_CODE_OUTPUT_BUFFER_SIZE_INFO") }} + + + + + {{ t("TXT_CODE_b91a94f9") }} diff --git a/languages/de_DE.json b/languages/de_DE.json index 8e2185026..0885f23fe 100644 --- a/languages/de_DE.json +++ b/languages/de_DE.json @@ -2929,5 +2929,7 @@ "TXT_CODE_system_instance_control.existRepeatTask": "Es sind bereits doppelte Aufgaben vorhanden", "TXT_CODE_system_instance_control.illegalName": "Falscher Projektname, unterstützt nur Unterstriche, Zahlen, Buchstaben und einige lokale Sprachen", "TXT_CODE_ui.help": "[Konsole] Der Daemon verfügt über grundlegende interaktive Funktionen. Bitte geben Sie „Hilfe“ ein, um weitere Informationen anzuzeigen", - "TXT_CODE_version.versionDetectErr": "Die Versionsprüfung ist fehlgeschlagen" + "TXT_CODE_version.versionDetectErr": "Die Versionsprüfung ist fehlgeschlagen", + "TXT_CODE_OUTPUT_BUFFER_SIZE": "Ausgabepuffergröße", + "TXT_CODE_OUTPUT_BUFFER_SIZE_INFO": "Steuert die maximale Anzahl von Ausgabeblöcken, die pro Aktualisierungszyklus gepuffert werden. Das Erhöhen dieses Werts kann die Warnung 'Der Inhalt der Sofortausgabe ist zu lang' beim Starten von Servern verhindern. Standard: 256, Bereich: 16-4096. Änderungen werden beim nächsten Instanzstart wirksam." } \ No newline at end of file diff --git a/languages/en_US.json b/languages/en_US.json index 0eb343420..32d784e99 100644 --- a/languages/en_US.json +++ b/languages/en_US.json @@ -3275,5 +3275,7 @@ "TXT_CODE_system_instance_control.existRepeatTask": "A duplicate task already exists.", "TXT_CODE_system_instance_control.illegalName": "Illegal task name. Only underscores, numbers, letters, and some local language characters are supported. It's safest to stick to alphanumeric characters.", "TXT_CODE_ui.help": "[Terminal] The daemon has basic interactive functionality. Please enter 'help' for more information.", - "TXT_CODE_version.versionDetectErr": "Version Check Failed" + "TXT_CODE_version.versionDetectErr": "Version Check Failed", + "TXT_CODE_OUTPUT_BUFFER_SIZE": "Output Buffer Size", + "TXT_CODE_OUTPUT_BUFFER_SIZE_INFO": "Controls the maximum number of output chunks buffered per refresh cycle. Increasing this value can prevent the 'instantaneous output content is too long' warning when starting servers with large amounts of initial output. Default: 256, Range: 16-4096. Changes take effect on next instance start." } diff --git a/languages/es_ES.json b/languages/es_ES.json index 44f68b002..a5b472273 100644 --- a/languages/es_ES.json +++ b/languages/es_ES.json @@ -3275,5 +3275,7 @@ "TXT_CODE_system_instance_control.existRepeatTask": "Ya existen tareas duplicadas", "TXT_CODE_system_instance_control.illegalName": "Nombre de proyecto incorrecto, solo admite guiones bajos, números, letras y algunos idiomas locales", "TXT_CODE_ui.help": "[Consola] El demonio tiene funciones interactivas básicas, ingrese \"ayuda\" para ver más información", - "TXT_CODE_version.versionDetectErr": "Error en la verificación de versión" + "TXT_CODE_version.versionDetectErr": "Error en la verificación de versión", + "TXT_CODE_OUTPUT_BUFFER_SIZE": "Tamaño del búfer de salida", + "TXT_CODE_OUTPUT_BUFFER_SIZE_INFO": "Controla el número máximo de bloques de salida almacenados por ciclo de actualización. Aumentar este valor puede evitar la advertencia 'El contenido de la salida instantánea es demasiado largo' al iniciar servidores. Predeterminado: 256, Rango: 16-4096. Los cambios surten efecto en el próximo inicio de la instancia." } \ No newline at end of file diff --git a/languages/fr_FR.json b/languages/fr_FR.json index e2cb1e484..c1884d7e0 100644 --- a/languages/fr_FR.json +++ b/languages/fr_FR.json @@ -3275,5 +3275,7 @@ "TXT_CODE_system_instance_control.existRepeatTask": "Des tâches en double existent déjà", "TXT_CODE_system_instance_control.illegalName": "Nom de projet incorrect, ne prend en charge que les traits de soulignement, les chiffres, les lettres et certaines langues locales", "TXT_CODE_ui.help": "[Console] Le démon a des fonctions interactives de base, veuillez saisir \"aide\" pour afficher plus d'informations", - "TXT_CODE_version.versionDetectErr": "La vérification de la version a échoué" + "TXT_CODE_version.versionDetectErr": "La vérification de la version a échoué", + "TXT_CODE_OUTPUT_BUFFER_SIZE": "Taille du tampon de sortie", + "TXT_CODE_OUTPUT_BUFFER_SIZE_INFO": "Contrôle le nombre maximum de blocs de sortie mis en mémoire tampon par cycle de rafraîchissement. Augmenter cette valeur peut empêcher l'avertissement 'Le contenu de la sortie instantanée est trop long' lors du démarrage des serveurs. Par défaut : 256, Plage : 16-4096. Les modifications prendront effet au prochain démarrage de l'instance." } \ No newline at end of file diff --git a/languages/ja_JP.json b/languages/ja_JP.json index 0a2202ee3..8c3983327 100644 --- a/languages/ja_JP.json +++ b/languages/ja_JP.json @@ -3275,5 +3275,7 @@ "TXT_CODE_system_instance_control.existRepeatTask": "重複したタスクがすでに存在します", "TXT_CODE_system_instance_control.illegalName": "プロジェクト名が間違っています。アンダースコア、数字、文字、および一部の現地言語のみをサポートしています", "TXT_CODE_ui.help": "[コンソール] デーモンには基本的な対話機能があります。詳細を表示するには「ヘルプ」と入力してください。", - "TXT_CODE_version.versionDetectErr": "バージョンチェックに失敗しました" + "TXT_CODE_version.versionDetectErr": "バージョンチェックに失敗しました", + "TXT_CODE_OUTPUT_BUFFER_SIZE": "出力バッファサイズ", + "TXT_CODE_OUTPUT_BUFFER_SIZE_INFO": "リフレッシュサイクルごとにバッファリングされる出力チャンクの最大数を制御します。この値を増やすと、サーバー起動時の「インスタント出力コンテンツが長すぎるため、表示が拒否されました」という警告を防ぐことができます。デフォルト: 256、範囲: 16-4096。変更は次回インスタンス起動時に有効になります。" } \ No newline at end of file diff --git a/languages/ko_KR.json b/languages/ko_KR.json index 476603a2b..f14d33800 100644 --- a/languages/ko_KR.json +++ b/languages/ko_KR.json @@ -3275,5 +3275,7 @@ "TXT_CODE_system_instance_control.existRepeatTask": "중복된 할 일이 이미 존재합니다.", "TXT_CODE_system_instance_control.illegalName": "프로젝트 이름이 잘못되었습니다. 밑줄, 숫자, 문자 및 일부 현지 언어만 지원됩니다.", "TXT_CODE_ui.help": "[콘솔] 데몬에는 기본 대화형 기능이 있습니다. 자세한 내용을 보려면 \"help\"를 입력하십시오.", - "TXT_CODE_version.versionDetectErr": "버전 확인 실패" + "TXT_CODE_version.versionDetectErr": "버전 확인 실패", + "TXT_CODE_OUTPUT_BUFFER_SIZE": "출력 버퍼 크기", + "TXT_CODE_OUTPUT_BUFFER_SIZE_INFO": "새로 고침 주기당 버퍼링되는 최대 출력 청크 수를 제어합니다. 이 값을 늘리면 서버 시작 시 '인스턴트 출력 내용이 너무 길어서 표시가 거부되었습니다' 경고를 방지할 수 있습니다. 기본값: 256, 범위: 16-4096. 변경 사항은 다음 인스턴스 시작 시 적용됩니다." } \ No newline at end of file diff --git a/languages/pt_BR.json b/languages/pt_BR.json index ac1f8089f..81f128204 100644 --- a/languages/pt_BR.json +++ b/languages/pt_BR.json @@ -3275,5 +3275,7 @@ "TXT_CODE_system_instance_control.existRepeatTask": "Uma tarefa duplicada já existe.", "TXT_CODE_system_instance_control.illegalName": "Nome de tarefa ilegal. Apenas underscores, números, letras e alguns caracteres de idioma local são suportados.", "TXT_CODE_ui.help": "[Terminal] O daemon tem funcionalidade básica de interação. Por favor, insira 'help' para mais informações.", - "TXT_CODE_version.versionDetectErr": "Falha na verificação da versão" + "TXT_CODE_version.versionDetectErr": "Falha na verificação da versão", + "TXT_CODE_OUTPUT_BUFFER_SIZE": "Tamanho do Buffer de Saída", + "TXT_CODE_OUTPUT_BUFFER_SIZE_INFO": "Controla o número máximo de blocos de saída armazenados por ciclo de atualização. Aumentar este valor pode evitar o aviso 'O conteúdo da saída instantânea é muito longo' ao iniciar servidores. Padrão: 256, Intervalo: 16-4096. As alterações entram em vigor na próxima inicialização da instância." } \ No newline at end of file diff --git a/languages/ru_RU.json b/languages/ru_RU.json index 66a4df8fc..c335e4aa5 100644 --- a/languages/ru_RU.json +++ b/languages/ru_RU.json @@ -3275,5 +3275,7 @@ "TXT_CODE_system_instance_control.existRepeatTask": "Такая задача уже существует.", "TXT_CODE_system_instance_control.illegalName": "Некорректное имя задачи. Допустимы только подчеркивания, цифры, буквы и некоторые локальные языковые символы.", "TXT_CODE_ui.help": "[Терминал] У демона есть базовые интерактивные функции. Пожалуйста, введите 'help' для получения больше информации.", - "TXT_CODE_version.versionDetectErr": "Ошибка проверки версии" + "TXT_CODE_version.versionDetectErr": "Ошибка проверки версии", + "TXT_CODE_OUTPUT_BUFFER_SIZE": "Размер буфера вывода", + "TXT_CODE_OUTPUT_BUFFER_SIZE_INFO": "Контролирует максимальное количество блоков вывода, буферизуемых за один цикл обновления. Увеличение этого значения может предотвратить предупреждение «Мгновенный вывод слишком длинный и отклонен» при запуске серверов. По умолчанию: 256, Диапазон: 16-4096. Изменения вступят в силу при следующем запуске экземпляра." } \ No newline at end of file diff --git a/languages/th_TH.json b/languages/th_TH.json index 0ccc5adc9..a0b32bfea 100644 --- a/languages/th_TH.json +++ b/languages/th_TH.json @@ -3275,5 +3275,7 @@ "TXT_CODE_system_instance_control.existRepeatTask": "มีงานที่ซ้ำกันอยู่แล้ว", "TXT_CODE_system_instance_control.illegalName": "ชื่องานไม่ถูกต้อง รองรับเฉพาะขีดล่าง ตัวเลข ตัวอักษร และอักขระภาษาท้องถิ่นบางตัวเท่านั้น", "TXT_CODE_ui.help": "[เทอร์มินัล] Daemon มีฟังก์ชันการโต้ตอบพื้นฐาน กรุณาป้อน 'help' สำหรับข้อมูลเพิ่มเติม", - "TXT_CODE_version.versionDetectErr": "การตรวจสอบเวอร์ชันล้มเหลว" + "TXT_CODE_version.versionDetectErr": "การตรวจสอบเวอร์ชันล้มเหลว", + "TXT_CODE_OUTPUT_BUFFER_SIZE": "Output Buffer Size", + "TXT_CODE_OUTPUT_BUFFER_SIZE_INFO": "Controls the maximum number of output chunks buffered per refresh cycle. Increasing this value can prevent the 'instantaneous output content is too long' warning when starting servers with large amounts of initial output. Default: 256, Range: 16-4096. Changes take effect on next instance start." } \ No newline at end of file diff --git a/languages/tr_TR.json b/languages/tr_TR.json index 64b494e7f..742afc618 100644 --- a/languages/tr_TR.json +++ b/languages/tr_TR.json @@ -3275,5 +3275,7 @@ "TXT_CODE_system_instance_control.existRepeatTask": "Yinelenen bir görev zaten var.", "TXT_CODE_system_instance_control.illegalName": "Yasadışı görev adı. Yalnızca alt çizgiler, sayılar, harfler ve bazı yerel dil karakterleri desteklenir.", "TXT_CODE_ui.help": "[Terminal] Daemon temel etkileşimli işlevselliğe sahiptir. Daha fazla bilgi için lütfen 'help' girin.", - "TXT_CODE_version.versionDetectErr": "Sürüm Kontrolü Başarısız" + "TXT_CODE_version.versionDetectErr": "Sürüm Kontrolü Başarısız", + "TXT_CODE_OUTPUT_BUFFER_SIZE": "Output Buffer Size", + "TXT_CODE_OUTPUT_BUFFER_SIZE_INFO": "Controls the maximum number of output chunks buffered per refresh cycle. Increasing this value can prevent the 'instantaneous output content is too long' warning when starting servers with large amounts of initial output. Default: 256, Range: 16-4096. Changes take effect on next instance start." } \ No newline at end of file diff --git a/languages/zh_CN.json b/languages/zh_CN.json index 8aa3b4092..2a8394789 100644 --- a/languages/zh_CN.json +++ b/languages/zh_CN.json @@ -3275,5 +3275,7 @@ "TXT_CODE_system_instance_control.existRepeatTask": "已存在重复的任务", "TXT_CODE_system_instance_control.illegalName": "非法的计划名,仅支持下划线,数字,字母和部分本地语言", "TXT_CODE_ui.help": "[终端] 守护进程拥有基本的交互功能,请输入\"help\"查看更多信息", - "TXT_CODE_version.versionDetectErr": "版本检查失败" + "TXT_CODE_version.versionDetectErr": "版本检查失败", + "TXT_CODE_OUTPUT_BUFFER_SIZE": "输出缓冲区大小", + "TXT_CODE_OUTPUT_BUFFER_SIZE_INFO": "控制每个刷新周期内缓冲的最大输出块数量。增大此值可以防止启动服务端时出现「此刻瞬时输出内容过长,已拒绝显示」的警告。默认值:256,范围:16-4096。更改将在下次启动实例时生效。" } diff --git a/languages/zh_TW.json b/languages/zh_TW.json index 6366ead65..01d924e8e 100644 --- a/languages/zh_TW.json +++ b/languages/zh_TW.json @@ -3275,5 +3275,7 @@ "TXT_CODE_system_instance_control.existRepeatTask": "已存在重複的任務", "TXT_CODE_system_instance_control.illegalName": "錯誤的計畫名,只支援底線,數字,字母和部分本地語言", "TXT_CODE_ui.help": "[終端] 守護程式擁有基本的互動功能,請輸入\"help\"查看更多資訊", - "TXT_CODE_version.versionDetectErr": "版本檢查失敗" + "TXT_CODE_version.versionDetectErr": "版本檢查失敗", + "TXT_CODE_OUTPUT_BUFFER_SIZE": "輸出緩衝區大小", + "TXT_CODE_OUTPUT_BUFFER_SIZE_INFO": "控制每個刷新週期內緩衝的最大輸出塊數量。增大此值可以防止啟動伺服器時出現「瞬間輸出內容太長,已拒絕顯示」的警告。預設值:256,範圍:16-4096。更改將在下次啟動實例時生效。" } \ No newline at end of file diff --git a/panel/src/app/routers/instance_operate_router.ts b/panel/src/app/routers/instance_operate_router.ts index c5e69dc3a..66ed9454e 100755 --- a/panel/src/app/routers/instance_operate_router.ts +++ b/panel/src/app/routers/instance_operate_router.ts @@ -442,7 +442,8 @@ router.put( haveColor: toBoolean(config.terminalOption?.haveColor), pty: toBoolean(config.terminalOption?.pty), ptyWindowCol: toNumber(config.terminalOption?.ptyWindowCol), - ptyWindowRow: toNumber(config.terminalOption?.ptyWindowRow) + ptyWindowRow: toNumber(config.terminalOption?.ptyWindowRow), + outputBufferSize: toNumber(config.terminalOption?.outputBufferSize) }; // extra service From 026ba4b486d7b0e0ea76b50c366e591aa7f7f6a4 Mon Sep 17 00:00:00 2001 From: wyf9 Date: Sun, 22 Feb 2026 12:38:45 +0800 Subject: [PATCH 005/256] Fix typo in zh_CN.json for auto-restart message --- languages/zh_CN.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/languages/zh_CN.json b/languages/zh_CN.json index 8aa3b4092..782a4ae83 100644 --- a/languages/zh_CN.json +++ b/languages/zh_CN.json @@ -1400,7 +1400,7 @@ "TXT_CODE_8900e7ee": "添加现有Java", "TXT_CODE_890aa44c": "RCON 端口", "TXT_CODE_893567ac": "二次确认", - "TXT_CODE_894b8e52": "达到自动重启最大次数上线", + "TXT_CODE_894b8e52": "达到自动重启最大次数上限", "TXT_CODE_8956123b": "我们是否应将IP地址和其他数据转发到后端服务器?", "TXT_CODE_8965b2cf": "将发送到JAVA客户端的服务器名称。这在暂停菜单和设置菜单中都可见。", "TXT_CODE_8981d724": "未命名标题栏", From 5355dbc2a7b568029941750c2ce1ca0c39b3da71 Mon Sep 17 00:00:00 2001 From: xxtg666 <1747433912@qq.com> Date: Sun, 22 Feb 2026 04:43:47 +0000 Subject: [PATCH 006/256] feat: update output buffer size configuration keys in language files --- frontend/src/widgets/instance/dialogs/TermConfig.vue | 4 ++-- languages/de_DE.json | 4 ++-- languages/en_US.json | 4 ++-- languages/es_ES.json | 4 ++-- languages/fr_FR.json | 4 ++-- languages/ja_JP.json | 4 ++-- languages/ko_KR.json | 4 ++-- languages/pt_BR.json | 4 ++-- languages/ru_RU.json | 4 ++-- languages/th_TH.json | 4 ++-- languages/tr_TR.json | 4 ++-- languages/zh_CN.json | 4 ++-- languages/zh_TW.json | 4 ++-- 13 files changed, 26 insertions(+), 26 deletions(-) diff --git a/frontend/src/widgets/instance/dialogs/TermConfig.vue b/frontend/src/widgets/instance/dialogs/TermConfig.vue index 687db423c..0490a3d3b 100644 --- a/frontend/src/widgets/instance/dialogs/TermConfig.vue +++ b/frontend/src/widgets/instance/dialogs/TermConfig.vue @@ -93,11 +93,11 @@ defineExpose({ {{ - t("TXT_CODE_OUTPUT_BUFFER_SIZE") + t("TXT_CODE_instanceConf.outputBufferSize") }} - {{ t("TXT_CODE_OUTPUT_BUFFER_SIZE_INFO") }} + {{ t("TXT_CODE_instanceConf.outputBufferSizeInfo") }} Date: Sun, 22 Feb 2026 06:27:02 +0000 Subject: [PATCH 007/256] refactor: move log buffer size configuration to daemon settings --- common/global.d.ts | 1 - daemon/src/entity/config.ts | 7 +++++++ daemon/src/entity/instance/Instance_config.ts | 3 +-- daemon/src/entity/instance/instance.ts | 20 ++++-------------- daemon/src/routers/info_router.ts | 7 ++++++- frontend/src/services/apis/instance.ts | 1 - .../widgets/instance/dialogs/TermConfig.vue | 17 --------------- .../src/widgets/node/NodeDetailDialog.vue | 21 ++++++++++++++++++- languages/de_DE.json | 4 ++-- languages/en_US.json | 4 ++-- languages/es_ES.json | 4 ++-- languages/fr_FR.json | 4 ++-- languages/ja_JP.json | 4 ++-- languages/ko_KR.json | 4 ++-- languages/pt_BR.json | 4 ++-- languages/ru_RU.json | 4 ++-- languages/th_TH.json | 4 ++-- languages/tr_TR.json | 4 ++-- languages/zh_CN.json | 4 ++-- languages/zh_TW.json | 4 ++-- .../app/routers/instance_operate_router.ts | 3 +-- 21 files changed, 63 insertions(+), 65 deletions(-) diff --git a/common/global.d.ts b/common/global.d.ts index f0b89fc90..8797496e9 100644 --- a/common/global.d.ts +++ b/common/global.d.ts @@ -35,7 +35,6 @@ declare global { pty: boolean; ptyWindowCol: number; ptyWindowRow: number; - outputBufferSize: number; }; eventTask: { autoStart: boolean; diff --git a/daemon/src/entity/config.ts b/daemon/src/entity/config.ts index 831f9e9f0..02ec581de 100755 --- a/daemon/src/entity/config.ts +++ b/daemon/src/entity/config.ts @@ -31,6 +31,13 @@ class Config { // default: 1, if set 0 => Unlimited public maxDownloadFromUrlFileCount = 1; + // Output buffer size (number of chunks) for instance terminal output. + // Each chunk is up to 256 characters, flushed every 50ms. + // Increasing this value allows more output per flush cycle, + // but may increase memory usage under high output load. + // default: 256 (~64KB per flush), range: 16-4096 + public outputBufferSize = 256; + public whiteListPanelIp = false; public whiteListPanelIps = ["127.0.0.1", "::1"]; diff --git a/daemon/src/entity/instance/Instance_config.ts b/daemon/src/entity/instance/Instance_config.ts index 23f2cffe3..bd204a73a 100755 --- a/daemon/src/entity/instance/Instance_config.ts +++ b/daemon/src/entity/instance/Instance_config.ts @@ -41,8 +41,7 @@ export default class InstanceConfig implements IGlobalInstanceConfig { haveColor: false, pty: true, ptyWindowCol: 164, - ptyWindowRow: 40, - outputBufferSize: 256 + ptyWindowRow: 40 }; // Event task diff --git a/daemon/src/entity/instance/instance.ts b/daemon/src/entity/instance/instance.ts index 47c569ed9..508849433 100755 --- a/daemon/src/entity/instance/instance.ts +++ b/daemon/src/entity/instance/instance.ts @@ -123,7 +123,7 @@ export default class Instance extends EventEmitter { this.config = config; this.outputBuffer = new CircularBuffer( - config.terminalOption.outputBufferSize || 256 + globalConfiguration.config.outputBufferSize || 256 ); this.process = undefined; @@ -255,21 +255,6 @@ export default class Instance extends EventEmitter { configureEntityParams(this.config.terminalOption, cfg.terminalOption, "haveColor", Boolean); } - if (cfg?.terminalOption?.outputBufferSize != null) { - const newSize = Number(cfg.terminalOption.outputBufferSize); - if (newSize > 0 && newSize !== this.config.terminalOption.outputBufferSize) { - configureEntityParams( - this.config.terminalOption, - cfg.terminalOption, - "outputBufferSize", - Number - ); - if (this.isStoppedOrBusy()) { - this.outputBuffer = new CircularBuffer(newSize); - } - } - } - if (cfg.startCommand && commandStringToArray(cfg.startCommand)[0] != "{mcsm_java}") { this.config.java.id = ""; } else if (cfg.java) { @@ -591,6 +576,9 @@ export default class Instance extends EventEmitter { } private startOutputLoop() { + this.outputBuffer = new CircularBuffer( + globalConfiguration.config.outputBufferSize || 256 + ); this.outputLoopTask = setInterval(() => { this.flushOutputBuffer(); }, 50); diff --git a/daemon/src/routers/info_router.ts b/daemon/src/routers/info_router.ts index 253eba247..cb7000292 100755 --- a/daemon/src/routers/info_router.ts +++ b/daemon/src/routers/info_router.ts @@ -53,7 +53,8 @@ routerApp.on("info/overview", async (ctx) => { portRangeStart: globalConfiguration.config.allocatablePortRange[0], portRangeEnd: globalConfiguration.config.allocatablePortRange[1], portAssignInterval: globalConfiguration.config.portAssignInterval, - port: globalConfiguration.config.port + port: globalConfiguration.config.port, + outputBufferSize: globalConfiguration.config.outputBufferSize }, dockerPlatforms }; @@ -69,6 +70,7 @@ routerApp.on("info/setting", async (ctx, data) => { const portRangeEnd = toNumber(data.portRangeEnd); const portAssignInterval = toNumber(data.portAssignInterval); const port = toNumber(data.port); + const outputBufferSize = toNumber(data.outputBufferSize); if (language) { logger.warn($t("TXT_CODE_66e32091"), language); i18next.changeLanguage(language); @@ -94,6 +96,9 @@ routerApp.on("info/setting", async (ctx, data) => { if (port && port > 0 && port < 65535) { globalConfiguration.config.port = port; } + if (outputBufferSize != null && outputBufferSize >= 16 && outputBufferSize <= 4096) { + globalConfiguration.config.outputBufferSize = outputBufferSize; + } globalConfiguration.store(); protocol.response(ctx, true); }); diff --git a/frontend/src/services/apis/instance.ts b/frontend/src/services/apis/instance.ts index 91fc6ba82..1c292cebe 100644 --- a/frontend/src/services/apis/instance.ts +++ b/frontend/src/services/apis/instance.ts @@ -141,7 +141,6 @@ export const updateInstanceConfig = useDefineApi< terminalOption?: { haveColor: boolean; pty: boolean; - outputBufferSize?: number; }; crlf?: number; ie?: string; diff --git a/frontend/src/widgets/instance/dialogs/TermConfig.vue b/frontend/src/widgets/instance/dialogs/TermConfig.vue index 0490a3d3b..de19b0bec 100644 --- a/frontend/src/widgets/instance/dialogs/TermConfig.vue +++ b/frontend/src/widgets/instance/dialogs/TermConfig.vue @@ -91,23 +91,6 @@ defineExpose({ - - {{ - t("TXT_CODE_instanceConf.outputBufferSize") - }} - - - {{ t("TXT_CODE_instanceConf.outputBufferSizeInfo") }} - - - - - {{ t("TXT_CODE_b91a94f9") }} diff --git a/frontend/src/widgets/node/NodeDetailDialog.vue b/frontend/src/widgets/node/NodeDetailDialog.vue index 035c5a529..641fe32e0 100644 --- a/frontend/src/widgets/node/NodeDetailDialog.vue +++ b/frontend/src/widgets/node/NodeDetailDialog.vue @@ -29,7 +29,8 @@ const DEFAULT_CONFIG = { portRangeEnd: 0, portAssignInterval: 0, daemonPort: 24444, - remoteMappings: [] as IPanelOverviewRemoteMappingResponse[] + remoteMappings: [] as IPanelOverviewRemoteMappingResponse[], + outputBufferSize: 256 }; const SPEED_RATE_OPTIONS = [ @@ -274,6 +275,24 @@ defineExpose({ openDialog }); + + + + + {{ t("TXT_CODE_daemon_outputBufferSizeInfo") }} + + + + + diff --git a/languages/de_DE.json b/languages/de_DE.json index aaa8c82b8..73b38e0c1 100644 --- a/languages/de_DE.json +++ b/languages/de_DE.json @@ -2930,6 +2930,6 @@ "TXT_CODE_system_instance_control.illegalName": "Falscher Projektname, unterstützt nur Unterstriche, Zahlen, Buchstaben und einige lokale Sprachen", "TXT_CODE_ui.help": "[Konsole] Der Daemon verfügt über grundlegende interaktive Funktionen. Bitte geben Sie „Hilfe“ ein, um weitere Informationen anzuzeigen", "TXT_CODE_version.versionDetectErr": "Die Versionsprüfung ist fehlgeschlagen", - "TXT_CODE_instanceConf.outputBufferSize": "Ausgabepuffergröße", - "TXT_CODE_instanceConf.outputBufferSizeInfo": "Steuert die maximale Anzahl von Ausgabeblöcken, die pro Aktualisierungszyklus gepuffert werden. Das Erhöhen dieses Werts kann die Warnung 'Der Inhalt der Sofortausgabe ist zu lang' beim Starten von Servern verhindern. Standard: 256, Bereich: 16-4096. Änderungen werden beim nächsten Instanzstart wirksam." + "TXT_CODE_daemon_outputBufferSize": "Log-Puffergröße", + "TXT_CODE_daemon_outputBufferSizeInfo": "Ein größerer Puffer gewährleistet eine bessere Vollständigkeit der Terminalausgabe, erhöht jedoch den Speicher- und Leistungsdruck und kann sogar zu Speicherlecks führen." } \ No newline at end of file diff --git a/languages/en_US.json b/languages/en_US.json index a873f7c78..c18a521cd 100644 --- a/languages/en_US.json +++ b/languages/en_US.json @@ -3276,6 +3276,6 @@ "TXT_CODE_system_instance_control.illegalName": "Illegal task name. Only underscores, numbers, letters, and some local language characters are supported. It's safest to stick to alphanumeric characters.", "TXT_CODE_ui.help": "[Terminal] The daemon has basic interactive functionality. Please enter 'help' for more information.", "TXT_CODE_version.versionDetectErr": "Version Check Failed", - "TXT_CODE_instanceConf.outputBufferSize": "Output Buffer Size", - "TXT_CODE_instanceConf.outputBufferSizeInfo": "Controls the maximum number of output chunks buffered per refresh cycle. Increasing this value can prevent the 'instantaneous output content is too long' warning when starting servers with large amounts of initial output. Default: 256, Range: 16-4096. Changes take effect on next instance start." + "TXT_CODE_daemon_outputBufferSize": "Log Buffer Size", + "TXT_CODE_daemon_outputBufferSizeInfo": "Increasing the buffer can better ensure the completeness of terminal output content, but will put greater pressure on memory and performance, and may even cause memory leaks." } diff --git a/languages/es_ES.json b/languages/es_ES.json index d3a638e6d..49cdf0f03 100644 --- a/languages/es_ES.json +++ b/languages/es_ES.json @@ -3276,6 +3276,6 @@ "TXT_CODE_system_instance_control.illegalName": "Nombre de proyecto incorrecto, solo admite guiones bajos, números, letras y algunos idiomas locales", "TXT_CODE_ui.help": "[Consola] El demonio tiene funciones interactivas básicas, ingrese \"ayuda\" para ver más información", "TXT_CODE_version.versionDetectErr": "Error en la verificación de versión", - "TXT_CODE_instanceConf.outputBufferSize": "Tamaño del búfer de salida", - "TXT_CODE_instanceConf.outputBufferSizeInfo": "Controla el número máximo de bloques de salida almacenados por ciclo de actualización. Aumentar este valor puede evitar la advertencia 'El contenido de la salida instantánea es demasiado largo' al iniciar servidores. Predeterminado: 256, Rango: 16-4096. Los cambios surten efecto en el próximo inicio de la instancia." + "TXT_CODE_daemon_outputBufferSize": "Tamaño del búfer de registro", + "TXT_CODE_daemon_outputBufferSizeInfo": "Aumentar el búfer puede garantizar mejor la integridad del contenido de salida del terminal, pero ejercerá mayor presión sobre la memoria y el rendimiento, e incluso puede causar fugas de memoria." } \ No newline at end of file diff --git a/languages/fr_FR.json b/languages/fr_FR.json index 0fa9a6588..cd6a72146 100644 --- a/languages/fr_FR.json +++ b/languages/fr_FR.json @@ -3276,6 +3276,6 @@ "TXT_CODE_system_instance_control.illegalName": "Nom de projet incorrect, ne prend en charge que les traits de soulignement, les chiffres, les lettres et certaines langues locales", "TXT_CODE_ui.help": "[Console] Le démon a des fonctions interactives de base, veuillez saisir \"aide\" pour afficher plus d'informations", "TXT_CODE_version.versionDetectErr": "La vérification de la version a échoué", - "TXT_CODE_instanceConf.outputBufferSize": "Taille du tampon de sortie", - "TXT_CODE_instanceConf.outputBufferSizeInfo": "Contrôle le nombre maximum de blocs de sortie mis en mémoire tampon par cycle de rafraîchissement. Augmenter cette valeur peut empêcher l'avertissement 'Le contenu de la sortie instantanée est trop long' lors du démarrage des serveurs. Par défaut : 256, Plage : 16-4096. Les modifications prendront effet au prochain démarrage de l'instance." + "TXT_CODE_daemon_outputBufferSize": "Taille du tampon de journalisation", + "TXT_CODE_daemon_outputBufferSizeInfo": "Augmenter le tampon permet de mieux garantir l'intégrité du contenu de sortie du terminal, mais augmente la pression sur la mémoire et les performances, pouvant même provoquer des fuites de mémoire." } \ No newline at end of file diff --git a/languages/ja_JP.json b/languages/ja_JP.json index 5beeac11c..abcf60154 100644 --- a/languages/ja_JP.json +++ b/languages/ja_JP.json @@ -3276,6 +3276,6 @@ "TXT_CODE_system_instance_control.illegalName": "プロジェクト名が間違っています。アンダースコア、数字、文字、および一部の現地言語のみをサポートしています", "TXT_CODE_ui.help": "[コンソール] デーモンには基本的な対話機能があります。詳細を表示するには「ヘルプ」と入力してください。", "TXT_CODE_version.versionDetectErr": "バージョンチェックに失敗しました", - "TXT_CODE_instanceConf.outputBufferSize": "出力バッファサイズ", - "TXT_CODE_instanceConf.outputBufferSizeInfo": "リフレッシュサイクルごとにバッファリングされる出力チャンクの最大数を制御します。この値を増やすと、サーバー起動時の「インスタント出力コンテンツが長すぎるため、表示が拒否されました」という警告を防ぐことができます。デフォルト: 256、範囲: 16-4096。変更は次回インスタンス起動時に有効になります。" + "TXT_CODE_daemon_outputBufferSize": "ログバッファサイズ", + "TXT_CODE_daemon_outputBufferSizeInfo": "バッファを増やすことでターミナル出力の内容の完全性をより確保できますが、メモリとパフォーマンスへの負荷が大きくなり、メモリリークが発生する可能性もあります。" } \ No newline at end of file diff --git a/languages/ko_KR.json b/languages/ko_KR.json index 8d27d3c0d..3dc7ab5e6 100644 --- a/languages/ko_KR.json +++ b/languages/ko_KR.json @@ -3276,6 +3276,6 @@ "TXT_CODE_system_instance_control.illegalName": "프로젝트 이름이 잘못되었습니다. 밑줄, 숫자, 문자 및 일부 현지 언어만 지원됩니다.", "TXT_CODE_ui.help": "[콘솔] 데몬에는 기본 대화형 기능이 있습니다. 자세한 내용을 보려면 \"help\"를 입력하십시오.", "TXT_CODE_version.versionDetectErr": "버전 확인 실패", - "TXT_CODE_instanceConf.outputBufferSize": "출력 버퍼 크기", - "TXT_CODE_instanceConf.outputBufferSizeInfo": "새로 고침 주기당 버퍼링되는 최대 출력 청크 수를 제어합니다. 이 값을 늘리면 서버 시작 시 '인스턴트 출력 내용이 너무 길어서 표시가 거부되었습니다' 경고를 방지할 수 있습니다. 기본값: 256, 범위: 16-4096. 변경 사항은 다음 인스턴스 시작 시 적용됩니다." + "TXT_CODE_daemon_outputBufferSize": "로그 버퍼 크기", + "TXT_CODE_daemon_outputBufferSizeInfo": "버퍼를 늘리면 터미널 출력 내용의 완전성을 더 잘 보장할 수 있지만, 메모리와 성능에 더 큰 부담을 주며 메모리 누수가 발생할 수도 있습니다." } \ No newline at end of file diff --git a/languages/pt_BR.json b/languages/pt_BR.json index 05e8b4d1b..0dedde3dd 100644 --- a/languages/pt_BR.json +++ b/languages/pt_BR.json @@ -3276,6 +3276,6 @@ "TXT_CODE_system_instance_control.illegalName": "Nome de tarefa ilegal. Apenas underscores, números, letras e alguns caracteres de idioma local são suportados.", "TXT_CODE_ui.help": "[Terminal] O daemon tem funcionalidade básica de interação. Por favor, insira 'help' para mais informações.", "TXT_CODE_version.versionDetectErr": "Falha na verificação da versão", - "TXT_CODE_instanceConf.outputBufferSize": "Tamanho do Buffer de Saída", - "TXT_CODE_instanceConf.outputBufferSizeInfo": "Controla o número máximo de blocos de saída armazenados por ciclo de atualização. Aumentar este valor pode evitar o aviso 'O conteúdo da saída instantânea é muito longo' ao iniciar servidores. Padrão: 256, Intervalo: 16-4096. As alterações entram em vigor na próxima inicialização da instância." + "TXT_CODE_daemon_outputBufferSize": "Tamanho do buffer de log", + "TXT_CODE_daemon_outputBufferSizeInfo": "Aumentar o buffer pode garantir melhor a integridade do conteúdo de saída do terminal, mas aumentará a pressão sobre a memória e o desempenho, podendo até causar vazamentos de memória." } \ No newline at end of file diff --git a/languages/ru_RU.json b/languages/ru_RU.json index 76f28a952..f3d12a43f 100644 --- a/languages/ru_RU.json +++ b/languages/ru_RU.json @@ -3276,6 +3276,6 @@ "TXT_CODE_system_instance_control.illegalName": "Некорректное имя задачи. Допустимы только подчеркивания, цифры, буквы и некоторые локальные языковые символы.", "TXT_CODE_ui.help": "[Терминал] У демона есть базовые интерактивные функции. Пожалуйста, введите 'help' для получения больше информации.", "TXT_CODE_version.versionDetectErr": "Ошибка проверки версии", - "TXT_CODE_instanceConf.outputBufferSize": "Размер буфера вывода", - "TXT_CODE_instanceConf.outputBufferSizeInfo": "Контролирует максимальное количество блоков вывода, буферизуемых за один цикл обновления. Увеличение этого значения может предотвратить предупреждение «Мгновенный вывод слишком длинный и отклонен» при запуске серверов. По умолчанию: 256, Диапазон: 16-4096. Изменения вступят в силу при следующем запуске экземпляра." + "TXT_CODE_daemon_outputBufferSize": "Размер буфера логов", + "TXT_CODE_daemon_outputBufferSizeInfo": "Увеличение буфера лучше обеспечивает полноту вывода терминала, но увеличивает нагрузку на память и производительность, вплоть до утечки памяти." } \ No newline at end of file diff --git a/languages/th_TH.json b/languages/th_TH.json index 17317a375..a23cd40a3 100644 --- a/languages/th_TH.json +++ b/languages/th_TH.json @@ -3276,6 +3276,6 @@ "TXT_CODE_system_instance_control.illegalName": "ชื่องานไม่ถูกต้อง รองรับเฉพาะขีดล่าง ตัวเลข ตัวอักษร และอักขระภาษาท้องถิ่นบางตัวเท่านั้น", "TXT_CODE_ui.help": "[เทอร์มินัล] Daemon มีฟังก์ชันการโต้ตอบพื้นฐาน กรุณาป้อน 'help' สำหรับข้อมูลเพิ่มเติม", "TXT_CODE_version.versionDetectErr": "การตรวจสอบเวอร์ชันล้มเหลว", - "TXT_CODE_instanceConf.outputBufferSize": "Output Buffer Size", - "TXT_CODE_instanceConf.outputBufferSizeInfo": "Controls the maximum number of output chunks buffered per refresh cycle. Increasing this value can prevent the 'instantaneous output content is too long' warning when starting servers with large amounts of initial output. Default: 256, Range: 16-4096. Changes take effect on next instance start." + "TXT_CODE_daemon_outputBufferSize": "Log Buffer Size", + "TXT_CODE_daemon_outputBufferSizeInfo": "Increasing the buffer can better ensure the completeness of terminal output content, but will put greater pressure on memory and performance, and may even cause memory leaks." } \ No newline at end of file diff --git a/languages/tr_TR.json b/languages/tr_TR.json index 27480c543..dbf96c98b 100644 --- a/languages/tr_TR.json +++ b/languages/tr_TR.json @@ -3276,6 +3276,6 @@ "TXT_CODE_system_instance_control.illegalName": "Yasadışı görev adı. Yalnızca alt çizgiler, sayılar, harfler ve bazı yerel dil karakterleri desteklenir.", "TXT_CODE_ui.help": "[Terminal] Daemon temel etkileşimli işlevselliğe sahiptir. Daha fazla bilgi için lütfen 'help' girin.", "TXT_CODE_version.versionDetectErr": "Sürüm Kontrolü Başarısız", - "TXT_CODE_instanceConf.outputBufferSize": "Output Buffer Size", - "TXT_CODE_instanceConf.outputBufferSizeInfo": "Controls the maximum number of output chunks buffered per refresh cycle. Increasing this value can prevent the 'instantaneous output content is too long' warning when starting servers with large amounts of initial output. Default: 256, Range: 16-4096. Changes take effect on next instance start." + "TXT_CODE_daemon_outputBufferSize": "Log Buffer Size", + "TXT_CODE_daemon_outputBufferSizeInfo": "Increasing the buffer can better ensure the completeness of terminal output content, but will put greater pressure on memory and performance, and may even cause memory leaks." } \ No newline at end of file diff --git a/languages/zh_CN.json b/languages/zh_CN.json index b61cd40b1..b532eb870 100644 --- a/languages/zh_CN.json +++ b/languages/zh_CN.json @@ -3276,6 +3276,6 @@ "TXT_CODE_system_instance_control.illegalName": "非法的计划名,仅支持下划线,数字,字母和部分本地语言", "TXT_CODE_ui.help": "[终端] 守护进程拥有基本的交互功能,请输入\"help\"查看更多信息", "TXT_CODE_version.versionDetectErr": "版本检查失败", - "TXT_CODE_instanceConf.outputBufferSize": "输出缓冲区大小", - "TXT_CODE_instanceConf.outputBufferSizeInfo": "控制每个刷新周期内缓冲的最大输出块数量。增大此值可以防止启动服务端时出现「此刻瞬时输出内容过长,已拒绝显示」的警告。默认值:256,范围:16-4096。更改将在下次启动实例时生效。" + "TXT_CODE_daemon_outputBufferSize": "日志缓冲区大小", + "TXT_CODE_daemon_outputBufferSizeInfo": "增大缓冲区可更好的保证终端输出的内容完整性,但内存和性能的压力将会更大,甚至内存泄漏。" } diff --git a/languages/zh_TW.json b/languages/zh_TW.json index 8196066bc..16828c506 100644 --- a/languages/zh_TW.json +++ b/languages/zh_TW.json @@ -3276,6 +3276,6 @@ "TXT_CODE_system_instance_control.illegalName": "錯誤的計畫名,只支援底線,數字,字母和部分本地語言", "TXT_CODE_ui.help": "[終端] 守護程式擁有基本的互動功能,請輸入\"help\"查看更多資訊", "TXT_CODE_version.versionDetectErr": "版本檢查失敗", - "TXT_CODE_instanceConf.outputBufferSize": "輸出緩衝區大小", - "TXT_CODE_instanceConf.outputBufferSizeInfo": "控制每個刷新週期內緩衝的最大輸出塊數量。增大此值可以防止啟動伺服器時出現「瞬間輸出內容太長,已拒絕顯示」的警告。預設值:256,範圍:16-4096。更改將在下次啟動實例時生效。" + "TXT_CODE_daemon_outputBufferSize": "日誌緩衝區大小", + "TXT_CODE_daemon_outputBufferSizeInfo": "增大緩衝區可更好的保證終端輸出的內容完整性,但記憶體和效能的壓力將會更大,甚至記憶體洩漏。" } \ No newline at end of file diff --git a/panel/src/app/routers/instance_operate_router.ts b/panel/src/app/routers/instance_operate_router.ts index 66ed9454e..c5e69dc3a 100755 --- a/panel/src/app/routers/instance_operate_router.ts +++ b/panel/src/app/routers/instance_operate_router.ts @@ -442,8 +442,7 @@ router.put( haveColor: toBoolean(config.terminalOption?.haveColor), pty: toBoolean(config.terminalOption?.pty), ptyWindowCol: toNumber(config.terminalOption?.ptyWindowCol), - ptyWindowRow: toNumber(config.terminalOption?.ptyWindowRow), - outputBufferSize: toNumber(config.terminalOption?.outputBufferSize) + ptyWindowRow: toNumber(config.terminalOption?.ptyWindowRow) }; // extra service From 04cb39590166584291c2ffcf192d37f11dba54bf Mon Sep 17 00:00:00 2001 From: xxtg666 <1747433912@qq.com> Date: Sun, 22 Feb 2026 06:32:32 +0000 Subject: [PATCH 008/256] fix: i18n --- languages/th_TH.json | 4 ++-- languages/tr_TR.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/languages/th_TH.json b/languages/th_TH.json index a23cd40a3..faca512ed 100644 --- a/languages/th_TH.json +++ b/languages/th_TH.json @@ -3276,6 +3276,6 @@ "TXT_CODE_system_instance_control.illegalName": "ชื่องานไม่ถูกต้อง รองรับเฉพาะขีดล่าง ตัวเลข ตัวอักษร และอักขระภาษาท้องถิ่นบางตัวเท่านั้น", "TXT_CODE_ui.help": "[เทอร์มินัล] Daemon มีฟังก์ชันการโต้ตอบพื้นฐาน กรุณาป้อน 'help' สำหรับข้อมูลเพิ่มเติม", "TXT_CODE_version.versionDetectErr": "การตรวจสอบเวอร์ชันล้มเหลว", - "TXT_CODE_daemon_outputBufferSize": "Log Buffer Size", - "TXT_CODE_daemon_outputBufferSizeInfo": "Increasing the buffer can better ensure the completeness of terminal output content, but will put greater pressure on memory and performance, and may even cause memory leaks." + "TXT_CODE_daemon_outputBufferSize": "ขนาดบัฟเฟอร์บันทึก", + "TXT_CODE_daemon_outputBufferSizeInfo": "การเพิ่มขนาดบัฟเฟอร์สามารถรับประกันความสมบูรณ์ของเนื้อหาเอาต์พุตเทอร์มินัลได้ดีขึ้น แต่จะเพิ่มแรงกดดันต่อหน่วยความจำและประสิทธิภาพมากขึ้น และอาจทำให้หน่วยความจำรั่วไหลได้" } \ No newline at end of file diff --git a/languages/tr_TR.json b/languages/tr_TR.json index dbf96c98b..a7700b6a9 100644 --- a/languages/tr_TR.json +++ b/languages/tr_TR.json @@ -3276,6 +3276,6 @@ "TXT_CODE_system_instance_control.illegalName": "Yasadışı görev adı. Yalnızca alt çizgiler, sayılar, harfler ve bazı yerel dil karakterleri desteklenir.", "TXT_CODE_ui.help": "[Terminal] Daemon temel etkileşimli işlevselliğe sahiptir. Daha fazla bilgi için lütfen 'help' girin.", "TXT_CODE_version.versionDetectErr": "Sürüm Kontrolü Başarısız", - "TXT_CODE_daemon_outputBufferSize": "Log Buffer Size", - "TXT_CODE_daemon_outputBufferSizeInfo": "Increasing the buffer can better ensure the completeness of terminal output content, but will put greater pressure on memory and performance, and may even cause memory leaks." + "TXT_CODE_daemon_outputBufferSize": "Günlük Arabellek Boyutu", + "TXT_CODE_daemon_outputBufferSizeInfo": "Arabelleği büyütmek terminal çıktı içeriğinin bütünlüğünü daha iyi sağlayabilir, ancak bellek ve performans üzerindeki baskıyı artırır, hatta bellek sızıntısına neden olabilir." } \ No newline at end of file From 0384f76dd09521129529b17c6786984ade1f45ec Mon Sep 17 00:00:00 2001 From: yumao233 Date: Tue, 24 Feb 2026 21:20:11 +0800 Subject: [PATCH 009/256] feat: optionalDependencies --- common/global.d.ts | 1 + daemon/package-lock.json | 9 ++++++--- daemon/package.json | 6 ++++-- frontend/src/widgets/node/NodeDetailDialog.vue | 5 +---- panel/package-lock.json | 9 ++++++--- panel/package.json | 6 ++++-- 6 files changed, 22 insertions(+), 14 deletions(-) diff --git a/common/global.d.ts b/common/global.d.ts index 8797496e9..73b3c19d4 100644 --- a/common/global.d.ts +++ b/common/global.d.ts @@ -163,6 +163,7 @@ declare global { portRangeEnd: number; portAssignInterval: number; port: number; + outputBufferSize: number; }; dockerPlatforms?: string[]; } diff --git a/daemon/package-lock.json b/daemon/package-lock.json index 8ea164c50..7d529f3e0 100644 --- a/daemon/package-lock.json +++ b/daemon/package-lock.json @@ -1,12 +1,12 @@ { "name": "mcsmanager-daemon", - "version": "4.12.1", + "version": "4.12.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "mcsmanager-daemon", - "version": "4.12.1", + "version": "4.12.2", "license": "Apache-2.0", "dependencies": { "@iarna/toml": "^2.2.5", @@ -23,7 +23,6 @@ "koa-body": "^6.0.1", "koa-send": "^5.0.1", "log4js": "^6.4.0", - "mcsmanager-common": "file:../common", "node-schedule": "^2.0.0", "node-stream-zip": "^1.15.0", "os-utils": "0.0.14", @@ -63,12 +62,16 @@ "webpack": "^5.94.0", "webpack-cli": "^4.10.0", "webpack-node-externals": "^3.0.0" + }, + "optionalDependencies": { + "mcsmanager-common": "file:../common" } }, "../common": { "name": "mcsmanager-common", "version": "1.2.0", "license": "Apache-2.0", + "optional": true, "dependencies": { "@types/fs-extra": "^11.0.4", "@types/node": "^20.9.0", diff --git a/daemon/package.json b/daemon/package.json index 8e34fc58a..2b485eeb4 100644 --- a/daemon/package.json +++ b/daemon/package.json @@ -16,6 +16,9 @@ "_moduleAliases": { "@languages": "../languages" }, + "optionalDependencies": { + "mcsmanager-common": "file:../common" + }, "dependencies": { "@iarna/toml": "^2.2.5", "@koa/router": "^10.0.0", @@ -31,7 +34,6 @@ "koa-body": "^6.0.1", "koa-send": "^5.0.1", "log4js": "^6.4.0", - "mcsmanager-common": "file:../common", "node-schedule": "^2.0.0", "node-stream-zip": "^1.15.0", "os-utils": "0.0.14", @@ -72,4 +74,4 @@ "webpack-cli": "^4.10.0", "webpack-node-externals": "^3.0.0" } -} \ No newline at end of file +} diff --git a/frontend/src/widgets/node/NodeDetailDialog.vue b/frontend/src/widgets/node/NodeDetailDialog.vue index 641fe32e0..f406f0226 100644 --- a/frontend/src/widgets/node/NodeDetailDialog.vue +++ b/frontend/src/widgets/node/NodeDetailDialog.vue @@ -276,10 +276,7 @@ defineExpose({ openDialog }); - + {{ t("TXT_CODE_daemon_outputBufferSizeInfo") }} diff --git a/panel/package-lock.json b/panel/package-lock.json index 7631a2430..d51f1f4da 100644 --- a/panel/package-lock.json +++ b/panel/package-lock.json @@ -1,12 +1,12 @@ { "name": "mcsmanager-panel", - "version": "10.12.2", + "version": "10.12.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "mcsmanager-panel", - "version": "10.12.2", + "version": "10.12.4", "license": "Apache-2.0", "dependencies": { "@koa/router": "^10.0.0", @@ -23,7 +23,6 @@ "koa-session": "^6.2.0", "koa-static": "^5.0.0", "log4js": "^6.4.0", - "mcsmanager-common": "file:../common", "md5": "^2.3.0", "nanoid": "^3.3.8", "node-schedule": "^2.0.0", @@ -57,12 +56,16 @@ "webpack": "^5.94.0", "webpack-cli": "^4.10.0", "webpack-node-externals": "^3.0.0" + }, + "optionalDependencies": { + "mcsmanager-common": "file:../common" } }, "../common": { "name": "mcsmanager-common", "version": "1.2.0", "license": "Apache-2.0", + "optional": true, "dependencies": { "@types/fs-extra": "^11.0.4", "@types/node": "^20.9.0", diff --git a/panel/package.json b/panel/package.json index 238e71922..d490022f0 100644 --- a/panel/package.json +++ b/panel/package.json @@ -17,6 +17,9 @@ "_moduleAliases": { "@languages": "../languages" }, + "optionalDependencies": { + "mcsmanager-common": "file:../common" + }, "dependencies": { "@koa/router": "^10.0.0", "@types/qrcode": "^1.5.5", @@ -32,7 +35,6 @@ "koa-session": "^6.2.0", "koa-static": "^5.0.0", "log4js": "^6.4.0", - "mcsmanager-common": "file:../common", "md5": "^2.3.0", "nanoid": "^3.3.8", "node-schedule": "^2.0.0", @@ -67,4 +69,4 @@ "webpack-cli": "^4.10.0", "webpack-node-externals": "^3.0.0" } -} \ No newline at end of file +} From 7ff62ed540babd85a9dab62a78f16bf80f707f0e Mon Sep 17 00:00:00 2001 From: yumao233 Date: Wed, 25 Feb 2026 15:47:43 +0800 Subject: [PATCH 010/256] feat: replace CardPanel with InstallOptionButton in market widget and update text opacity --- frontend/src/App.vue | 0 frontend/src/assets/base.scss | 0 frontend/src/assets/bg-extend-theme.scss | 0 frontend/src/assets/components/java.png | Bin .../src/assets/daemon_connection_error.png | Bin frontend/src/assets/global.scss | 0 frontend/src/assets/logo.png | Bin frontend/src/assets/tools.scss | 0 frontend/src/assets/variables-dark.scss | 0 frontend/src/assets/variables.scss | 0 frontend/src/components/ActionButton.vue | 0 frontend/src/components/AppConfigProvider.vue | 0 frontend/src/components/AppHeader.vue | 0 frontend/src/components/BetweenMenus.vue | 0 frontend/src/components/CardError.vue | 0 frontend/src/components/CardOperator.vue | 0 frontend/src/components/CardPanel.vue | 0 frontend/src/components/CopyButton.vue | 0 frontend/src/components/DataStatistic.vue | 0 frontend/src/components/Editor.vue | 0 frontend/src/components/Empty.vue | 0 frontend/src/components/FadeUpAnimation.vue | 0 frontend/src/components/IconBtn.vue | 0 frontend/src/components/IframeBox/config.ts | 0 frontend/src/components/IframeBox/handler.ts | 0 frontend/src/components/IframeBox/index.vue | 0 frontend/src/components/IframeModal/index.vue | 0 .../components/IframeModal/useIframeModal.ts | 0 frontend/src/components/InnerCard.vue | 0 .../src/components/InputDialogProvider.vue | 0 .../src/components/InstanceConfigEditor.vue | 0 frontend/src/components/LayoutCard.vue | 0 frontend/src/components/LeftMenuBtn.vue | 0 frontend/src/components/LeftMenusPanel.vue | 0 frontend/src/components/LineOption.vue | 0 frontend/src/components/Loading.vue | 0 frontend/src/components/MyselfInfoDialog.vue | 0 frontend/src/components/NewCardList/index.vue | 0 .../src/components/NewCardList/params.vue | 0 frontend/src/components/NoPreviewCard.vue | 0 .../src/components/NodeRemoteMappingEdit.vue | 0 frontend/src/components/NodeSimpleChart.vue | 0 .../components/OverwriteFilesPopUpContent.vue | 0 frontend/src/components/PlaceHolderCard.vue | 0 .../src/components/ResponsiveLayoutGroup.vue | 0 frontend/src/components/TerminalCore.vue | 0 frontend/src/components/TerminalTags.vue | 0 frontend/src/components/TextContainer.vue | 0 frontend/src/components/UploadBubble.vue | 0 .../src/components/UploadTaskProgress.vue | 0 frontend/src/components/fc/AddJavaDialog.vue | 0 .../fc/CmdAssistantDialog/AnyAppForm.vue | 0 .../CmdAssistantDialog/MinecraftJavaForm.vue | 0 .../fc/CmdAssistantDialog/index.vue | 0 .../components/fc/DockerCapabilityDialog.vue | 0 .../src/components/fc/DockerDeviceDialog.vue | 0 .../src/components/fc/DockerPortDialog.vue | 0 .../src/components/fc/DownloadFileDialog.vue | 0 .../src/components/fc/DownloadJavaDialog.vue | 0 .../src/components/fc/KvOptionsDialog.vue | 0 .../src/components/fc/NodeSelectDialog.vue | 0 frontend/src/components/fc/RenewalDialog.vue | 0 frontend/src/components/fc/RightMenu.vue | 0 .../src/components/fc/SelectInstances.vue | 0 frontend/src/components/fc/TagsDialog.vue | 0 .../src/components/fc/TaskLoadingDialog.vue | 0 .../src/components/fc/UploadFileDialog.vue | 0 frontend/src/components/fc/WarningDialog.vue | 0 frontend/src/components/fc/index.ts | 0 frontend/src/components/interface.ts | 0 frontend/src/components/time/Style1.vue | 0 frontend/src/components/time/Style2.vue | 0 frontend/src/config/const.ts | 0 frontend/src/config/index.ts | 0 frontend/src/config/instanceConfigMap.ts | 0 frontend/src/config/originLayoutConfig.ts | 0 frontend/src/config/router.ts | 0 frontend/src/global.d.ts | 0 frontend/src/hooks/useApi.ts | 0 frontend/src/hooks/useAppRouters.ts | 0 frontend/src/hooks/useCardDragMove.ts | 0 frontend/src/hooks/useCardLayoutComputed.ts | 0 frontend/src/hooks/useCardOperation.ts | 0 frontend/src/hooks/useCardTools.ts | 0 frontend/src/hooks/useCategoryEvents.ts | 0 frontend/src/hooks/useCommandHistory.ts | 0 frontend/src/hooks/useDialog.ts | 0 frontend/src/hooks/useFcIcon.ts | 0 frontend/src/hooks/useFileManager.ts | 0 frontend/src/hooks/useGenerateStartCmd.ts | 0 frontend/src/hooks/useInstance.ts | 0 frontend/src/hooks/useInstanceTag.ts | 0 frontend/src/hooks/useKeyboardEvents.ts | 0 frontend/src/hooks/useMarketPackages.ts | 0 frontend/src/hooks/useMountComponent.ts | 0 frontend/src/hooks/useMouseEnter.ts | 0 frontend/src/hooks/useOperationLog.ts | 0 frontend/src/hooks/useOverviewChart.ts | 0 frontend/src/hooks/useOverviewInfo.ts | 0 frontend/src/hooks/useRemoteNode.ts | 0 frontend/src/hooks/useRightClickMenu.ts | 0 frontend/src/hooks/useRouterParams.ts | 0 frontend/src/hooks/useSchedule.ts | 0 frontend/src/hooks/useScreen.ts | 0 frontend/src/hooks/useServerConfig.ts | 0 frontend/src/hooks/useSocketIo.ts | 0 frontend/src/hooks/useTerminal.ts | 0 frontend/src/hooks/useXhrPollError.ts | 0 frontend/src/hooks/widgets/quickStartFlow.ts | 0 frontend/src/initLib.ts | 0 frontend/src/lang/i18n.ts | 0 frontend/src/main.ts | 0 frontend/src/mount.ts | 0 frontend/src/services/apiService.ts | 0 frontend/src/services/apis/envImage.ts | 0 frontend/src/services/apis/fileManager.ts | 0 frontend/src/services/apis/index.ts | 0 frontend/src/services/apis/instance.ts | 0 frontend/src/services/apis/javaManager.ts | 0 frontend/src/services/apis/layout.ts | 0 frontend/src/services/apis/modManager.ts | 0 frontend/src/services/apis/operationLog.ts | 0 frontend/src/services/apis/redeem.ts | 0 frontend/src/services/apis/user.ts | 0 frontend/src/services/layout.ts | 0 frontend/src/services/overviewService.ts | 0 frontend/src/services/uploadService.ts | 0 frontend/src/stores/useAppConfigStore.ts | 0 frontend/src/stores/useAppStateStore.ts | 0 frontend/src/stores/useAppToolsStore.ts | 0 frontend/src/stores/useCardPool.ts | 0 frontend/src/stores/useDefineApi.ts | 0 frontend/src/stores/useLayoutConfig.ts | 0 .../src/stores/useLayoutContainerStore.ts | 0 frontend/src/tools/array.ts | 0 frontend/src/tools/common.ts | 0 frontend/src/tools/copy.ts | 0 frontend/src/tools/dom.ts | 0 frontend/src/tools/fileManager.ts | 0 frontend/src/tools/fileSize.ts | 0 frontend/src/tools/fileSum.ts | 0 frontend/src/tools/memory.ts | 0 frontend/src/tools/nodes.ts | 0 frontend/src/tools/object.ts | 0 frontend/src/tools/permission.ts | 0 frontend/src/tools/protocol.ts | 0 frontend/src/tools/randId.ts | 0 frontend/src/tools/safe.ts | 0 frontend/src/tools/sandbox.ts | 0 frontend/src/tools/string.ts | 0 frontend/src/tools/throttle.ts | 0 frontend/src/tools/time.ts | 0 frontend/src/tools/validator.ts | 0 frontend/src/tools/version.ts | 0 frontend/src/types/ant.ts | 0 frontend/src/types/const.ts | 0 frontend/src/types/fileManager.ts | 0 frontend/src/types/index.ts | 0 frontend/src/types/javaManager.ts | 0 frontend/src/types/operationLog.ts | 0 frontend/src/types/user.ts | 0 frontend/src/types/vue-i18n.ts | 0 frontend/src/views/Install.vue | 0 frontend/src/views/LayoutContainer.vue | 0 frontend/src/views/Login.vue | 0 frontend/src/widgets/DefaultCard.vue | 0 frontend/src/widgets/EmptyCard.vue | 0 frontend/src/widgets/InstanceChart.vue | 0 frontend/src/widgets/InstanceList.vue | 0 frontend/src/widgets/LoginCard.vue | 0 frontend/src/widgets/NodeList.vue | 0 frontend/src/widgets/NodeOverview.vue | 0 frontend/src/widgets/OperationLogCard.vue | 0 frontend/src/widgets/Page404.vue | 0 frontend/src/widgets/PanelOverview.vue | 0 frontend/src/widgets/QuickStart.vue | 0 frontend/src/widgets/RequestChart.vue | 0 frontend/src/widgets/Settings.vue | 0 frontend/src/widgets/ShelvesCard.vue | 0 frontend/src/widgets/StatusBlock.vue | 0 frontend/src/widgets/TitleCard.vue | 0 frontend/src/widgets/UserInstanceList.vue | 0 frontend/src/widgets/UserList.vue | 0 frontend/src/widgets/UserStatusBlock.vue | 0 .../widgets/imageManager/BuildProgress.vue | 0 .../widgets/imageManager/DockerFileForm.vue | 0 .../src/widgets/imageManager/NewImage.vue | 0 frontend/src/widgets/imageManager/index.vue | 0 frontend/src/widgets/instance/BaseInfo.vue | 0 frontend/src/widgets/instance/FileManager.vue | 0 frontend/src/widgets/instance/ManagerBtns.vue | 0 frontend/src/widgets/instance/ModManager.vue | 0 frontend/src/widgets/instance/Schedule.vue | 0 .../src/widgets/instance/ServerConfigFile.vue | 0 .../widgets/instance/ServerConfigOverview.vue | 0 frontend/src/widgets/instance/Shortcut.vue | 0 frontend/src/widgets/instance/Terminal.vue | 0 .../instance/dialogs/DeleteInstanceDialog.vue | 0 .../widgets/instance/dialogs/DockerInfo.vue | 0 .../widgets/instance/dialogs/EventConfig.vue | 0 .../widgets/instance/dialogs/FileEditor.vue | 0 .../widgets/instance/dialogs/ImageViewer.vue | 0 .../instance/dialogs/InstanceDetail.vue | 0 .../dialogs/InstanceFundamentalDetail.vue | 0 .../widgets/instance/dialogs/JavaManager.vue | 0 .../widgets/instance/dialogs/MarketDialog.vue | 0 .../instance/dialogs/McPingSettings.vue | 0 .../widgets/instance/dialogs/NewSchedule.vue | 0 .../widgets/instance/dialogs/PingConfig.vue | 0 .../widgets/instance/dialogs/RconSettings.vue | 0 .../instance/dialogs/SelectUnzipCode.vue | 0 .../instance/dialogs/TemplateNameDialog.vue | 0 .../widgets/instance/dialogs/TermConfig.vue | 0 .../instance/mod-manager/LocalModTable.vue | 0 .../instance/mod-manager/ModConfigModal.vue | 0 .../instance/mod-manager/ModFloatingTools.vue | 0 .../instance/mod-manager/ModVersionModal.vue | 0 .../instance/mod-manager/SearchModTable.vue | 0 .../instance/mod-manager/useDeferredTasks.ts | 0 .../instance/mod-manager/useLocalMods.ts | 0 .../instance/mod-manager/useModConfig.ts | 0 .../instance/mod-manager/useModSearch.ts | 0 .../instance/mod-manager/useModUpload.ts | 0 .../widgets/market/InstallOptionButton.vue | 139 ++++++++++++++++++ frontend/src/widgets/market/editor.vue | 0 frontend/src/widgets/market/index.vue | 85 +---------- .../src/widgets/node/NodeDetailDialog.vue | 0 frontend/src/widgets/node/NodeItem.vue | 0 frontend/src/widgets/others/Carousel.vue | 0 frontend/src/widgets/others/ClockCard.vue | 0 frontend/src/widgets/others/IframeCard.vue | 0 frontend/src/widgets/others/ImageBox.vue | 0 frontend/src/widgets/others/LinkCard.vue | 0 frontend/src/widgets/others/MusicCard.vue | 0 frontend/src/widgets/others/PluginCard.vue | 0 frontend/src/widgets/others/TextCard.vue | 0 frontend/src/widgets/setupApp/AppPackages.vue | 2 +- .../widgets/setupApp/CreateInstanceForm.vue | 0 frontend/src/widgets/setupApp/McPreset.vue | 0 .../src/widgets/setupApp/QuickStartFlow.vue | 0 frontend/src/widgets/user/AccessSettings.vue | 0 languages/zh_CN.json | 2 +- 242 files changed, 144 insertions(+), 84 deletions(-) mode change 100644 => 100755 frontend/src/App.vue mode change 100644 => 100755 frontend/src/assets/base.scss mode change 100644 => 100755 frontend/src/assets/bg-extend-theme.scss mode change 100644 => 100755 frontend/src/assets/components/java.png mode change 100644 => 100755 frontend/src/assets/daemon_connection_error.png mode change 100644 => 100755 frontend/src/assets/global.scss mode change 100644 => 100755 frontend/src/assets/logo.png mode change 100644 => 100755 frontend/src/assets/tools.scss mode change 100644 => 100755 frontend/src/assets/variables-dark.scss mode change 100644 => 100755 frontend/src/assets/variables.scss mode change 100644 => 100755 frontend/src/components/ActionButton.vue mode change 100644 => 100755 frontend/src/components/AppConfigProvider.vue mode change 100644 => 100755 frontend/src/components/AppHeader.vue mode change 100644 => 100755 frontend/src/components/BetweenMenus.vue mode change 100644 => 100755 frontend/src/components/CardError.vue mode change 100644 => 100755 frontend/src/components/CardOperator.vue mode change 100644 => 100755 frontend/src/components/CardPanel.vue mode change 100644 => 100755 frontend/src/components/CopyButton.vue mode change 100644 => 100755 frontend/src/components/DataStatistic.vue mode change 100644 => 100755 frontend/src/components/Editor.vue mode change 100644 => 100755 frontend/src/components/Empty.vue mode change 100644 => 100755 frontend/src/components/FadeUpAnimation.vue mode change 100644 => 100755 frontend/src/components/IconBtn.vue mode change 100644 => 100755 frontend/src/components/IframeBox/config.ts mode change 100644 => 100755 frontend/src/components/IframeBox/handler.ts mode change 100644 => 100755 frontend/src/components/IframeBox/index.vue mode change 100644 => 100755 frontend/src/components/IframeModal/index.vue mode change 100644 => 100755 frontend/src/components/IframeModal/useIframeModal.ts mode change 100644 => 100755 frontend/src/components/InnerCard.vue mode change 100644 => 100755 frontend/src/components/InputDialogProvider.vue mode change 100644 => 100755 frontend/src/components/InstanceConfigEditor.vue mode change 100644 => 100755 frontend/src/components/LayoutCard.vue mode change 100644 => 100755 frontend/src/components/LeftMenuBtn.vue mode change 100644 => 100755 frontend/src/components/LeftMenusPanel.vue mode change 100644 => 100755 frontend/src/components/LineOption.vue mode change 100644 => 100755 frontend/src/components/Loading.vue mode change 100644 => 100755 frontend/src/components/MyselfInfoDialog.vue mode change 100644 => 100755 frontend/src/components/NewCardList/index.vue mode change 100644 => 100755 frontend/src/components/NewCardList/params.vue mode change 100644 => 100755 frontend/src/components/NoPreviewCard.vue mode change 100644 => 100755 frontend/src/components/NodeRemoteMappingEdit.vue mode change 100644 => 100755 frontend/src/components/NodeSimpleChart.vue mode change 100644 => 100755 frontend/src/components/OverwriteFilesPopUpContent.vue mode change 100644 => 100755 frontend/src/components/PlaceHolderCard.vue mode change 100644 => 100755 frontend/src/components/ResponsiveLayoutGroup.vue mode change 100644 => 100755 frontend/src/components/TerminalCore.vue mode change 100644 => 100755 frontend/src/components/TerminalTags.vue mode change 100644 => 100755 frontend/src/components/TextContainer.vue mode change 100644 => 100755 frontend/src/components/UploadBubble.vue mode change 100644 => 100755 frontend/src/components/UploadTaskProgress.vue mode change 100644 => 100755 frontend/src/components/fc/AddJavaDialog.vue mode change 100644 => 100755 frontend/src/components/fc/CmdAssistantDialog/AnyAppForm.vue mode change 100644 => 100755 frontend/src/components/fc/CmdAssistantDialog/MinecraftJavaForm.vue mode change 100644 => 100755 frontend/src/components/fc/CmdAssistantDialog/index.vue mode change 100644 => 100755 frontend/src/components/fc/DockerCapabilityDialog.vue mode change 100644 => 100755 frontend/src/components/fc/DockerDeviceDialog.vue mode change 100644 => 100755 frontend/src/components/fc/DockerPortDialog.vue mode change 100644 => 100755 frontend/src/components/fc/DownloadFileDialog.vue mode change 100644 => 100755 frontend/src/components/fc/DownloadJavaDialog.vue mode change 100644 => 100755 frontend/src/components/fc/KvOptionsDialog.vue mode change 100644 => 100755 frontend/src/components/fc/NodeSelectDialog.vue mode change 100644 => 100755 frontend/src/components/fc/RenewalDialog.vue mode change 100644 => 100755 frontend/src/components/fc/RightMenu.vue mode change 100644 => 100755 frontend/src/components/fc/SelectInstances.vue mode change 100644 => 100755 frontend/src/components/fc/TagsDialog.vue mode change 100644 => 100755 frontend/src/components/fc/TaskLoadingDialog.vue mode change 100644 => 100755 frontend/src/components/fc/UploadFileDialog.vue mode change 100644 => 100755 frontend/src/components/fc/WarningDialog.vue mode change 100644 => 100755 frontend/src/components/fc/index.ts mode change 100644 => 100755 frontend/src/components/interface.ts mode change 100644 => 100755 frontend/src/components/time/Style1.vue mode change 100644 => 100755 frontend/src/components/time/Style2.vue mode change 100644 => 100755 frontend/src/config/const.ts mode change 100644 => 100755 frontend/src/config/index.ts mode change 100644 => 100755 frontend/src/config/instanceConfigMap.ts mode change 100644 => 100755 frontend/src/config/originLayoutConfig.ts mode change 100644 => 100755 frontend/src/config/router.ts mode change 100644 => 100755 frontend/src/global.d.ts mode change 100644 => 100755 frontend/src/hooks/useApi.ts mode change 100644 => 100755 frontend/src/hooks/useAppRouters.ts mode change 100644 => 100755 frontend/src/hooks/useCardDragMove.ts mode change 100644 => 100755 frontend/src/hooks/useCardLayoutComputed.ts mode change 100644 => 100755 frontend/src/hooks/useCardOperation.ts mode change 100644 => 100755 frontend/src/hooks/useCardTools.ts mode change 100644 => 100755 frontend/src/hooks/useCategoryEvents.ts mode change 100644 => 100755 frontend/src/hooks/useCommandHistory.ts mode change 100644 => 100755 frontend/src/hooks/useDialog.ts mode change 100644 => 100755 frontend/src/hooks/useFcIcon.ts mode change 100644 => 100755 frontend/src/hooks/useFileManager.ts mode change 100644 => 100755 frontend/src/hooks/useGenerateStartCmd.ts mode change 100644 => 100755 frontend/src/hooks/useInstance.ts mode change 100644 => 100755 frontend/src/hooks/useInstanceTag.ts mode change 100644 => 100755 frontend/src/hooks/useKeyboardEvents.ts mode change 100644 => 100755 frontend/src/hooks/useMarketPackages.ts mode change 100644 => 100755 frontend/src/hooks/useMountComponent.ts mode change 100644 => 100755 frontend/src/hooks/useMouseEnter.ts mode change 100644 => 100755 frontend/src/hooks/useOperationLog.ts mode change 100644 => 100755 frontend/src/hooks/useOverviewChart.ts mode change 100644 => 100755 frontend/src/hooks/useOverviewInfo.ts mode change 100644 => 100755 frontend/src/hooks/useRemoteNode.ts mode change 100644 => 100755 frontend/src/hooks/useRightClickMenu.ts mode change 100644 => 100755 frontend/src/hooks/useRouterParams.ts mode change 100644 => 100755 frontend/src/hooks/useSchedule.ts mode change 100644 => 100755 frontend/src/hooks/useScreen.ts mode change 100644 => 100755 frontend/src/hooks/useServerConfig.ts mode change 100644 => 100755 frontend/src/hooks/useSocketIo.ts mode change 100644 => 100755 frontend/src/hooks/useTerminal.ts mode change 100644 => 100755 frontend/src/hooks/useXhrPollError.ts mode change 100644 => 100755 frontend/src/hooks/widgets/quickStartFlow.ts mode change 100644 => 100755 frontend/src/initLib.ts mode change 100644 => 100755 frontend/src/lang/i18n.ts mode change 100644 => 100755 frontend/src/main.ts mode change 100644 => 100755 frontend/src/mount.ts mode change 100644 => 100755 frontend/src/services/apiService.ts mode change 100644 => 100755 frontend/src/services/apis/envImage.ts mode change 100644 => 100755 frontend/src/services/apis/fileManager.ts mode change 100644 => 100755 frontend/src/services/apis/index.ts mode change 100644 => 100755 frontend/src/services/apis/instance.ts mode change 100644 => 100755 frontend/src/services/apis/javaManager.ts mode change 100644 => 100755 frontend/src/services/apis/layout.ts mode change 100644 => 100755 frontend/src/services/apis/modManager.ts mode change 100644 => 100755 frontend/src/services/apis/operationLog.ts mode change 100644 => 100755 frontend/src/services/apis/redeem.ts mode change 100644 => 100755 frontend/src/services/apis/user.ts mode change 100644 => 100755 frontend/src/services/layout.ts mode change 100644 => 100755 frontend/src/services/overviewService.ts mode change 100644 => 100755 frontend/src/services/uploadService.ts mode change 100644 => 100755 frontend/src/stores/useAppConfigStore.ts mode change 100644 => 100755 frontend/src/stores/useAppStateStore.ts mode change 100644 => 100755 frontend/src/stores/useAppToolsStore.ts mode change 100644 => 100755 frontend/src/stores/useCardPool.ts mode change 100644 => 100755 frontend/src/stores/useDefineApi.ts mode change 100644 => 100755 frontend/src/stores/useLayoutConfig.ts mode change 100644 => 100755 frontend/src/stores/useLayoutContainerStore.ts mode change 100644 => 100755 frontend/src/tools/array.ts mode change 100644 => 100755 frontend/src/tools/common.ts mode change 100644 => 100755 frontend/src/tools/copy.ts mode change 100644 => 100755 frontend/src/tools/dom.ts mode change 100644 => 100755 frontend/src/tools/fileManager.ts mode change 100644 => 100755 frontend/src/tools/fileSize.ts mode change 100644 => 100755 frontend/src/tools/fileSum.ts mode change 100644 => 100755 frontend/src/tools/memory.ts mode change 100644 => 100755 frontend/src/tools/nodes.ts mode change 100644 => 100755 frontend/src/tools/object.ts mode change 100644 => 100755 frontend/src/tools/permission.ts mode change 100644 => 100755 frontend/src/tools/protocol.ts mode change 100644 => 100755 frontend/src/tools/randId.ts mode change 100644 => 100755 frontend/src/tools/safe.ts mode change 100644 => 100755 frontend/src/tools/sandbox.ts mode change 100644 => 100755 frontend/src/tools/string.ts mode change 100644 => 100755 frontend/src/tools/throttle.ts mode change 100644 => 100755 frontend/src/tools/time.ts mode change 100644 => 100755 frontend/src/tools/validator.ts mode change 100644 => 100755 frontend/src/tools/version.ts mode change 100644 => 100755 frontend/src/types/ant.ts mode change 100644 => 100755 frontend/src/types/const.ts mode change 100644 => 100755 frontend/src/types/fileManager.ts mode change 100644 => 100755 frontend/src/types/index.ts mode change 100644 => 100755 frontend/src/types/javaManager.ts mode change 100644 => 100755 frontend/src/types/operationLog.ts mode change 100644 => 100755 frontend/src/types/user.ts mode change 100644 => 100755 frontend/src/types/vue-i18n.ts mode change 100644 => 100755 frontend/src/views/Install.vue mode change 100644 => 100755 frontend/src/views/LayoutContainer.vue mode change 100644 => 100755 frontend/src/views/Login.vue mode change 100644 => 100755 frontend/src/widgets/DefaultCard.vue mode change 100644 => 100755 frontend/src/widgets/EmptyCard.vue mode change 100644 => 100755 frontend/src/widgets/InstanceChart.vue mode change 100644 => 100755 frontend/src/widgets/InstanceList.vue mode change 100644 => 100755 frontend/src/widgets/LoginCard.vue mode change 100644 => 100755 frontend/src/widgets/NodeList.vue mode change 100644 => 100755 frontend/src/widgets/NodeOverview.vue mode change 100644 => 100755 frontend/src/widgets/OperationLogCard.vue mode change 100644 => 100755 frontend/src/widgets/Page404.vue mode change 100644 => 100755 frontend/src/widgets/PanelOverview.vue mode change 100644 => 100755 frontend/src/widgets/QuickStart.vue mode change 100644 => 100755 frontend/src/widgets/RequestChart.vue mode change 100644 => 100755 frontend/src/widgets/Settings.vue mode change 100644 => 100755 frontend/src/widgets/ShelvesCard.vue mode change 100644 => 100755 frontend/src/widgets/StatusBlock.vue mode change 100644 => 100755 frontend/src/widgets/TitleCard.vue mode change 100644 => 100755 frontend/src/widgets/UserInstanceList.vue mode change 100644 => 100755 frontend/src/widgets/UserList.vue mode change 100644 => 100755 frontend/src/widgets/UserStatusBlock.vue mode change 100644 => 100755 frontend/src/widgets/imageManager/BuildProgress.vue mode change 100644 => 100755 frontend/src/widgets/imageManager/DockerFileForm.vue mode change 100644 => 100755 frontend/src/widgets/imageManager/NewImage.vue mode change 100644 => 100755 frontend/src/widgets/imageManager/index.vue mode change 100644 => 100755 frontend/src/widgets/instance/BaseInfo.vue mode change 100644 => 100755 frontend/src/widgets/instance/FileManager.vue mode change 100644 => 100755 frontend/src/widgets/instance/ManagerBtns.vue mode change 100644 => 100755 frontend/src/widgets/instance/ModManager.vue mode change 100644 => 100755 frontend/src/widgets/instance/Schedule.vue mode change 100644 => 100755 frontend/src/widgets/instance/ServerConfigFile.vue mode change 100644 => 100755 frontend/src/widgets/instance/ServerConfigOverview.vue mode change 100644 => 100755 frontend/src/widgets/instance/Shortcut.vue mode change 100644 => 100755 frontend/src/widgets/instance/Terminal.vue mode change 100644 => 100755 frontend/src/widgets/instance/dialogs/DeleteInstanceDialog.vue mode change 100644 => 100755 frontend/src/widgets/instance/dialogs/DockerInfo.vue mode change 100644 => 100755 frontend/src/widgets/instance/dialogs/EventConfig.vue mode change 100644 => 100755 frontend/src/widgets/instance/dialogs/FileEditor.vue mode change 100644 => 100755 frontend/src/widgets/instance/dialogs/ImageViewer.vue mode change 100644 => 100755 frontend/src/widgets/instance/dialogs/InstanceDetail.vue mode change 100644 => 100755 frontend/src/widgets/instance/dialogs/InstanceFundamentalDetail.vue mode change 100644 => 100755 frontend/src/widgets/instance/dialogs/JavaManager.vue mode change 100644 => 100755 frontend/src/widgets/instance/dialogs/MarketDialog.vue mode change 100644 => 100755 frontend/src/widgets/instance/dialogs/McPingSettings.vue mode change 100644 => 100755 frontend/src/widgets/instance/dialogs/NewSchedule.vue mode change 100644 => 100755 frontend/src/widgets/instance/dialogs/PingConfig.vue mode change 100644 => 100755 frontend/src/widgets/instance/dialogs/RconSettings.vue mode change 100644 => 100755 frontend/src/widgets/instance/dialogs/SelectUnzipCode.vue mode change 100644 => 100755 frontend/src/widgets/instance/dialogs/TemplateNameDialog.vue mode change 100644 => 100755 frontend/src/widgets/instance/dialogs/TermConfig.vue mode change 100644 => 100755 frontend/src/widgets/instance/mod-manager/LocalModTable.vue mode change 100644 => 100755 frontend/src/widgets/instance/mod-manager/ModConfigModal.vue mode change 100644 => 100755 frontend/src/widgets/instance/mod-manager/ModFloatingTools.vue mode change 100644 => 100755 frontend/src/widgets/instance/mod-manager/ModVersionModal.vue mode change 100644 => 100755 frontend/src/widgets/instance/mod-manager/SearchModTable.vue mode change 100644 => 100755 frontend/src/widgets/instance/mod-manager/useDeferredTasks.ts mode change 100644 => 100755 frontend/src/widgets/instance/mod-manager/useLocalMods.ts mode change 100644 => 100755 frontend/src/widgets/instance/mod-manager/useModConfig.ts mode change 100644 => 100755 frontend/src/widgets/instance/mod-manager/useModSearch.ts mode change 100644 => 100755 frontend/src/widgets/instance/mod-manager/useModUpload.ts create mode 100755 frontend/src/widgets/market/InstallOptionButton.vue mode change 100644 => 100755 frontend/src/widgets/market/editor.vue mode change 100644 => 100755 frontend/src/widgets/market/index.vue mode change 100644 => 100755 frontend/src/widgets/node/NodeDetailDialog.vue mode change 100644 => 100755 frontend/src/widgets/node/NodeItem.vue mode change 100644 => 100755 frontend/src/widgets/others/Carousel.vue mode change 100644 => 100755 frontend/src/widgets/others/ClockCard.vue mode change 100644 => 100755 frontend/src/widgets/others/IframeCard.vue mode change 100644 => 100755 frontend/src/widgets/others/ImageBox.vue mode change 100644 => 100755 frontend/src/widgets/others/LinkCard.vue mode change 100644 => 100755 frontend/src/widgets/others/MusicCard.vue mode change 100644 => 100755 frontend/src/widgets/others/PluginCard.vue mode change 100644 => 100755 frontend/src/widgets/others/TextCard.vue mode change 100644 => 100755 frontend/src/widgets/setupApp/AppPackages.vue mode change 100644 => 100755 frontend/src/widgets/setupApp/CreateInstanceForm.vue mode change 100644 => 100755 frontend/src/widgets/setupApp/McPreset.vue mode change 100644 => 100755 frontend/src/widgets/setupApp/QuickStartFlow.vue mode change 100644 => 100755 frontend/src/widgets/user/AccessSettings.vue diff --git a/frontend/src/App.vue b/frontend/src/App.vue old mode 100644 new mode 100755 diff --git a/frontend/src/assets/base.scss b/frontend/src/assets/base.scss old mode 100644 new mode 100755 diff --git a/frontend/src/assets/bg-extend-theme.scss b/frontend/src/assets/bg-extend-theme.scss old mode 100644 new mode 100755 diff --git a/frontend/src/assets/components/java.png b/frontend/src/assets/components/java.png old mode 100644 new mode 100755 diff --git a/frontend/src/assets/daemon_connection_error.png b/frontend/src/assets/daemon_connection_error.png old mode 100644 new mode 100755 diff --git a/frontend/src/assets/global.scss b/frontend/src/assets/global.scss old mode 100644 new mode 100755 diff --git a/frontend/src/assets/logo.png b/frontend/src/assets/logo.png old mode 100644 new mode 100755 diff --git a/frontend/src/assets/tools.scss b/frontend/src/assets/tools.scss old mode 100644 new mode 100755 diff --git a/frontend/src/assets/variables-dark.scss b/frontend/src/assets/variables-dark.scss old mode 100644 new mode 100755 diff --git a/frontend/src/assets/variables.scss b/frontend/src/assets/variables.scss old mode 100644 new mode 100755 diff --git a/frontend/src/components/ActionButton.vue b/frontend/src/components/ActionButton.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/AppConfigProvider.vue b/frontend/src/components/AppConfigProvider.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/AppHeader.vue b/frontend/src/components/AppHeader.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/BetweenMenus.vue b/frontend/src/components/BetweenMenus.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/CardError.vue b/frontend/src/components/CardError.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/CardOperator.vue b/frontend/src/components/CardOperator.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/CardPanel.vue b/frontend/src/components/CardPanel.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/CopyButton.vue b/frontend/src/components/CopyButton.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/DataStatistic.vue b/frontend/src/components/DataStatistic.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/Editor.vue b/frontend/src/components/Editor.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/Empty.vue b/frontend/src/components/Empty.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/FadeUpAnimation.vue b/frontend/src/components/FadeUpAnimation.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/IconBtn.vue b/frontend/src/components/IconBtn.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/IframeBox/config.ts b/frontend/src/components/IframeBox/config.ts old mode 100644 new mode 100755 diff --git a/frontend/src/components/IframeBox/handler.ts b/frontend/src/components/IframeBox/handler.ts old mode 100644 new mode 100755 diff --git a/frontend/src/components/IframeBox/index.vue b/frontend/src/components/IframeBox/index.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/IframeModal/index.vue b/frontend/src/components/IframeModal/index.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/IframeModal/useIframeModal.ts b/frontend/src/components/IframeModal/useIframeModal.ts old mode 100644 new mode 100755 diff --git a/frontend/src/components/InnerCard.vue b/frontend/src/components/InnerCard.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/InputDialogProvider.vue b/frontend/src/components/InputDialogProvider.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/InstanceConfigEditor.vue b/frontend/src/components/InstanceConfigEditor.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/LayoutCard.vue b/frontend/src/components/LayoutCard.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/LeftMenuBtn.vue b/frontend/src/components/LeftMenuBtn.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/LeftMenusPanel.vue b/frontend/src/components/LeftMenusPanel.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/LineOption.vue b/frontend/src/components/LineOption.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/Loading.vue b/frontend/src/components/Loading.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/MyselfInfoDialog.vue b/frontend/src/components/MyselfInfoDialog.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/NewCardList/index.vue b/frontend/src/components/NewCardList/index.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/NewCardList/params.vue b/frontend/src/components/NewCardList/params.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/NoPreviewCard.vue b/frontend/src/components/NoPreviewCard.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/NodeRemoteMappingEdit.vue b/frontend/src/components/NodeRemoteMappingEdit.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/NodeSimpleChart.vue b/frontend/src/components/NodeSimpleChart.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/OverwriteFilesPopUpContent.vue b/frontend/src/components/OverwriteFilesPopUpContent.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/PlaceHolderCard.vue b/frontend/src/components/PlaceHolderCard.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/ResponsiveLayoutGroup.vue b/frontend/src/components/ResponsiveLayoutGroup.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/TerminalCore.vue b/frontend/src/components/TerminalCore.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/TerminalTags.vue b/frontend/src/components/TerminalTags.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/TextContainer.vue b/frontend/src/components/TextContainer.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/UploadBubble.vue b/frontend/src/components/UploadBubble.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/UploadTaskProgress.vue b/frontend/src/components/UploadTaskProgress.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/fc/AddJavaDialog.vue b/frontend/src/components/fc/AddJavaDialog.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/fc/CmdAssistantDialog/AnyAppForm.vue b/frontend/src/components/fc/CmdAssistantDialog/AnyAppForm.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/fc/CmdAssistantDialog/MinecraftJavaForm.vue b/frontend/src/components/fc/CmdAssistantDialog/MinecraftJavaForm.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/fc/CmdAssistantDialog/index.vue b/frontend/src/components/fc/CmdAssistantDialog/index.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/fc/DockerCapabilityDialog.vue b/frontend/src/components/fc/DockerCapabilityDialog.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/fc/DockerDeviceDialog.vue b/frontend/src/components/fc/DockerDeviceDialog.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/fc/DockerPortDialog.vue b/frontend/src/components/fc/DockerPortDialog.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/fc/DownloadFileDialog.vue b/frontend/src/components/fc/DownloadFileDialog.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/fc/DownloadJavaDialog.vue b/frontend/src/components/fc/DownloadJavaDialog.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/fc/KvOptionsDialog.vue b/frontend/src/components/fc/KvOptionsDialog.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/fc/NodeSelectDialog.vue b/frontend/src/components/fc/NodeSelectDialog.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/fc/RenewalDialog.vue b/frontend/src/components/fc/RenewalDialog.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/fc/RightMenu.vue b/frontend/src/components/fc/RightMenu.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/fc/SelectInstances.vue b/frontend/src/components/fc/SelectInstances.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/fc/TagsDialog.vue b/frontend/src/components/fc/TagsDialog.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/fc/TaskLoadingDialog.vue b/frontend/src/components/fc/TaskLoadingDialog.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/fc/UploadFileDialog.vue b/frontend/src/components/fc/UploadFileDialog.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/fc/WarningDialog.vue b/frontend/src/components/fc/WarningDialog.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/fc/index.ts b/frontend/src/components/fc/index.ts old mode 100644 new mode 100755 diff --git a/frontend/src/components/interface.ts b/frontend/src/components/interface.ts old mode 100644 new mode 100755 diff --git a/frontend/src/components/time/Style1.vue b/frontend/src/components/time/Style1.vue old mode 100644 new mode 100755 diff --git a/frontend/src/components/time/Style2.vue b/frontend/src/components/time/Style2.vue old mode 100644 new mode 100755 diff --git a/frontend/src/config/const.ts b/frontend/src/config/const.ts old mode 100644 new mode 100755 diff --git a/frontend/src/config/index.ts b/frontend/src/config/index.ts old mode 100644 new mode 100755 diff --git a/frontend/src/config/instanceConfigMap.ts b/frontend/src/config/instanceConfigMap.ts old mode 100644 new mode 100755 diff --git a/frontend/src/config/originLayoutConfig.ts b/frontend/src/config/originLayoutConfig.ts old mode 100644 new mode 100755 diff --git a/frontend/src/config/router.ts b/frontend/src/config/router.ts old mode 100644 new mode 100755 diff --git a/frontend/src/global.d.ts b/frontend/src/global.d.ts old mode 100644 new mode 100755 diff --git a/frontend/src/hooks/useApi.ts b/frontend/src/hooks/useApi.ts old mode 100644 new mode 100755 diff --git a/frontend/src/hooks/useAppRouters.ts b/frontend/src/hooks/useAppRouters.ts old mode 100644 new mode 100755 diff --git a/frontend/src/hooks/useCardDragMove.ts b/frontend/src/hooks/useCardDragMove.ts old mode 100644 new mode 100755 diff --git a/frontend/src/hooks/useCardLayoutComputed.ts b/frontend/src/hooks/useCardLayoutComputed.ts old mode 100644 new mode 100755 diff --git a/frontend/src/hooks/useCardOperation.ts b/frontend/src/hooks/useCardOperation.ts old mode 100644 new mode 100755 diff --git a/frontend/src/hooks/useCardTools.ts b/frontend/src/hooks/useCardTools.ts old mode 100644 new mode 100755 diff --git a/frontend/src/hooks/useCategoryEvents.ts b/frontend/src/hooks/useCategoryEvents.ts old mode 100644 new mode 100755 diff --git a/frontend/src/hooks/useCommandHistory.ts b/frontend/src/hooks/useCommandHistory.ts old mode 100644 new mode 100755 diff --git a/frontend/src/hooks/useDialog.ts b/frontend/src/hooks/useDialog.ts old mode 100644 new mode 100755 diff --git a/frontend/src/hooks/useFcIcon.ts b/frontend/src/hooks/useFcIcon.ts old mode 100644 new mode 100755 diff --git a/frontend/src/hooks/useFileManager.ts b/frontend/src/hooks/useFileManager.ts old mode 100644 new mode 100755 diff --git a/frontend/src/hooks/useGenerateStartCmd.ts b/frontend/src/hooks/useGenerateStartCmd.ts old mode 100644 new mode 100755 diff --git a/frontend/src/hooks/useInstance.ts b/frontend/src/hooks/useInstance.ts old mode 100644 new mode 100755 diff --git a/frontend/src/hooks/useInstanceTag.ts b/frontend/src/hooks/useInstanceTag.ts old mode 100644 new mode 100755 diff --git a/frontend/src/hooks/useKeyboardEvents.ts b/frontend/src/hooks/useKeyboardEvents.ts old mode 100644 new mode 100755 diff --git a/frontend/src/hooks/useMarketPackages.ts b/frontend/src/hooks/useMarketPackages.ts old mode 100644 new mode 100755 diff --git a/frontend/src/hooks/useMountComponent.ts b/frontend/src/hooks/useMountComponent.ts old mode 100644 new mode 100755 diff --git a/frontend/src/hooks/useMouseEnter.ts b/frontend/src/hooks/useMouseEnter.ts old mode 100644 new mode 100755 diff --git a/frontend/src/hooks/useOperationLog.ts b/frontend/src/hooks/useOperationLog.ts old mode 100644 new mode 100755 diff --git a/frontend/src/hooks/useOverviewChart.ts b/frontend/src/hooks/useOverviewChart.ts old mode 100644 new mode 100755 diff --git a/frontend/src/hooks/useOverviewInfo.ts b/frontend/src/hooks/useOverviewInfo.ts old mode 100644 new mode 100755 diff --git a/frontend/src/hooks/useRemoteNode.ts b/frontend/src/hooks/useRemoteNode.ts old mode 100644 new mode 100755 diff --git a/frontend/src/hooks/useRightClickMenu.ts b/frontend/src/hooks/useRightClickMenu.ts old mode 100644 new mode 100755 diff --git a/frontend/src/hooks/useRouterParams.ts b/frontend/src/hooks/useRouterParams.ts old mode 100644 new mode 100755 diff --git a/frontend/src/hooks/useSchedule.ts b/frontend/src/hooks/useSchedule.ts old mode 100644 new mode 100755 diff --git a/frontend/src/hooks/useScreen.ts b/frontend/src/hooks/useScreen.ts old mode 100644 new mode 100755 diff --git a/frontend/src/hooks/useServerConfig.ts b/frontend/src/hooks/useServerConfig.ts old mode 100644 new mode 100755 diff --git a/frontend/src/hooks/useSocketIo.ts b/frontend/src/hooks/useSocketIo.ts old mode 100644 new mode 100755 diff --git a/frontend/src/hooks/useTerminal.ts b/frontend/src/hooks/useTerminal.ts old mode 100644 new mode 100755 diff --git a/frontend/src/hooks/useXhrPollError.ts b/frontend/src/hooks/useXhrPollError.ts old mode 100644 new mode 100755 diff --git a/frontend/src/hooks/widgets/quickStartFlow.ts b/frontend/src/hooks/widgets/quickStartFlow.ts old mode 100644 new mode 100755 diff --git a/frontend/src/initLib.ts b/frontend/src/initLib.ts old mode 100644 new mode 100755 diff --git a/frontend/src/lang/i18n.ts b/frontend/src/lang/i18n.ts old mode 100644 new mode 100755 diff --git a/frontend/src/main.ts b/frontend/src/main.ts old mode 100644 new mode 100755 diff --git a/frontend/src/mount.ts b/frontend/src/mount.ts old mode 100644 new mode 100755 diff --git a/frontend/src/services/apiService.ts b/frontend/src/services/apiService.ts old mode 100644 new mode 100755 diff --git a/frontend/src/services/apis/envImage.ts b/frontend/src/services/apis/envImage.ts old mode 100644 new mode 100755 diff --git a/frontend/src/services/apis/fileManager.ts b/frontend/src/services/apis/fileManager.ts old mode 100644 new mode 100755 diff --git a/frontend/src/services/apis/index.ts b/frontend/src/services/apis/index.ts old mode 100644 new mode 100755 diff --git a/frontend/src/services/apis/instance.ts b/frontend/src/services/apis/instance.ts old mode 100644 new mode 100755 diff --git a/frontend/src/services/apis/javaManager.ts b/frontend/src/services/apis/javaManager.ts old mode 100644 new mode 100755 diff --git a/frontend/src/services/apis/layout.ts b/frontend/src/services/apis/layout.ts old mode 100644 new mode 100755 diff --git a/frontend/src/services/apis/modManager.ts b/frontend/src/services/apis/modManager.ts old mode 100644 new mode 100755 diff --git a/frontend/src/services/apis/operationLog.ts b/frontend/src/services/apis/operationLog.ts old mode 100644 new mode 100755 diff --git a/frontend/src/services/apis/redeem.ts b/frontend/src/services/apis/redeem.ts old mode 100644 new mode 100755 diff --git a/frontend/src/services/apis/user.ts b/frontend/src/services/apis/user.ts old mode 100644 new mode 100755 diff --git a/frontend/src/services/layout.ts b/frontend/src/services/layout.ts old mode 100644 new mode 100755 diff --git a/frontend/src/services/overviewService.ts b/frontend/src/services/overviewService.ts old mode 100644 new mode 100755 diff --git a/frontend/src/services/uploadService.ts b/frontend/src/services/uploadService.ts old mode 100644 new mode 100755 diff --git a/frontend/src/stores/useAppConfigStore.ts b/frontend/src/stores/useAppConfigStore.ts old mode 100644 new mode 100755 diff --git a/frontend/src/stores/useAppStateStore.ts b/frontend/src/stores/useAppStateStore.ts old mode 100644 new mode 100755 diff --git a/frontend/src/stores/useAppToolsStore.ts b/frontend/src/stores/useAppToolsStore.ts old mode 100644 new mode 100755 diff --git a/frontend/src/stores/useCardPool.ts b/frontend/src/stores/useCardPool.ts old mode 100644 new mode 100755 diff --git a/frontend/src/stores/useDefineApi.ts b/frontend/src/stores/useDefineApi.ts old mode 100644 new mode 100755 diff --git a/frontend/src/stores/useLayoutConfig.ts b/frontend/src/stores/useLayoutConfig.ts old mode 100644 new mode 100755 diff --git a/frontend/src/stores/useLayoutContainerStore.ts b/frontend/src/stores/useLayoutContainerStore.ts old mode 100644 new mode 100755 diff --git a/frontend/src/tools/array.ts b/frontend/src/tools/array.ts old mode 100644 new mode 100755 diff --git a/frontend/src/tools/common.ts b/frontend/src/tools/common.ts old mode 100644 new mode 100755 diff --git a/frontend/src/tools/copy.ts b/frontend/src/tools/copy.ts old mode 100644 new mode 100755 diff --git a/frontend/src/tools/dom.ts b/frontend/src/tools/dom.ts old mode 100644 new mode 100755 diff --git a/frontend/src/tools/fileManager.ts b/frontend/src/tools/fileManager.ts old mode 100644 new mode 100755 diff --git a/frontend/src/tools/fileSize.ts b/frontend/src/tools/fileSize.ts old mode 100644 new mode 100755 diff --git a/frontend/src/tools/fileSum.ts b/frontend/src/tools/fileSum.ts old mode 100644 new mode 100755 diff --git a/frontend/src/tools/memory.ts b/frontend/src/tools/memory.ts old mode 100644 new mode 100755 diff --git a/frontend/src/tools/nodes.ts b/frontend/src/tools/nodes.ts old mode 100644 new mode 100755 diff --git a/frontend/src/tools/object.ts b/frontend/src/tools/object.ts old mode 100644 new mode 100755 diff --git a/frontend/src/tools/permission.ts b/frontend/src/tools/permission.ts old mode 100644 new mode 100755 diff --git a/frontend/src/tools/protocol.ts b/frontend/src/tools/protocol.ts old mode 100644 new mode 100755 diff --git a/frontend/src/tools/randId.ts b/frontend/src/tools/randId.ts old mode 100644 new mode 100755 diff --git a/frontend/src/tools/safe.ts b/frontend/src/tools/safe.ts old mode 100644 new mode 100755 diff --git a/frontend/src/tools/sandbox.ts b/frontend/src/tools/sandbox.ts old mode 100644 new mode 100755 diff --git a/frontend/src/tools/string.ts b/frontend/src/tools/string.ts old mode 100644 new mode 100755 diff --git a/frontend/src/tools/throttle.ts b/frontend/src/tools/throttle.ts old mode 100644 new mode 100755 diff --git a/frontend/src/tools/time.ts b/frontend/src/tools/time.ts old mode 100644 new mode 100755 diff --git a/frontend/src/tools/validator.ts b/frontend/src/tools/validator.ts old mode 100644 new mode 100755 diff --git a/frontend/src/tools/version.ts b/frontend/src/tools/version.ts old mode 100644 new mode 100755 diff --git a/frontend/src/types/ant.ts b/frontend/src/types/ant.ts old mode 100644 new mode 100755 diff --git a/frontend/src/types/const.ts b/frontend/src/types/const.ts old mode 100644 new mode 100755 diff --git a/frontend/src/types/fileManager.ts b/frontend/src/types/fileManager.ts old mode 100644 new mode 100755 diff --git a/frontend/src/types/index.ts b/frontend/src/types/index.ts old mode 100644 new mode 100755 diff --git a/frontend/src/types/javaManager.ts b/frontend/src/types/javaManager.ts old mode 100644 new mode 100755 diff --git a/frontend/src/types/operationLog.ts b/frontend/src/types/operationLog.ts old mode 100644 new mode 100755 diff --git a/frontend/src/types/user.ts b/frontend/src/types/user.ts old mode 100644 new mode 100755 diff --git a/frontend/src/types/vue-i18n.ts b/frontend/src/types/vue-i18n.ts old mode 100644 new mode 100755 diff --git a/frontend/src/views/Install.vue b/frontend/src/views/Install.vue old mode 100644 new mode 100755 diff --git a/frontend/src/views/LayoutContainer.vue b/frontend/src/views/LayoutContainer.vue old mode 100644 new mode 100755 diff --git a/frontend/src/views/Login.vue b/frontend/src/views/Login.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/DefaultCard.vue b/frontend/src/widgets/DefaultCard.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/EmptyCard.vue b/frontend/src/widgets/EmptyCard.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/InstanceChart.vue b/frontend/src/widgets/InstanceChart.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/InstanceList.vue b/frontend/src/widgets/InstanceList.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/LoginCard.vue b/frontend/src/widgets/LoginCard.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/NodeList.vue b/frontend/src/widgets/NodeList.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/NodeOverview.vue b/frontend/src/widgets/NodeOverview.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/OperationLogCard.vue b/frontend/src/widgets/OperationLogCard.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/Page404.vue b/frontend/src/widgets/Page404.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/PanelOverview.vue b/frontend/src/widgets/PanelOverview.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/QuickStart.vue b/frontend/src/widgets/QuickStart.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/RequestChart.vue b/frontend/src/widgets/RequestChart.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/Settings.vue b/frontend/src/widgets/Settings.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/ShelvesCard.vue b/frontend/src/widgets/ShelvesCard.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/StatusBlock.vue b/frontend/src/widgets/StatusBlock.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/TitleCard.vue b/frontend/src/widgets/TitleCard.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/UserInstanceList.vue b/frontend/src/widgets/UserInstanceList.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/UserList.vue b/frontend/src/widgets/UserList.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/UserStatusBlock.vue b/frontend/src/widgets/UserStatusBlock.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/imageManager/BuildProgress.vue b/frontend/src/widgets/imageManager/BuildProgress.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/imageManager/DockerFileForm.vue b/frontend/src/widgets/imageManager/DockerFileForm.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/imageManager/NewImage.vue b/frontend/src/widgets/imageManager/NewImage.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/imageManager/index.vue b/frontend/src/widgets/imageManager/index.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/instance/BaseInfo.vue b/frontend/src/widgets/instance/BaseInfo.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/instance/FileManager.vue b/frontend/src/widgets/instance/FileManager.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/instance/ManagerBtns.vue b/frontend/src/widgets/instance/ManagerBtns.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/instance/ModManager.vue b/frontend/src/widgets/instance/ModManager.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/instance/Schedule.vue b/frontend/src/widgets/instance/Schedule.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/instance/ServerConfigFile.vue b/frontend/src/widgets/instance/ServerConfigFile.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/instance/ServerConfigOverview.vue b/frontend/src/widgets/instance/ServerConfigOverview.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/instance/Shortcut.vue b/frontend/src/widgets/instance/Shortcut.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/instance/Terminal.vue b/frontend/src/widgets/instance/Terminal.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/instance/dialogs/DeleteInstanceDialog.vue b/frontend/src/widgets/instance/dialogs/DeleteInstanceDialog.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/instance/dialogs/DockerInfo.vue b/frontend/src/widgets/instance/dialogs/DockerInfo.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/instance/dialogs/EventConfig.vue b/frontend/src/widgets/instance/dialogs/EventConfig.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/instance/dialogs/FileEditor.vue b/frontend/src/widgets/instance/dialogs/FileEditor.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/instance/dialogs/ImageViewer.vue b/frontend/src/widgets/instance/dialogs/ImageViewer.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/instance/dialogs/InstanceDetail.vue b/frontend/src/widgets/instance/dialogs/InstanceDetail.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/instance/dialogs/InstanceFundamentalDetail.vue b/frontend/src/widgets/instance/dialogs/InstanceFundamentalDetail.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/instance/dialogs/JavaManager.vue b/frontend/src/widgets/instance/dialogs/JavaManager.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/instance/dialogs/MarketDialog.vue b/frontend/src/widgets/instance/dialogs/MarketDialog.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/instance/dialogs/McPingSettings.vue b/frontend/src/widgets/instance/dialogs/McPingSettings.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/instance/dialogs/NewSchedule.vue b/frontend/src/widgets/instance/dialogs/NewSchedule.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/instance/dialogs/PingConfig.vue b/frontend/src/widgets/instance/dialogs/PingConfig.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/instance/dialogs/RconSettings.vue b/frontend/src/widgets/instance/dialogs/RconSettings.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/instance/dialogs/SelectUnzipCode.vue b/frontend/src/widgets/instance/dialogs/SelectUnzipCode.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/instance/dialogs/TemplateNameDialog.vue b/frontend/src/widgets/instance/dialogs/TemplateNameDialog.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/instance/dialogs/TermConfig.vue b/frontend/src/widgets/instance/dialogs/TermConfig.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/instance/mod-manager/LocalModTable.vue b/frontend/src/widgets/instance/mod-manager/LocalModTable.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/instance/mod-manager/ModConfigModal.vue b/frontend/src/widgets/instance/mod-manager/ModConfigModal.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/instance/mod-manager/ModFloatingTools.vue b/frontend/src/widgets/instance/mod-manager/ModFloatingTools.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/instance/mod-manager/ModVersionModal.vue b/frontend/src/widgets/instance/mod-manager/ModVersionModal.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/instance/mod-manager/SearchModTable.vue b/frontend/src/widgets/instance/mod-manager/SearchModTable.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/instance/mod-manager/useDeferredTasks.ts b/frontend/src/widgets/instance/mod-manager/useDeferredTasks.ts old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/instance/mod-manager/useLocalMods.ts b/frontend/src/widgets/instance/mod-manager/useLocalMods.ts old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/instance/mod-manager/useModConfig.ts b/frontend/src/widgets/instance/mod-manager/useModConfig.ts old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/instance/mod-manager/useModSearch.ts b/frontend/src/widgets/instance/mod-manager/useModSearch.ts old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/instance/mod-manager/useModUpload.ts b/frontend/src/widgets/instance/mod-manager/useModUpload.ts old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/market/InstallOptionButton.vue b/frontend/src/widgets/market/InstallOptionButton.vue new file mode 100755 index 000000000..8fccfcdd8 --- /dev/null +++ b/frontend/src/widgets/market/InstallOptionButton.vue @@ -0,0 +1,139 @@ + + + + + diff --git a/frontend/src/widgets/market/editor.vue b/frontend/src/widgets/market/editor.vue old mode 100644 new mode 100755 diff --git a/frontend/src/widgets/market/index.vue b/frontend/src/widgets/market/index.vue old mode 100644 new mode 100755 index 5da65f297..a4ecd5cb7 --- a/frontend/src/widgets/market/index.vue +++ b/frontend/src/widgets/market/index.vue @@ -1,5 +1,4 @@ diff --git a/frontend/src/widgets/instance/BaseInfo.vue b/frontend/src/widgets/instance/BaseInfo.vue index 087b76bc3..3e11ad463 100755 --- a/frontend/src/widgets/instance/BaseInfo.vue +++ b/frontend/src/widgets/instance/BaseInfo.vue @@ -168,11 +168,11 @@ onMounted(async () => { - +
{{ t("TXT_CODE_eaabd222") }}: Date: Wed, 1 Apr 2026 10:21:40 +0000 Subject: [PATCH 127/256] fix: instance stop condition in DiskLimitService --- daemon/src/service/disk_limit_service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daemon/src/service/disk_limit_service.ts b/daemon/src/service/disk_limit_service.ts index 5b03b5e4a..c46383fcf 100644 --- a/daemon/src/service/disk_limit_service.ts +++ b/daemon/src/service/disk_limit_service.ts @@ -63,7 +63,7 @@ class DiskLimitService { const startCount = instance.startCount; instance.execPreset("stop"); await sleep(1000 * 60); - if (instance.status() === Instance.STATUS_RUNNING && startCount === instance.startCount) { + if (instance.status() !== Instance.STATUS_STOP && startCount === instance.startCount) { instance.println("ERROR", $t("TXT_CODE_8418e7fe")); instance .execPreset("kill") From 06bc2a5fd69c1a794a3e1e1494ce302352035fca Mon Sep 17 00:00:00 2001 From: Lazy <2211717435@qq.com> Date: Wed, 1 Apr 2026 10:30:52 +0000 Subject: [PATCH 128/256] opt: reduce sleep duration --- daemon/src/service/disk_limit_service.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/daemon/src/service/disk_limit_service.ts b/daemon/src/service/disk_limit_service.ts index c46383fcf..87c660d25 100644 --- a/daemon/src/service/disk_limit_service.ts +++ b/daemon/src/service/disk_limit_service.ts @@ -62,7 +62,7 @@ class DiskLimitService { if (instance.status() === Instance.STATUS_RUNNING) { const startCount = instance.startCount; instance.execPreset("stop"); - await sleep(1000 * 60); + await sleep(1000 * 10); if (instance.status() !== Instance.STATUS_STOP && startCount === instance.startCount) { instance.println("ERROR", $t("TXT_CODE_8418e7fe")); instance @@ -108,10 +108,7 @@ class DiskLimitService { storageUsage: convertBytesToGB(storageUsage) }) ); - instance.println( - "WARNING", - $t("TXT_CODE_d448d98d") - ); + instance.println("WARNING", $t("TXT_CODE_d448d98d")); await sleep(200); } this.#stopInstance(instance); From 998bcb405027008877acaef9baad82b30b0f54e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A9=99=E6=B1=81=E5=96=B5?= <292200693@qq.com> Date: Sun, 5 Apr 2026 21:00:14 +0800 Subject: [PATCH 129/256] feat: using custom header to get user ip with reverse proxy mode --- frontend/src/types/index.ts | 1 + frontend/src/widgets/Settings.vue | 27 +++++++++++++++++++++--- panel/src/app.ts | 2 +- panel/src/app/entity/setting.ts | 2 ++ panel/src/app/routers/login_router.ts | 18 ++++++++-------- panel/src/app/routers/settings_router.ts | 7 +++--- 6 files changed, 40 insertions(+), 17 deletions(-) diff --git a/frontend/src/types/index.ts b/frontend/src/types/index.ts index 382d707b4..a83a60156 100644 --- a/frontend/src/types/index.ts +++ b/frontend/src/types/index.ts @@ -68,6 +68,7 @@ export interface Settings { httpPort: number; httpIp: any; reverseProxyMode: boolean; + reverseProxyHeader: string; dataPort: number; forwardType: number; crossDomain: boolean; diff --git a/frontend/src/widgets/Settings.vue b/frontend/src/widgets/Settings.vue index e7f2c55a8..6b06974b0 100644 --- a/frontend/src/widgets/Settings.vue +++ b/frontend/src/widgets/Settings.vue @@ -8,7 +8,9 @@ import { router } from "@/config/router"; import { SUPPORTED_LANGS, isCN, t } from "@/lang/i18n"; import { setSettingInfo, settingInfo } from "@/services/apis"; import { useAppConfigStore } from "@/stores/useAppConfigStore"; +import { useLayoutConfigStore } from "@/stores/useLayoutConfig"; import { useLayoutContainerStore } from "@/stores/useLayoutContainerStore"; +import { arrayFilter } from "@/tools/array"; import { reportErrorMsg } from "@/tools/validator"; import type { LayoutCard, Settings } from "@/types"; import { @@ -27,8 +29,6 @@ import { } from "@ant-design/icons-vue"; import { Modal, message, notification } from "ant-design-vue"; import { onMounted, onUnmounted, ref } from "vue"; -import { useLayoutConfigStore } from "@/stores/useLayoutConfig"; -import { arrayFilter } from "@/tools/array"; defineProps<{ card: LayoutCard; @@ -674,7 +674,11 @@ onUnmounted(() => { - {{ t("TXT_CODE_ae575e12") }} + {{ + t( + "如果您正在使用反向代理访问面板,请开启此选项。面板将会从特定的请求头来获取真实IP。" + ) + }} @@ -692,6 +696,23 @@ onUnmounted(() => { + + + {{ t("反向代理请求头") }} + + + + {{ t("当反向代理模式开启时,面板将会从这个请求头中获取用户真实IP。") }} + + + + + + {{ t("TXT_CODE_1d67c9c6") }} diff --git a/panel/src/app.ts b/panel/src/app.ts index 048260c9f..c8ac61477 100755 --- a/panel/src/app.ts +++ b/panel/src/app.ts @@ -126,7 +126,7 @@ _ / / / / /___ ____/ /_ / / / / /_/ /_ / / / /_/ /_ /_/ // __/ / const app = new Koa({ proxy: systemConfig?.reverseProxyMode || false, - proxyIpHeader: "X-Real-IP" + proxyIpHeader: systemConfig?.reverseProxyHeader || "X-Real-IP" }); // Listen for Koa errors diff --git a/panel/src/app/entity/setting.ts b/panel/src/app/entity/setting.ts index 496e1f0a0..55ec80e47 100755 --- a/panel/src/app/entity/setting.ts +++ b/panel/src/app/entity/setting.ts @@ -7,6 +7,8 @@ export default class SystemConfig { // reverse proxy mode reverseProxyMode: boolean = false; + // reverse proxy header + reverseProxyHeader: string = "X-Real-IP"; // data transfer port dataPort: number = 23334; diff --git a/panel/src/app/routers/login_router.ts b/panel/src/app/routers/login_router.ts index 874eaafca..b35c60f68 100755 --- a/panel/src/app/routers/login_router.ts +++ b/panel/src/app/routers/login_router.ts @@ -1,17 +1,17 @@ -import Koa from "koa"; import Router from "@koa/router"; -import validator from "../middleware/validator"; -import permission from "../middleware/permission"; -import { check, login, logout, checkBanIp, loginSuccess } from "../service/passport_service"; -import { systemConfig } from "../setting"; -import userSystem, { TwoFactorError } from "../service/user_service"; -import { logger } from "../service/log"; -import { $t } from "../i18n"; import axios from "axios"; +import Koa from "koa"; import { GlobalVariable } from "mcsmanager-common"; -import { ROLE } from "../entity/user"; import SystemConfig from "../entity/setting"; +import { ROLE } from "../entity/user"; +import { $t } from "../i18n"; +import permission from "../middleware/permission"; +import validator from "../middleware/validator"; +import { logger } from "../service/log"; import { operationLogger } from "../service/operation_logger"; +import { check, checkBanIp, login, logout } from "../service/passport_service"; +import userSystem, { TwoFactorError } from "../service/user_service"; +import { systemConfig } from "../setting"; const router = new Router({ prefix: "/auth" }); diff --git a/panel/src/app/routers/settings_router.ts b/panel/src/app/routers/settings_router.ts index 36db47fa1..855c00d87 100755 --- a/panel/src/app/routers/settings_router.ts +++ b/panel/src/app/routers/settings_router.ts @@ -38,10 +38,9 @@ router.put("/setting", permission({ level: ROLE.ADMIN }), async (ctx) => { if (config.httpIp != null) systemConfig.httpIp = config.httpIp; if (config.httpPort != null) systemConfig.httpPort = config.httpPort; if (config.prefix != null) systemConfig.prefix = config.prefix; - if (config.reverseProxyMode != null) { - systemConfig.reverseProxyMode = Boolean(config.reverseProxyMode); - ctx.app.proxy = systemConfig.reverseProxyMode; - } + if (config.reverseProxyMode != null) systemConfig.reverseProxyMode = config.reverseProxyMode; + if (config.reverseProxyHeader != null) + systemConfig.reverseProxyHeader = config.reverseProxyHeader; if (config.crossDomain != null) systemConfig.crossDomain = config.crossDomain; if (config.gzip != null) systemConfig.gzip = config.gzip; if (config.maxCompress != null) systemConfig.maxCompress = config.maxCompress; From 41eccd327e17731a9183143e28e29ee1fb9c63e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A9=99=E6=B1=81=E5=96=B5?= <292200693@qq.com> Date: Sun, 5 Apr 2026 21:05:05 +0800 Subject: [PATCH 130/256] chore: i18n --- frontend/src/widgets/Settings.vue | 16 ++++++---------- languages/en_US.json | 5 ++++- languages/zh_CN.json | 5 ++++- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/frontend/src/widgets/Settings.vue b/frontend/src/widgets/Settings.vue index a6cc91496..3e9a7b1b6 100644 --- a/frontend/src/widgets/Settings.vue +++ b/frontend/src/widgets/Settings.vue @@ -821,11 +821,7 @@ onUnmounted(() => { - {{ - t( - "如果您正在使用反向代理访问面板,请开启此选项。面板将会从特定的请求头来获取真实IP。" - ) - }} + {{ t("TXT_CODE_2b85af6d") }} @@ -845,11 +841,11 @@ onUnmounted(() => { - {{ t("反向代理请求头") }} + {{ t("TXT_CODE_66aeac82") }} - {{ t("当反向代理模式开启时,面板将会从这个请求头中获取用户真实IP。") }} + {{ t("TXT_CODE_fd8bc51f") }} @@ -933,9 +929,9 @@ onUnmounted(() => { {{ t("TXT_CODE_SSO_ENABLE_DESC") }} - {{ - t("TXT_CODE_718c9310") - }} + + {{ t("TXT_CODE_718c9310") }} + OpenID Connect (OIDC) OAuth 2.0 diff --git a/languages/en_US.json b/languages/en_US.json index af0b4b8b9..35a6400c1 100644 --- a/languages/en_US.json +++ b/languages/en_US.json @@ -3425,5 +3425,8 @@ "TXT_CODE_gpu_invalid_driver": "Invalid GPU driver name: {{v}}. Only letters and digits are allowed.", "TXT_CODE_gpu_conflict_count_and_ids": "GPU configuration conflict: cannot specify both GPU count and device IDs at the same time.", "TXT_CODE_29e85f34": "Are you sure?", - "TXT_CODE_f18f65db": "Please make sure your current work has been saved. You can freely adjust the interface after entering. The page will refresh after exiting!" + "TXT_CODE_f18f65db": "Please make sure your current work has been saved. You can freely adjust the interface after entering. The page will refresh after exiting!", + "TXT_CODE_2b85af6d": "If you are accessing the panel through a reverse proxy, please enable this option. The panel will retrieve your real IP address from a specific request header.", + "TXT_CODE_66aeac82": "Reverse Proxy Request Header", + "TXT_CODE_fd8bc51f": "When reverse proxy mode is enabled, the panel will retrieve the user's real IP address from this request header." } diff --git a/languages/zh_CN.json b/languages/zh_CN.json index 5877ed82d..dbeb264da 100644 --- a/languages/zh_CN.json +++ b/languages/zh_CN.json @@ -3425,5 +3425,8 @@ "TXT_CODE_gpu_invalid_driver": "无效的 GPU 驱动名称:{{v}},只允许字母和数字。", "TXT_CODE_gpu_conflict_count_and_ids": "GPU 配置冲突:不能同时指定 GPU 数量和设备 ID。", "TXT_CODE_29e85f34": "确定进入自定义设计模式吗?", - "TXT_CODE_f18f65db": "请确认当前工作已保存,进入后可以对界面进行自由调整,退出后会刷新页面!" + "TXT_CODE_f18f65db": "请确认当前工作已保存,进入后可以对界面进行自由调整,退出后会刷新页面!", + "TXT_CODE_2b85af6d": "如果您正在使用反向代理访问面板,请开启此选项。面板将会从特定的请求头来获取真实IP。", + "TXT_CODE_66aeac82": "反向代理请求头", + "TXT_CODE_fd8bc51f": "当反向代理模式开启时,面板将会从这个请求头中获取用户真实IP。" } From 9843c26af7a924c17f5f20e3cdbf2cea29d044d3 Mon Sep 17 00:00:00 2001 From: limbang <495071565@qq.com> Date: Wed, 15 Apr 2026 18:35:41 +0800 Subject: [PATCH 131/256] fix: improve Forge/NeoForge metadata parsing and version fallback - Add support for NeoForge mods.toml alongside Forge mods.toml - Refactor TOML file resolution using a unified lookup list - Fix placeholder version handling (${file.jarVersion}) by introducing manifest fallback - Add getVersionFromManifest() to extract version from MANIFEST.MF - Improve robustness of mod metadata parsing across different mod loader formats --- daemon/src/service/mod_service.ts | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/daemon/src/service/mod_service.ts b/daemon/src/service/mod_service.ts index dd085f72d..ac1e7aaf2 100644 --- a/daemon/src/service/mod_service.ts +++ b/daemon/src/service/mod_service.ts @@ -50,6 +50,20 @@ export class ModService { }); } + /** + * Try to get version from MANIFEST.MF + */ + private async getVersionFromManifest(zip: any, entries: any): Promise { + const manifestPath = "META-INF/MANIFEST.MF"; + if (!entries[manifestPath]) return null; + const data = await zip.entryData(manifestPath); + const content = data.toString(); + // Use regex to match Implementation-Version or Specification-Version + const match = content.match(/Implementation-Version:\s*(.+)/i) + || content.match(/Specification-Version:\s*(.+)/i); + return match ? match[1].trim() : null; + } + private async parseJarMetadata(jarPath: string): Promise | null> { const zip = new StreamZip.async({ file: jarPath }); try { @@ -68,15 +82,22 @@ export class ModService { }; } - // Forge (mods.toml) - if (entries["META-INF/mods.toml"]) { - const data = await zip.entryData("META-INF/mods.toml"); + // Forge (mods.toml) / NeoForge (neoforge.mods.toml) + const TOML_FILES = ["META-INF/mods.toml","META-INF/neoforge.mods.toml"]; + for (const filePath of TOML_FILES) { + if (!entries[filePath]) continue; + const data = await zip.entryData(filePath); const config = toml.parse(data.toString()) as any; - const mod = config.mods ? config.mods[0] : {}; + const mod = config.mods?.[0] || {}; + // Handle placeholder logic + let version = mod.version; + if (version === "${file.jarVersion}") { + version = await this.getVersionFromManifest(zip, entries) || version; + } return { id: mod.modId, name: mod.displayName || mod.modId, - version: mod.version, + version: version, description: mod.description, type: "mod" }; From d5977617465be1e16eb235dbbe385f28f0f38781 Mon Sep 17 00:00:00 2001 From: TeraBytes1024 <277686518+TeraBytes1024@users.noreply.github.com> Date: Mon, 20 Apr 2026 16:57:00 +0800 Subject: [PATCH 132/256] fix auth_router.ts --- daemon/src/routers/auth_router.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/daemon/src/routers/auth_router.ts b/daemon/src/routers/auth_router.ts index ec200e0b6..89d5a1fc0 100755 --- a/daemon/src/routers/auth_router.ts +++ b/daemon/src/routers/auth_router.ts @@ -55,8 +55,8 @@ routerApp.on("auth", (ctx, data) => { (!globalConfiguration.config.whiteListPanelIp || globalConfiguration.config.whiteListPanelIps.includes(ip)) && timingSafeEqual( - Uint8Array.from(String(data ?? "")), - Uint8Array.from(String(globalConfiguration.config.key ?? "")) + Buffer.from(String(data ?? "")), + Buffer.from(String(globalConfiguration.config.key ?? "")) ) ) { // The authentication is passed, and the registered session is a trusted session From add80cb4383749fa6603678907b7c973687eeacd Mon Sep 17 00:00:00 2001 From: Lemon-miaow Date: Tue, 21 Apr 2026 10:14:05 +0800 Subject: [PATCH 133/256] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=20MCDR=20?= =?UTF-8?q?=E5=AE=9E=E4=BE=8B=E8=87=AA=E5=8A=A8=E8=A7=A3=E6=9E=90=E5=BA=95?= =?UTF-8?q?=E5=B1=82=E6=9C=8D=E5=8A=A1=E7=AB=AF=E7=B1=BB=E5=9E=8B=E4=B8=8E?= =?UTF-8?q?=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- daemon/src/entity/commands/dispatcher.ts | 6 ++- daemon/src/service/mcdr_service.ts | 19 +++++++++ daemon/src/service/mod_service.ts | 39 ++++++++++++++++--- frontend/src/widgets/instance/ManagerBtns.vue | 13 +++++-- 4 files changed, 67 insertions(+), 10 deletions(-) create mode 100644 daemon/src/service/mcdr_service.ts diff --git a/daemon/src/entity/commands/dispatcher.ts b/daemon/src/entity/commands/dispatcher.ts index cc4e9048a..072b32a7b 100755 --- a/daemon/src/entity/commands/dispatcher.ts +++ b/daemon/src/entity/commands/dispatcher.ts @@ -1,3 +1,4 @@ +import { TYPE_MINECRAFT_MCDR } from "../../service/mcdr_service"; import Instance from "../instance/instance"; import InstanceCommand from "./base/command"; import DockerResizeCommand from "./docker/docker_pty_resize"; @@ -77,7 +78,10 @@ export default class FunctionDispatcher extends InstanceCommand { } // Minecraft Ping - if (instance.config.type.includes(Instance.TYPE_MINECRAFT_JAVA)) { + if ( + instance.config.type.includes(Instance.TYPE_MINECRAFT_JAVA) || + instance.config.type === TYPE_MINECRAFT_MCDR + ) { instance.setPreset("refreshPlayers", new PingJavaMinecraftServerCommand()); instance.lifeCycleTaskManager.registerLifeCycleTask(new PingMinecraftServerTask()); } diff --git a/daemon/src/service/mcdr_service.ts b/daemon/src/service/mcdr_service.ts new file mode 100644 index 000000000..6b24faf61 --- /dev/null +++ b/daemon/src/service/mcdr_service.ts @@ -0,0 +1,19 @@ +import fs from "fs-extra"; +import path from "path"; +import yaml from "yaml"; + +export const TYPE_MINECRAFT_MCDR = "universal/mcdr"; + +export function resolveMCDRServerRoot(type: string, instanceCwd: string): string | null { + if (type !== TYPE_MINECRAFT_MCDR) return null; + try { + const raw = fs.readFileSync(path.join(instanceCwd, "config.yml"), "utf-8"); + const dir = yaml.parse(raw)?.working_directory; + if (typeof dir !== "string" || !dir.trim()) return null; + return path.isAbsolute(dir) + ? path.normalize(dir) + : path.normalize(path.join(instanceCwd, dir.trim())); + } catch { + return null; + } +} diff --git a/daemon/src/service/mod_service.ts b/daemon/src/service/mod_service.ts index dd085f72d..a042ee9c4 100644 --- a/daemon/src/service/mod_service.ts +++ b/daemon/src/service/mod_service.ts @@ -5,8 +5,10 @@ import path from "path"; import toml from 'smol-toml'; import yaml from "yaml"; import downloadManager from "./download_manager"; -import { getFileManager } from "./file_router_service"; +import { resolveMCDRServerRoot } from "./mcdr_service"; import logger from "./log"; +import InstanceSubsystem from "./system_instance"; +import FileManager from "./system_file"; export interface ModInfo { name: string; @@ -169,7 +171,12 @@ export class ModService { if (pageSize < 1) pageSize = 10; if (page < 1) page = 1; - const fileManager = getFileManager(instanceUuid); + const instance = InstanceSubsystem.getInstance(instanceUuid)!; + const cwd = instance.absoluteCwdPath(); + const fileManager = new FileManager( + resolveMCDRServerRoot(instance.config.type, cwd) ?? cwd, + instance.config?.fileCode + ); // if (!FileManager.checkFileName(folder ?? "")) { // throw new Error("Invalid folder name"); @@ -287,7 +294,12 @@ export class ModService { } public async toggleMod(instanceUuid: string, fileName: string): Promise { - const fileManager = getFileManager(instanceUuid); + const instance = InstanceSubsystem.getInstance(instanceUuid)!; + const cwd = instance.absoluteCwdPath(); + const fileManager = new FileManager( + resolveMCDRServerRoot(instance.config.type, cwd) ?? cwd, + instance.config?.fileCode + ); if (!fileManager.checkPath(fileName)) throw new Error("Invalid file name"); const rootDir = fileManager.toAbsolutePath("."); @@ -317,7 +329,12 @@ export class ModService { } public async deleteMod(instanceUuid: string, fileName: string): Promise { - const fileManager = getFileManager(instanceUuid); + const instance = InstanceSubsystem.getInstance(instanceUuid)!; + const cwd = instance.absoluteCwdPath(); + const fileManager = new FileManager( + resolveMCDRServerRoot(instance.config.type, cwd) ?? cwd, + instance.config?.fileCode + ); if (!fileManager.checkPath(fileName)) throw new Error("Invalid file name"); const rootDir = fileManager.toAbsolutePath("."); @@ -346,7 +363,12 @@ export class ModService { type: "mod" | "plugin", options: { fallbackUrl?: string } = {} ) { - const fileManager = getFileManager(instanceUuid); + const instance = InstanceSubsystem.getInstance(instanceUuid)!; + const cwd = instance.absoluteCwdPath(); + const fileManager = new FileManager( + resolveMCDRServerRoot(instance.config.type, cwd) ?? cwd, + instance.config?.fileCode + ); const rootDir = fileManager.toAbsolutePath("."); // Determine the save directory based on what exists (case-sensitive check for Linux) @@ -378,7 +400,12 @@ export class ModService { type: "mod" | "plugin", fileName?: string ): Promise { - const fileManager = getFileManager(instanceUuid); + const instance = InstanceSubsystem.getInstance(instanceUuid)!; + const cwd = instance.absoluteCwdPath(); + const fileManager = new FileManager( + resolveMCDRServerRoot(instance.config.type, cwd) ?? cwd, + instance.config?.fileCode + ); if (fileName && !fileManager.checkPath(fileName)) throw new Error("Invalid file name"); if (modId && !fileManager.checkPath(modId)) throw new Error("Invalid mod ID"); const rootDir = fileManager.toAbsolutePath("."); diff --git a/frontend/src/widgets/instance/ManagerBtns.vue b/frontend/src/widgets/instance/ManagerBtns.vue index b7644096a..c4abb1b52 100755 --- a/frontend/src/widgets/instance/ManagerBtns.vue +++ b/frontend/src/widgets/instance/ManagerBtns.vue @@ -4,6 +4,7 @@ import ResponsiveLayoutGroup from "@/components/ResponsiveLayoutGroup.vue"; import { useAppRouters } from "@/hooks/useAppRouters"; import { TYPE_MINECRAFT_JAVA, + TYPE_MINECRAFT_MCDR, TYPE_STEAM_SERVER_UNIVERSAL, useInstanceInfo } from "@/hooks/useInstance"; @@ -155,8 +156,11 @@ const btns = computed(() => { }, condition: () => { const type = instanceInfo.value?.config.type || ""; - // Narrow it down to Minecraft server types only (Java or Bedrock) - const isMC = type.startsWith("minecraft/java") || type.startsWith("minecraft/bedrock"); + // Narrow it down to Minecraft server types only (Java, Bedrock, MCDR) + const isMC = + type.startsWith("minecraft/java") || + type.startsWith("minecraft/bedrock") || + type === TYPE_MINECRAFT_MCDR; if (!isMC) return false; const hasPermission = state.settings.canFileManager || isAdmin.value; if (!hasPermission) return false; @@ -228,7 +232,10 @@ const btns = computed(() => { click: () => { mcSettingsDialog.value?.openDialog(); }, - condition: () => instanceInfo.value?.config.type.includes(TYPE_MINECRAFT_JAVA) ?? false + condition: () => + (instanceInfo.value?.config.type.includes(TYPE_MINECRAFT_JAVA) || + instanceInfo.value?.config.type === TYPE_MINECRAFT_MCDR) ?? + false }, { title: t("TXT_CODE_4f34fc28"), From 78531ef2a37c98063e500f6d7c7bc57949331de9 Mon Sep 17 00:00:00 2001 From: XUANHLGG Date: Thu, 23 Apr 2026 00:14:26 +0800 Subject: [PATCH 134/256] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=B8=8A=E4=BC=A0?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E6=97=B6=E7=9B=AE=E5=BD=95=E5=AD=98=E5=9C=A8?= =?UTF-8?q?=E8=B7=A8=E9=A1=B5=E5=90=8C=E5=90=8D=E6=96=87=E4=BB=B6=E6=9C=AA?= =?UTF-8?q?=E8=A7=A6=E5=8F=91=E8=A6=86=E7=9B=96=E7=A1=AE=E8=AE=A4=E8=80=8C?= =?UTF-8?q?=E7=9B=B4=E6=8E=A5=E7=94=9F=E6=88=90=E5=89=AF=E6=9C=AC=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/hooks/useFileManager.ts | 253 +++++++++++++++------- frontend/src/services/apis/fileManager.ts | 19 +- 2 files changed, 180 insertions(+), 92 deletions(-) diff --git a/frontend/src/hooks/useFileManager.ts b/frontend/src/hooks/useFileManager.ts index 04601c904..5f8b98f5d 100755 --- a/frontend/src/hooks/useFileManager.ts +++ b/frontend/src/hooks/useFileManager.ts @@ -247,7 +247,7 @@ export const useFileManager = (instanceId: string = "", daemonId: string = "") = unzipmode: "0", code: "utf-8", ref: ref(), - ok: () => {}, + ok: () => { }, cancel: () => { dialog.value.value = ""; }, @@ -286,7 +286,7 @@ export const useFileManager = (instanceId: string = "", daemonId: string = "") = dialog.value.info = ""; dialog.value.mode = ""; dialog.value.style = {}; - dialog.value.ok = () => {}; + dialog.value.ok = () => { }; }; }); }; @@ -535,99 +535,186 @@ export const useFileManager = (instanceId: string = "", daemonId: string = "") = const spinning = ref(false); - const selectedFiles = async (files: File[], overridePath?: string) => { - const { state: missionCfg, execute: getUploadMissionCfg } = uploadAddress(); - const fileSet = new Set(files.map((f) => ({ file: f, overwrite: false }))); - const existingFiles: typeof fileSet = new Set(); + type SelectedUploadFile = { + file: File; + overwrite: boolean; + }; - for (const f of fileSet) { - if (dataSource.value?.find((dataType) => dataType.name === f.file.name)) { - existingFiles.add(f); - } - } + type UploadConflictDecision = { + keep: boolean; + overwrite: boolean; + applyToAll: boolean; + }; - for (const f of existingFiles) { - const all = ref(false); - const overwrite = ref(false); - const confirmPromise = new Promise((onComplete) => { - Modal.confirm({ - title: t("TXT_CODE_99ca8563"), - icon: createVNode(ExclamationCircleOutlined), - content: createVNode( - OverwriteFilesPopUpContent, - { - count: existingFiles.size, - fileName: f.file.name, - all: all, - overwrite: overwrite, - "onUpdate:all": (val: boolean) => (all.value = val), - "onUpdate:overwrite": (val: boolean) => (overwrite.value = val) - }, - null - ), - okText: t("TXT_CODE_ae09d79d"), - cancelText: t("TXT_CODE_518528d0"), - onOk() { - onComplete(true); - }, - onCancel() { - onComplete(false); - } - }); - }); - if (await confirmPromise) { - if (all.value) { - for (const f of existingFiles) { - f.overwrite = overwrite.value; - } - break; - } - f.overwrite = overwrite.value; - existingFiles.delete(f); - } else { - // skip - if (all.value) { - for (const f of existingFiles) { - fileSet.delete(f); - } - break; + const getExistingUploadNames = async (files: SelectedUploadFile[], targetPath: string) => { + const targetNames = new Set(files.map((item) => item.file.name)); + const existingNames = new Set(); + if (targetNames.size === 0) return existingNames; + + const { execute } = getFileListApi(); + const pageSize = 100; + let page = 0; + let total = 0; + + do { + const res = await execute({ + params: { + daemonId: daemonId || "", + uuid: instanceId || "", + page, + page_size: pageSize, + file_name: "", + target: targetPath } - existingFiles.delete(f); - fileSet.delete(f); + }); + + const items = res.value?.items || []; + total = res.value?.total || 0; + + for (const item of items) { + if (!targetNames.has(item.name)) continue; + existingNames.add(item.name); + targetNames.delete(item.name); } + + page += 1; + if (targetNames.size === 0 || items.length === 0) break; + } while (page * pageSize < total); + + return existingNames; + }; + + const countRemainingUploadConflicts = ( + files: SelectedUploadFile[], + startIndex: number, + occupiedNames: Set + ) => { + const simulatedOccupiedNames = new Set(occupiedNames); + let count = 0; + + for (let i = startIndex; i < files.length; i++) { + const fileName = files[i].file.name; + if (simulatedOccupiedNames.has(fileName)) count += 1; + simulatedOccupiedNames.add(fileName); } - for (const f of fileSet) { - try { - await getUploadMissionCfg({ - params: { - upload_dir: overridePath || currentPath.value, - daemonId: daemonId!, - uuid: instanceId!, - file_name: f.file.name - } - }); - if (!missionCfg.value) throw new Error(t("TXT_CODE_e8ce38c2")); + return count; + }; - const addr = parseForwardAddress(getFileConfigAddr(missionCfg.value), "http"); - uploadService.append( - f.file, - addr, - missionCfg.value.password, + const confirmUploadConflict = async ( + fileName: string, + conflictCount: number + ): Promise => { + const all = ref(false); + const overwrite = ref(false); + + const keep = await new Promise((onComplete) => { + Modal.confirm({ + title: t("TXT_CODE_99ca8563"), + icon: createVNode(ExclamationCircleOutlined), + content: createVNode( + OverwriteFilesPopUpContent, { - overwrite: f.overwrite + count: conflictCount, + fileName, + all, + overwrite, + "onUpdate:all": (val: boolean) => (all.value = val), + "onUpdate:overwrite": (val: boolean) => (overwrite.value = val) }, - (task) => { - task.instanceInfo = { - instanceId: instanceId || "", - daemonId: daemonId || "" + null + ), + okText: t("TXT_CODE_ae09d79d"), + cancelText: t("TXT_CODE_518528d0"), + onOk() { + onComplete(true); + }, + onCancel() { + onComplete(false); + } + }); + }); + + return { + keep, + overwrite: overwrite.value, + applyToAll: all.value + }; + }; + + const selectedFiles = async (files: File[], overridePath?: string) => { + const { state: missionCfg, execute: getUploadMissionCfg } = uploadAddress(); + const targetPath = overridePath || currentPath.value; + const uploadQueue: SelectedUploadFile[] = files.map((file) => ({ file, overwrite: false })); + + try { + const occupiedNames = await getExistingUploadNames(uploadQueue, targetPath); + const confirmedFiles: SelectedUploadFile[] = []; + let sharedDecision: Omit | undefined; + + for (let i = 0; i < uploadQueue.length; i++) { + const item = uploadQueue[i]; + const fileName = item.file.name; + const hasConflict = occupiedNames.has(fileName); + + if (hasConflict) { + const decision = sharedDecision + ? { ...sharedDecision, applyToAll: true } + : await confirmUploadConflict( + fileName, + countRemainingUploadConflicts(uploadQueue, i, occupiedNames) + ); + + if (decision.applyToAll) { + sharedDecision = { + keep: decision.keep, + overwrite: decision.overwrite }; } - ); - } catch (err: any) { - console.error(err); - return reportErrorMsg(err.response?.data || err.message); + + if (!decision.keep) continue; + item.overwrite = decision.overwrite; + } + + confirmedFiles.push(item); + occupiedNames.add(fileName); + } + + for (const f of confirmedFiles) { + try { + await getUploadMissionCfg({ + params: { + upload_dir: targetPath, + daemonId: daemonId!, + uuid: instanceId!, + file_name: f.file.name + } + }); + if (!missionCfg.value) throw new Error(t("TXT_CODE_e8ce38c2")); + + const addr = parseForwardAddress(getFileConfigAddr(missionCfg.value), "http"); + uploadService.append( + f.file, + addr, + missionCfg.value.password, + { + overwrite: f.overwrite + }, + (task) => { + task.instanceInfo = { + instanceId: instanceId || "", + daemonId: daemonId || "" + }; + } + ); + } catch (err: any) { + console.error(err); + return reportErrorMsg(err.response?.data || err.message); + } } + } catch (err: any) { + console.error(err); + return reportErrorMsg(err.response?.data || err.message); } }; diff --git a/frontend/src/services/apis/fileManager.ts b/frontend/src/services/apis/fileManager.ts index 4529113ea..fa942dfdd 100755 --- a/frontend/src/services/apis/fileManager.ts +++ b/frontend/src/services/apis/fileManager.ts @@ -182,6 +182,7 @@ export const uploadAddress = useDefineApi< upload_dir: string; daemonId: string; uuid: string; + file_name?: string; }; }, { @@ -197,15 +198,15 @@ export const uploadAddress = useDefineApi< export const uploadFile = useDefineApi< { params: - | { - overwrite: boolean; - filename: string; - size: number; - sum: string; - unzip?: boolean; - code?: string; - } - | { stop: boolean }; + | { + overwrite: boolean; + filename: string; + size: number; + sum: string; + unzip?: boolean; + code?: string; + } + | { stop: boolean }; }, { id?: string; From 3a67fcf139caa869307c98943fdada7110a3a9ce Mon Sep 17 00:00:00 2001 From: icebrick Date: Tue, 28 Apr 2026 16:57:14 +0800 Subject: [PATCH 135/256] fix: handle PTY toggle errors while instance is running --- .../widgets/instance/dialogs/TermConfig.vue | 19 ++++++++++++++++++- .../app/routers/instance_operate_router.ts | 2 +- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/frontend/src/widgets/instance/dialogs/TermConfig.vue b/frontend/src/widgets/instance/dialogs/TermConfig.vue index de19b0bec..94d2ce6bb 100755 --- a/frontend/src/widgets/instance/dialogs/TermConfig.vue +++ b/frontend/src/widgets/instance/dialogs/TermConfig.vue @@ -6,7 +6,7 @@ import type { InstanceDetail } from "@/types"; import { updateInstanceConfig } from "@/services/apis/instance"; import { message } from "ant-design-vue"; import { reportErrorMsg } from "@/tools/validator"; -import { TERMINAL_CODE } from "@/types/const"; +import { INSTANCE_STATUS_CODE, TERMINAL_CODE } from "@/types/const"; const props = defineProps<{ instanceInfo?: InstanceDetail; @@ -15,6 +15,7 @@ const props = defineProps<{ }>(); const emit = defineEmits(["update"]); const options = ref(); +const initialPty = ref(); const screen = useScreen(); const isPhone = computed(() => screen.isPhone.value); @@ -22,12 +23,28 @@ const open = ref(false); const openDialog = () => { open.value = true; options.value = props.instanceInfo; + initialPty.value = props.instanceInfo?.config.terminalOption?.pty; }; const { execute, isLoading } = updateInstanceConfig(); +const isChangingPtyWhileRunning = () => { + const previousPty = initialPty.value; + const currentPty = options.value?.config.terminalOption?.pty; + if (previousPty === undefined || currentPty === undefined || previousPty === currentPty) { + return false; + } + const status = options.value?.status ?? props.instanceInfo?.status; + if (status === undefined) return false; + return status !== INSTANCE_STATUS_CODE.STOPPED && status !== INSTANCE_STATUS_CODE.BUSY; +}; + const submit = async () => { try { + if (isChangingPtyWhileRunning()) { + return reportErrorMsg(t("TXT_CODE_instanceConf.cantModifyPtyModel")); + } + await execute({ params: { uuid: props.instanceId ?? "", diff --git a/panel/src/app/routers/instance_operate_router.ts b/panel/src/app/routers/instance_operate_router.ts index 73fdbe077..79102ded2 100755 --- a/panel/src/app/routers/instance_operate_router.ts +++ b/panel/src/app/routers/instance_operate_router.ts @@ -463,7 +463,7 @@ router.put( let advancedConfig = {}; advancedConfig = checkInstanceAdvancedParams(config, isTopPermission); - new RemoteRequest(remoteService).request("instance/update", { + await new RemoteRequest(remoteService).request("instance/update", { instanceUuid, config: { pingConfig: !isEmpty(config.pingConfig) ? pingConfig : null, From 3240b8c9daa033a87a04ad52717e147a683c17a6 Mon Sep 17 00:00:00 2001 From: icebrick Date: Tue, 28 Apr 2026 17:17:55 +0800 Subject: [PATCH 136/256] fix(i18n): register Turkish locale in panel and daemon --- daemon/src/i18n/index.ts | 4 ++++ panel/src/app/i18n/index.ts | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/daemon/src/i18n/index.ts b/daemon/src/i18n/index.ts index cb0b9bf5a..a5efc8995 100755 --- a/daemon/src/i18n/index.ts +++ b/daemon/src/i18n/index.ts @@ -14,6 +14,7 @@ import ko_KR from "@languages/ko_KR.json"; import de_DE from "@languages/de_DE.json"; import pt_BR from "@languages/pt_BR.json"; import th_TH from "@languages/th_TH.json"; +import tr_TR from "@languages/tr_TR.json"; i18next.init({ interpolation: { @@ -54,6 +55,9 @@ i18next.init({ }, th_th: { translation: th_TH + }, + tr_tr: { + translation: tr_TR } } }); diff --git a/panel/src/app/i18n/index.ts b/panel/src/app/i18n/index.ts index ae3ccd55d..751ae4f60 100755 --- a/panel/src/app/i18n/index.ts +++ b/panel/src/app/i18n/index.ts @@ -14,6 +14,7 @@ import ko_KR from "@languages/ko_KR.json"; import de_DE from "@languages/de_DE.json"; import pt_BR from "@languages/pt_BR.json"; import th_TH from "@languages/th_TH.json"; +import tr_TR from "@languages/tr_TR.json"; i18next.init({ interpolation: { @@ -54,6 +55,9 @@ i18next.init({ }, th_TH: { translation: th_TH + }, + tr_tr: { + translation: tr_TR } } }); From 8157b9ec2cadec40e29d3339143fa0bf7cc9efc6 Mon Sep 17 00:00:00 2001 From: icebrick Date: Tue, 28 Apr 2026 17:37:46 +0800 Subject: [PATCH 137/256] fix(frontend): remove misleading stop button in build progress --- frontend/src/widgets/imageManager/BuildProgress.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/widgets/imageManager/BuildProgress.vue b/frontend/src/widgets/imageManager/BuildProgress.vue index b6db99bb1..1dffe046f 100755 --- a/frontend/src/widgets/imageManager/BuildProgress.vue +++ b/frontend/src/widgets/imageManager/BuildProgress.vue @@ -79,7 +79,6 @@ defineExpose({ From 9a61b578a06993ddecc03bbdacf2293c73a55e49 Mon Sep 17 00:00:00 2001 From: xiaosu Date: Tue, 28 Apr 2026 19:43:49 +0800 Subject: [PATCH 138/256] feat: Implement folder upload and manual path editing - Support client-side folder compression and upload - Optimize file conflict resolution dialog - Support manual path editing and navigation - Add auto-delete after unzip parameter to the upload API --- daemon/src/entity/file_writer.ts | 34 +++- daemon/src/routers/http_router.ts | 11 +- daemon/src/service/system_file.ts | 14 +- frontend/components.d.ts | 1 + frontend/package-lock.json | 12 ++ frontend/package.json | 1 + .../components/OverwriteFilesPopUpContent.vue | 47 +++-- frontend/src/hooks/useFileManager.ts | 187 ++++++++++++++---- frontend/src/services/uploadService.ts | 1 + frontend/src/tools/folderUploader.ts | 85 ++++++++ frontend/src/widgets/instance/FileManager.vue | 180 ++++++++++++++--- languages/en_US.json | 11 +- languages/zh_CN.json | 11 +- 13 files changed, 488 insertions(+), 107 deletions(-) create mode 100644 frontend/src/tools/folderUploader.ts diff --git a/daemon/src/entity/file_writer.ts b/daemon/src/entity/file_writer.ts index 59b835cf7..334ba5b49 100644 --- a/daemon/src/entity/file_writer.ts +++ b/daemon/src/entity/file_writer.ts @@ -4,29 +4,34 @@ import * as lockfile from "proper-lockfile"; import logger from "../service/log"; import FileManager from "../service/system_file"; import uploadManager from "../service/upload_manager"; +import { globalEnv } from "./config"; +import Instance from "./instance/instance"; type ChunkRange = { start: number; end: number }; export default class FileWriter { readonly path: string; id?: string; + cwd?: string; private releaseLock?: () => Promise; private fd: number | null = null; readonly received: ChunkRange[] = []; lastUpdate: number = Date.now(); constructor( - public readonly cwd: string, + public readonly instance: Instance, private filename: string, public readonly size: number, private unzip: boolean, private zipCode: string, - filePath: string + filePath: string, + private deleteAfterUnzip: boolean = false ) { if (!FileManager.checkFileName(path.basename(this.filename))) throw new Error("Access denied: Malformed file name"); this.path = filePath; + this.cwd = instance.absoluteCwdPath(); } static async getPath(cwd: string, dir: string, filename: string, overwrite: boolean) { @@ -119,9 +124,28 @@ export default class FileWriter { logger.info("Browser Uploaded File:", this.path); if (this.unzip) { - const instanceFiles = new FileManager(this.cwd); - await instanceFiles.unzip(this.path, ".", this.zipCode); - logger.info("File unzipped:", this.path); + // Statistics of the number of tasks in a single instance file and the number of tasks in the entire daemon process + + globalEnv.fileTaskCount++; + if (this.instance) this.instance.info.fileLock++; + + try { + logger.info("Browser Uploaded File:", this.path); + + const instanceFiles = new FileManager(this.instance.absoluteCwdPath()); + await instanceFiles.unzip(this.path, ".", this.zipCode); + logger.info("File unzipped:", this.path); + + if (this.deleteAfterUnzip) { + await fs.remove(this.path); + logger.info("Temporary zip deleted:", this.path); + } + } catch (e) { + logger.error("Operation after upload failed:", e); + } finally { + globalEnv.fileTaskCount--; + if (this.instance) this.instance.info.fileLock--; + } } } diff --git a/daemon/src/routers/http_router.ts b/daemon/src/routers/http_router.ts index 1edfb19f2..fcdff11df 100755 --- a/daemon/src/routers/http_router.ts +++ b/daemon/src/routers/http_router.ts @@ -137,6 +137,7 @@ router.post("/upload-new/:key", async (ctx) => { const zipCode = String(ctx.query.code); const filename = String(ctx.query.filename); const size = Number(ctx.query.size); + const deleteAfterUnzip = Boolean(ctx.query.deleteAfterUnzip); if (ctx.query.stop) { const writer = uploadManager.get(key); if (writer) { @@ -166,7 +167,15 @@ router.post("/upload-new/:key", async (ctx) => { fr = undefined; } if (!fr) { - const fileWriter = new FileWriter(cwd, filename, size, unzip, zipCode, filePath); + const fileWriter = new FileWriter( + instance, + filename, + size, + unzip, + zipCode, + filePath, + deleteAfterUnzip + ); await fileWriter.init(); const id = uploadManager.add(fileWriter); fr = { id, writer: fileWriter }; diff --git a/daemon/src/service/system_file.ts b/daemon/src/service/system_file.ts index a50a10305..5fff312e4 100755 --- a/daemon/src/service/system_file.ts +++ b/daemon/src/service/system_file.ts @@ -22,7 +22,10 @@ interface IFile { export default class FileManager { public cwd: string = "."; - constructor(public topPath: string = "", public fileCode?: string) { + constructor( + public topPath: string = "", + public fileCode?: string + ) { if (!path.isAbsolute(topPath)) { this.topPath = path.normalize(path.join(process.cwd(), topPath)); } else { @@ -57,11 +60,10 @@ export default class FileManager { finalPath = path.normalize(path.join(this.topPath, this.cwd, fileName)); } - if ( - finalPath.indexOf(topAbsolutePath) !== 0 && - topAbsolutePath !== "/" && - topAbsolutePath !== "\\" - ) + // fix the /app/ vs /app mismatch bug and keep it secure + const relative = path.relative(topAbsolutePath, finalPath); + const isOutside = relative.startsWith("..") || path.isAbsolute(relative); + if (isOutside && topAbsolutePath !== "/" && topAbsolutePath !== "\\") throw new Error(ERROR_MSG_01); return finalPath; } diff --git a/frontend/components.d.ts b/frontend/components.d.ts index 0e10074d2..b4eb3701d 100644 --- a/frontend/components.d.ts +++ b/frontend/components.d.ts @@ -51,6 +51,7 @@ declare module 'vue' { AppHeader: typeof import('./src/components/AppHeader.vue')['default'] AppSidebarMenu: typeof import('./src/components/AppSidebarMenu.vue')['default'] AProgress: typeof import('ant-design-vue/es')['Progress'] + ARadio: typeof import('ant-design-vue/es')['Radio'] ARadioButton: typeof import('ant-design-vue/es')['RadioButton'] ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup'] AResult: typeof import('ant-design-vue/es')['Result'] diff --git a/frontend/package-lock.json b/frontend/package-lock.json index b38596d0e..e571b32ad 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -37,6 +37,7 @@ "dayjs": "^1.11.9", "echarts": "^5.4.3", "eventemitter3": "^5.0.1", + "fflate": "^0.8.2", "i18next-scanner": "^4.3.0", "lodash": "^4.17.23", "marked": "^7.0.3", @@ -4980,6 +4981,12 @@ "reusify": "^1.0.4" } }, + "node_modules/fflate": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", + "license": "MIT" + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -13816,6 +13823,11 @@ "reusify": "^1.0.4" } }, + "fflate": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==" + }, "file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", diff --git a/frontend/package.json b/frontend/package.json index a6621db9c..13d3c363f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -41,6 +41,7 @@ "dayjs": "^1.11.9", "echarts": "^5.4.3", "eventemitter3": "^5.0.1", + "fflate": "^0.8.2", "i18next-scanner": "^4.3.0", "lodash": "^4.17.23", "marked": "^7.0.3", diff --git a/frontend/src/components/OverwriteFilesPopUpContent.vue b/frontend/src/components/OverwriteFilesPopUpContent.vue index c8c97db2a..cf2de0a73 100755 --- a/frontend/src/components/OverwriteFilesPopUpContent.vue +++ b/frontend/src/components/OverwriteFilesPopUpContent.vue @@ -5,37 +5,48 @@ import { computed } from "vue"; const props = defineProps<{ count?: number; fileName: string; - all?: boolean; - overwrite: boolean; + all: boolean; + action: string; }>(); const emit = defineEmits<{ + (e: "update:action", value: string): void; (e: "update:all", value: boolean): void; - (e: "update:overwrite", value: boolean): void; }>(); -const overwriteRef = computed({ - get: () => props.overwrite, - set: (value: boolean) => emit("update:overwrite", value) +const actionModel = computed({ + get: () => props.action, + set: (v) => emit("update:action", v) }); -const allRef = computed({ + +const allModel = computed({ get: () => props.all, - set: (value: boolean) => emit("update:all", value) + set: (v) => emit("update:all", v) });