const fs = require('fs'); const path = require('path'); const logger = require('./logger'); const defaultConfig = { server: { port: 60961, host: '0.0.0.0' } }; function resolveConfigPaths() { const isPackaged = !!process.pkg; const exeDir = isPackaged ? path.dirname(process.execPath) : __dirname; const cwd = process.cwd(); const explicit = process.env.CONFIG_PATH && process.env.CONFIG_PATH.trim() ? path.resolve(process.env.CONFIG_PATH.trim()) : null; const candidates = []; if (explicit) candidates.push(explicit); // 优先:可执行文件所在目录(适用于 pkg 打包后的 exe 同目录) candidates.push(path.join(exeDir, 'config.json')); // 其次:当前工作目录(命令行运行时常用) candidates.push(path.join(cwd, 'config.json')); // 最后:源码目录(开发环境默认) candidates.push(path.join(__dirname, 'config.json')); return { candidates, isPackaged, exeDir }; } function loadConfig() { const { candidates, isPackaged, exeDir } = resolveConfigPaths(); let userConfig = {}; let usedPath = null; for (const p of candidates) { try { if (fs.existsSync(p)) { const raw = fs.readFileSync(p, 'utf-8'); userConfig = JSON.parse(raw); usedPath = p; break; } } catch (err) { logger.warn('读取配置路径失败,尝试下一个', { 路径: p, 错误: err.message }); } } if (usedPath) { logger.info('已加载配置文件', { 路径: usedPath, 打包运行: isPackaged, 可执行目录: exeDir }); } else { logger.warn('未找到配置文件,使用默认配置', { 打包运行: isPackaged, 可执行目录: exeDir }); } const cfg = { ...defaultConfig }; if (userConfig && typeof userConfig === 'object') { if (userConfig.server && typeof userConfig.server === 'object') { const s = userConfig.server; if (typeof s.port === 'number' && Number.isFinite(s.port)) { cfg.server.port = s.port; } if (typeof s.host === 'string' && s.host.trim()) { cfg.server.host = s.host.trim(); } } } if (process.env.PORT) { const envPort = Number(process.env.PORT); if (Number.isFinite(envPort) && envPort > 0 && envPort < 65536) { cfg.server.port = envPort; logger.info('使用环境变量 PORT 覆盖端口', { port: envPort }); } else { logger.warn('环境变量 PORT 无效,忽略', { PORT: process.env.PORT }); } } if (process.env.HOST && process.env.HOST.trim()) { cfg.server.host = process.env.HOST.trim(); logger.info('使用环境变量 HOST 覆盖主机', { host: cfg.server.host }); } return cfg; } module.exports = { loadConfig };