fb5-patch-pkg: the update package's boot step and install check (server/update.js) — before the server starts (runMain: npm start, launch.mjs, the Windows service's run-server.cmd, NSSM, systemd; launch.mjs also before setup) an extracted UPDATE.json is checked: malformed → logged and skipped; the install verified against MANIFEST.json, and a missing or different file the server or browser runs stops the start with the bilingual "download the full package" message (nothing deleted, UPDATE.json kept); else each removed file still holding a base's bytes is deleted (never a changed file, a player's pack, a symlink, a per-machine name or a path outside the install) and UPDATE.json becomes .update-applied.json; doctor gets a MANIFEST.json row; test/update-boot.test.js (10)
This commit is contained in:
1 parent
0b306baa49
commit
d6e40c7235
6 files changed
+710
-7
No files matched your search
+17
-1
@@ -3,7 +3,9 @@
|
||||
//
|
||||
// node tools/doctor.mjs [--port 3000] [--host 0.0.0.0]
|
||||
//
|
||||
// Checks: Node/npm versions, dependencies, public/vendor, data/*.json, downloaded art/audio, optional local-client art,
|
||||
// Checks: Node/npm versions, dependencies, public/vendor, data/*.json, the shipped files against the release's
|
||||
// MANIFEST.json (server/update.js checkInstall; a source checkout has none) and an update package not applied yet,
|
||||
// downloaded art/audio, optional local-client art,
|
||||
// Python (only needed for the optional extraction), the port (free / our server running → /healthz / another
|
||||
// program), LAN addresses friends can use (virtual adapters and VPNs labelled), firewall hints per OS, tunnel tools
|
||||
// (Tailscale, ZeroTier, cloudflared) and the env vars the server reads.
|
||||
@@ -20,6 +22,7 @@ import {
|
||||
checkNode, checkDeps, checkVendor, checkData, checkAssets, checkLocal, findClient, findPython,
|
||||
LOCAL_ART_FALLBACK, LOCAL_ART_COPY_HINT,
|
||||
} from './setup.mjs';
|
||||
import { checkInstall, MANIFEST_FILE, UPDATE_FILE } from '../server/update.js';
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------
|
||||
// LAN addresses (also used by scripts/launch.mjs)
|
||||
@@ -184,6 +187,19 @@ async function main() {
|
||||
row(vendor.ok ? 'ok' : 'err', '前端库 public/vendor', vendor.ok ? (vendor.optionalMissing.length ? 'three.js 缺失(3D 棋盘回退 2D)' : '') : `缺少 ${vendor.missing.join(', ')} → node tools/vendor.mjs`);
|
||||
const data = checkData();
|
||||
row(data.ok ? 'ok' : 'err', '游戏数据 data/*.json', data.ok ? '' : `缺少/损坏:${[...data.missing, ...data.broken].join(', ')}`);
|
||||
// the release's file list (every package has one; art is setup's and is checked below)
|
||||
const inst = checkInstall(ROOT);
|
||||
const instLabel = `文件校验 ${MANIFEST_FILE}`;
|
||||
if (inst.state === 'none') row('skip', instLabel, '没有:源码目录,不校验');
|
||||
else if (inst.state === 'broken') row('warn', instLabel, `无法读取(${inst.error})→ 重新解压同一版本的整合包`);
|
||||
else if (inst.state === 'ok') row('ok', instLabel, `${inst.checked} 个文件与 v${inst.app} 一致`);
|
||||
else {
|
||||
const bad = [...inst.runtime, ...inst.other];
|
||||
const eg = bad.slice(0, 3).join(' ') + (bad.length > 3 ? ' …' : '');
|
||||
row(inst.runtime.length ? 'err' : 'warn', instLabel, `${bad.length} 个文件与 v${inst.app} 不一致或缺失(例:${eg})`
|
||||
+ (inst.runtime.length ? ` → 重新解压 v${inst.app} 的完整包(或它的更新包)` : ':只是说明 / 脚本文件,不影响运行'));
|
||||
}
|
||||
if (inst.pending) row('warn', `更新包 ${UPDATE_FILE}`, '已解压、还没有应用:下次启动服务器时自动应用');
|
||||
const assets = checkAssets();
|
||||
row(assets.ok ? 'ok' : 'warn', '美术/音频 public/assets', assets.ok ? `${assets.total} 个文件`
|
||||
: !assets.present ? '未下载 → node tools/setup.mjs(游戏仍可运行,使用占位图)' : `缺 ${assets.missing}/${assets.total}(例:${assets.sample.join(' ')})→ node tools/setup.mjs`);
|
||||
|
||||
Reference in new issue
Block a user