// modelservice.js - 模型/对象服务协议(module_29554)的语义层 // // 出处:src/module_29554.js。客户端 `U.q7i(methodId, reader)` 按 methodId 分发 4 条 s2c: // _loadDependencies → K{ callbackId i32, resources list } // _loadObjectsData → W{ modelsData list>, objects list> } // _setModelCommandAlias → alias + 两个 i64(告诉客户端「某 gameType 由某 methodId 承载」) // _unloadObjects → objects // 客户端 → 服务端只有一条:`G.q1wd`(见下),负载实测 4 字节 i32。 // // 实测结论(命名/语义对应,标定过): // 这 4 条命令的 methodId 就是 names/method_table.json 里 4 条 `_t` / codec=`lt` 的行, // 而它们的**真实负载布局是容器的 zt 形状**(method_table 的 `Codec` 列在这几行上是错的,见 container.js 头注)。 // 空间 100045260 认证后那 3 帧,前两帧正好是 _loadDependencies 与 _loadObjectsData。 'use strict'; const fs = require('fs'); const path = require('path'); // 语义表:methodId(十进制字符串)→ 名字 + 方向 const METHOD = { '3216143066888387731': { Name: '_loadDependencies', Dir: 's2c' }, '7640916300855664666': { Name: '_loadObjectsData', Dir: 's2c' }, '8179162314198150518': { Name: '_setModelCommandAlias', Dir: 's2c' }, '9038756763225879447': { Name: '_unloadObjects', Dir: 's2c' }, '1816792453857564692': { Name: 'G.q1wd(客户端请求对象数据)', Dir: 'c2s' }, }; function Name(MethodId) { const M = METHOD[String(MethodId)]; return M ? M.Name : null; } // G.q1wd 的请求负载:实测 4 字节大端 i32(老注释里写的 ObjectsData 结构对不上字节,故按实测来) function DescribeRequest(Payload) { if (Payload.length === 4) return { Kind: 'i32', Value: Payload.readInt32BE(0) }; return { Kind: '未知', Hex: Payload.toString('hex').slice(0, 64) }; } // 从 method_table.json 里把这 4 行的模型名/ModelId 也读出来,便于日志与后续建表 function LoadRows(NamesDir) { const P = path.join(NamesDir, 'method_table.json'); if (!fs.existsSync(P)) return []; const J = JSON.parse(fs.readFileSync(P, 'utf8')); return (J.Rows || []).filter((R) => METHOD[String(R.MethodId)]); } module.exports = { METHOD, Name, DescribeRequest, LoadRows };