From 6072a30f89f4ada3fb192b58a492a5c2c40bff40 Mon Sep 17 00:00:00 2001 From: Maximus7474 Date: Sat, 18 Jul 2026 19:30:04 +0200 Subject: [PATCH 1/3] fix(core/routes/setup): use checkFXServerPaths to validate detected paths -> the basic check ignored if the path was a directory or file making the system believe it's valid when it isn't --- apps/core/src/routes/api/setup.ts | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/apps/core/src/routes/api/setup.ts b/apps/core/src/routes/api/setup.ts index a65a7cb..f7fce71 100644 --- a/apps/core/src/routes/api/setup.ts +++ b/apps/core/src/routes/api/setup.ts @@ -53,19 +53,22 @@ const SetupEndpoint: FastifyPluginAsync = async (fastify) => { ? cfg.serverConfigFile : path.join(cfg.serverDataPath, cfg.serverConfigFile); - const [executable, dataPath, cfgFound] = await Promise.all([ - fileExists(cfg.executablePath), - fileExists(cfg.serverDataPath), - fileExists(cfgPath), - ]); + const result = await ConfigManager.getInstance().checkFXServerPaths( + cfg.executablePath, + cfg.serverDataPath, + ); return { success: true, data: { - executable: cfg.executablePath, - dataPath: cfg.serverDataPath, - cfgPath, - found: { executable, dataPath, cfg: cfgFound }, + executable: result.files.executable, + dataPath: result.files.serverdata, + cfgPath: result.files.cfg, + found: { + executable: result.exists.executable, + dataPath: result.exists.serverdata, + cfg: result.exists.cfg, + }, }, } satisfies ApiResponse; }); From 63271b318f9691ebdb24f1cb7fa323c6c227b12a Mon Sep 17 00:00:00 2001 From: Maximus7474 Date: Sat, 18 Jul 2026 19:51:07 +0200 Subject: [PATCH 2/3] tweak(core/modules/config): added alpine paths for checking executable path validity --- apps/core/src/modules/config/manager.ts | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/apps/core/src/modules/config/manager.ts b/apps/core/src/modules/config/manager.ts index 0018853..4e977c3 100644 --- a/apps/core/src/modules/config/manager.ts +++ b/apps/core/src/modules/config/manager.ts @@ -142,10 +142,16 @@ export class ConfigManager { if (execStats.isDirectory()) { const validNames = process.platform === 'win32' - // cover both as a sanity check - ? ['fxserver.exe', 'FXServer.exe'] - // should only be FXServer, but just in case we do both - : ['fxserver', 'FXServer']; + ? // cover both as a sanity check + ['fxserver.exe', 'FXServer.exe'] + : // should only be FXServer, but just in case we do both + // we also cover the alpine path if omitted + [ + 'fxserver', + 'FXServer', + path.join('alpine', 'opt', 'cfx-server', 'fxserver'), + path.join('alpine', 'opt', 'cfx-server', 'FXServer'), + ]; for (const name of validNames) { const testPath = path.join(initialPath, name); @@ -165,9 +171,9 @@ export class ConfigManager { ? /^fxserver\.exe$/i : /^(fxserver|FXServer)$/; - if (validNames.test(fileName)) { - found = true; - } + if (validNames.test(fileName)) { + found = true; + } } } catch { found = false; From f2a07716ac6da2e7b16bbb18551547d037001aa6 Mon Sep 17 00:00:00 2001 From: Maximus7474 Date: Sat, 18 Jul 2026 19:58:30 +0200 Subject: [PATCH 3/3] chore(core/modules/config): update tests for checking linux executable --- apps/core/src/modules/config/manager.test.ts | 24 +++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/apps/core/src/modules/config/manager.test.ts b/apps/core/src/modules/config/manager.test.ts index f214fe7..77d2c80 100644 --- a/apps/core/src/modules/config/manager.test.ts +++ b/apps/core/src/modules/config/manager.test.ts @@ -236,7 +236,13 @@ describe('ConfigManager', () => { it('auto-detects Linux fxserver inside a valid directory', async () => { setPlatform('linux'); - const dirPath = path.join(process.cwd(), 'fxserver-folder'); + const dirPath = path.join( + process.cwd(), + 'fxserver', + 'alpine', + 'opt', + 'cfx-server', + ); const exePath = path.join(dirPath, 'fxserver'); fileSystem.set(dirPath, 'dir'); @@ -248,6 +254,22 @@ describe('ConfigManager', () => { expect(res.path).toBe(exePath); }); + it('auto-detects Linux fxserver from alpine path', async () => { + setPlatform('linux'); + const rootPath = path.join(process.cwd(), 'fxserver'); + const dirPath = path.join(rootPath, 'alpine', 'opt', 'cfx-server'); + const exePath = path.join(dirPath, 'fxserver'); + + fileSystem.set(rootPath, 'dir'); + fileSystem.set(dirPath, 'dir'); + fileSystem.set(exePath, 'file'); + + const config = ConfigManager.getInstance(); + const res = await config.validateExecutablePath(rootPath); + expect(res.valid).toBe(true); + expect(res.path).toBe(exePath); + }); + it('validates a direct file path (Case-Insensitive on Windows)', async () => { setPlatform('win32'); const exePath = path.join(process.cwd(), 'fXseRver.eXe');