44 lines
2.0 KiB
JavaScript
44 lines
2.0 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 };
|
|
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 };
|