From 5721158e6cd024a8edac988c32fe3d4b8057de9c Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Wed, 21 Oct 2026 01:38:56 +0800 Subject: [PATCH] =?UTF-8?q?feat(tools):=20dump=20=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E6=8C=89=20modelId=20=E5=90=88=E5=B9=B6=EF=BC=8C=E8=B7=A8?= =?UTF-8?q?=E4=BC=9A=E8=AF=9D=E7=B4=AF=E7=A7=AF=E6=B3=A8=E5=86=8C=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 3DTank/tools/serve.js | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) 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);