53 lines
2.5 KiB
JavaScript
53 lines
2.5 KiB
JavaScript
// 启动器与服务端共用的路径、配置校验。
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
function canonical(input) {
|
|
if (typeof input !== 'string' || !path.isAbsolute(input)) throw new Error('必须填写绝对路径');
|
|
let p = path.resolve(input);
|
|
const tail = [];
|
|
while (!fs.existsSync(p)) {
|
|
const parent = path.dirname(p);
|
|
if (parent === p) throw new Error('目录所在磁盘不存在');
|
|
tail.unshift(path.basename(p)); p = parent;
|
|
}
|
|
return path.join(fs.realpathSync.native(p), ...tail);
|
|
}
|
|
function samePath(a, b) { return canonical(a).toLowerCase() === canonical(b).toLowerCase(); }
|
|
function contains(a, b) {
|
|
const rel = path.relative(canonical(a).toLowerCase(), canonical(b).toLowerCase());
|
|
return rel === '' || (!rel.startsWith('..' + path.sep) && rel !== '..' && !path.isAbsolute(rel));
|
|
}
|
|
function validateConfig(config, gameDir) {
|
|
const next = { ...config };
|
|
// 独立工作区可显式指定游戏;旧版放在游戏/aitemp 下的布局仍然可用。
|
|
if (next.gameDir !== undefined) {
|
|
next.gameDir = canonical(String(next.gameDir).trim());
|
|
for (const name of ['package.json', 'index.html']) {
|
|
const file = path.join(next.gameDir, name);
|
|
if (!fs.existsSync(file) || !fs.statSync(file).isFile()) throw new Error('游戏目录不完整,缺少:' + file);
|
|
}
|
|
gameDir = next.gameDir;
|
|
}
|
|
for (const key of ['cdpPort', 'webPort']) {
|
|
const n = Number(next[key]);
|
|
if (!Number.isInteger(n) || n < 1024 || n > 65535) throw new Error(`${key} 必须是 1024~65535 的整数`);
|
|
next[key] = n;
|
|
}
|
|
if (next.cdpPort === next.webPort) throw new Error('游戏调试端口和控制面板端口不能相同');
|
|
next.sandboxDir = canonical(String(next.sandboxDir || '').trim());
|
|
if (contains(gameDir, next.sandboxDir) || contains(next.sandboxDir, gameDir)) {
|
|
throw new Error('沙盒与原版目录必须完全分开,不能相同,也不能互相包含');
|
|
}
|
|
return next;
|
|
}
|
|
function readConfig(file, defaults, gameDir) {
|
|
let patch = {};
|
|
if (fs.existsSync(file)) {
|
|
try { patch = JSON.parse(fs.readFileSync(file, 'utf8')); }
|
|
catch { throw new Error('config.json 损坏,请修正配置后重试;不会静默换用其他目录'); }
|
|
}
|
|
return validateConfig({ ...defaults, ...patch }, gameDir);
|
|
}
|
|
module.exports = { canonical, samePath, contains, validateConfig, readConfig };
|