diff --git a/3DTank/tools/serve.js b/3DTank/tools/serve.js index 2eaf25a..f3a7a03 100644 --- a/3DTank/tools/serve.js +++ b/3DTank/tools/serve.js @@ -254,6 +254,9 @@ const Server = http.createServer((Req, Res) => { const UrlPath = Req.url.split('#')[0]; // 浏览器 → 本地落盘:控制台脚本把 dump 结果 POST 上来,写到 names/ 下 // 用法(控制台):fetch('/__dump__/regdump.json', {method:'POST', body: JSON.stringify(x)}) + // *.json 且新旧都是 {entries:[{modelId,...}]} 形态时**按 modelId 合并**: + // modelId → codec 是懒注册的(进车库/商店/战局各注册一批),每个页面会话的累积集不同, + // 直接覆盖会把上一轮的注册表冲掉;合并后刷新/关页都不丢数据。 if (Req.method === 'POST' && UrlPath.startsWith('/__dump__/')) { const Name = path.basename(decodeURIComponent(UrlPath.slice('/__dump__/'.length))).replace(/[^\w.\-]/g, '_') || 'dump.json'; const Out = path.join(PROJECT, 'names', Name); @@ -261,10 +264,43 @@ const Server = http.createServer((Req, Res) => { Req.on('data', (C) => Chunks.push(C)); Req.on('end', () => { try { - const Buf = Buffer.concat(Chunks); + let Buf = Buffer.concat(Chunks); + let Merged = 0; + if (/\.json$/i.test(Name)) { + try { + const NewObj = JSON.parse(Buf.toString('utf8')); + if (NewObj && Array.isArray(NewObj.entries)) { + let OldObj = null; + try { + OldObj = JSON.parse(fs.readFileSync(Out, 'utf8')); + } catch (E) { + OldObj = null; + } + if (OldObj && Array.isArray(OldObj.entries)) { + const Seen = new Set(); + const All = []; + const Push = (E) => { + if (!E || E.modelId === undefined || Seen.has(String(E.modelId))) return; + Seen.add(String(E.modelId)); + All.push(E); + }; + OldObj.entries.forEach(Push); + NewObj.entries.forEach(Push); + Merged = All.length - NewObj.entries.length; + NewObj.entries = All; + NewObj.count = All.length; + NewObj.mergedFrom = OldObj.count; + Buf = Buffer.from(JSON.stringify(NewObj), 'utf8'); + } + } + } catch (E) { + // 不是 JSON 或不是该形态:原样落盘 + } + } fs.mkdirSync(path.dirname(Out), { recursive: true }); fs.writeFileSync(Out, Buf); - console.log('[dump] 已写入 ' + Out + '(' + Buf.length + ' 字节)'); + console.log('[dump] 已写入 ' + Out + '(' + Buf.length + ' 字节' + + (Merged ? ',合并新增 ' + Merged + ' 条' : '') + ')'); Res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' }).end('saved ' + Name + ' ' + Buf.length); } catch (Err) { console.log('[dump] 写入失败: ' + Err.message);