// enum_names.js - 枚举线形序数 → 成员名(**仅日志/展示用**;原始值一律不改) // // 为什么单独一个模块:协议里的 enum 在线上只有 4 字节 i32,解出来只有线形序数 `enum#N` // (口径见 tools/lib_space_codec.js)。真实客户端知道成员名,证据在 names/evidence.json: // byModule..enums = { <枚举短名>: [ {field, member, value}, … ] } // 本模块按需把它读进内存,供服务端日志把 `enum#N` 翻成「成员名(enum#N)」。 // **不参与任何解码/编码/落库**:Items.Category 等列里存的仍是原始令牌,一字不改。 // // 目前只做「物品装备槽类别」这一个枚举(服务端日志只用到它): // 字段所在 codec = module_85196::Lo,线形 type = `enum`;ja 定义在 module_85667(TypeCodec=module_85667::pu)。 'use strict'; const fs = require('fs'); const path = require('path'); const NAMES_DIR = path.resolve(__dirname, '..', '..', 'names'); const CATEGORY = { Module: '85667', Short: 'ja' }; let MemberByValue = null; // 懒加载(证据文件约 1MB;只有真要打日志时才读,读不到就按「未解」回退,绝不猜) function Ensure() { if (MemberByValue) return MemberByValue; MemberByValue = new Map(); try { const Ev = JSON.parse(fs.readFileSync(path.join(NAMES_DIR, 'evidence.json'), 'utf8')); const Members = ((((Ev.byModule || {})[CATEGORY.Module] || {}).enums) || {})[CATEGORY.Short] || []; for (const M of Members) if (!MemberByValue.has(String(M.value))) MemberByValue.set(String(M.value), String(M.member)); } catch (Err) { // 证据不可用:保持空表,CategoryLabel 会如实写「未解」 } return MemberByValue; } // 'enum#1' → 'ARMOR(enum#1)';空/NULL → '未知';查不到 → 'enum#1(未解)' function CategoryLabel(Raw) { if (Raw === null || Raw === undefined || Raw === '') return '未知'; const S = String(Raw); const M = /^enum#(-?\d+)$/.exec(S); const Name = M ? Ensure().get(M[1]) : null; return Name ? Name + '(' + S + ')' : S + '(未解)'; } module.exports = { CategoryLabel, CATEGORY };