Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
65 lines
6.1 KiB
JSON
65 lines
6.1 KiB
JSON
{
|
||
"_comment": "gameabc.min.js 逆向结果(PoC 阶段 1, 2026-09-02). 数据源权威: 下游消费方不得猜测/修补/兜底, unknown → throw.",
|
||
"spirit_types": {
|
||
"0": {
|
||
"component": "cc.Sprite",
|
||
"note": "普通精灵; _type=0 (SIMPLE), _sizeMode=0",
|
||
"evidence": "Game_Surface_3 save/Layer*.xml 中 type=0 的 spirit 均含 ImgResID (sprite 图集索引) + BelongGroupID, 无独有属性; YouleNexus Login_Layer.prefab 的普通 sprite (_type=0, _sizeMode=0) 与 type=0 spirit 一一对应"
|
||
},
|
||
"1": {
|
||
"component": "cc.Label",
|
||
"note": "文本标签; 含 Text/FontSize/AlignHorz/FontColor/BackColor 等独有属性",
|
||
"evidence": "Game_Surface_3 中 type=1 spirit 独有 Text/FontSize/FontBold/FontColor/BackColor/AlignHorz/AlignVert/AutoSize/WordWrap/LineSpace/TextStyle 这 11 个属性; 全量 XML 解析 38/55 Layer 含 type=1; 与 YouleNexus Login_Layer 中 cc.Label 节点字段对齐"
|
||
},
|
||
"3": {
|
||
"component": "cc.ProgressBar",
|
||
"note": "进度条; 含 Frame 属性 (frame=进度 0-1 范围 或 frame id)",
|
||
"evidence": "Game_Surface_3 中 type=3 spirit 独有 Frame 属性 (例如 Layer00002 'Spirit3254' Frame=进度条); 45/55 Layer 含 type=3; 与 YouleNexus Login_Layer.prefab 中 '进度条底' cc.ProgressBar 节点对应"
|
||
},
|
||
"4": {
|
||
"component": "cc.EditBox",
|
||
"note": "文本输入框; 独有属性 FrameText (默认/显示文本); CanClick=1; 含 ImgResID (背景图); CanDragSize=0",
|
||
"evidence": "Game_Surface_3 中 type=4 spirit 独有 FrameText 属性 (e.g. Layer00029 phoneInfo Spirit3246 FrameText='12' Spirit3247 FrameText='1' / Layer00014 Pay_Layer Spirit446 FrameText='12'); 15/55 Layer 含 type=4; YouleNexus Group106_PhoneVerify.prefab (映射到 Layer00029.xml phoneInfo) 含 1 个 cc.EditBox 节点, 与 type=4 的 FrameText 输入框语义一致 (phoneInfo 是手机号/验证码输入场景)",
|
||
"uncertainty_note": "Best-fit mapping only. Pay_Layer (Layer00014) has 11 type=4 spirits (id 446-455, ALL ImgResID=191, W=52 H=32) that look like repeated Button placeholders (amount shortcuts: 100/200/500/1000 元) rather than EditBox. Layer00012 (CombatLayer) type=4 (W=14 H=22) and Layer00006 type=4 (W=17 H=28) similarly narrow. PhoneInfo (Layer00029) W=42/21 H=28 matches EditBox input field geometry. If PoC 2 reveals type=4 should map to cc.Button (FrameText='12' could be 'amount shortcut button text'), update this entry + rerun Task 6 (mapSpiritTypeToComponent)."
|
||
},
|
||
"5": {
|
||
"component": "cc.Sprite",
|
||
"note": "9-slice 缩放精灵; 独有属性 LeftEdge/TopEdge/RightEdge/BottomEdge (4 个边缘宽度); CanClick=1, CanDragSize=1; Cocos 映射: cc.Sprite._type = 1 (SLICED)",
|
||
"evidence": "Game_Surface_3 中 type=5 spirit 独有 LeftEdge/TopEdge/RightEdge/BottomEdge 属性 (Layer00002 Spirit159 (100/80/100/80, 隐式) / Layer00006 Spirit287 (70/1/70/1) / Layer00017 '个人信息背景' (70/70/70/70) / Layer00609 '设置背景' (100/134/100/135) / Layer00612 Tips_Layer 5 个 type=5 边缘容器); 39/55 Layer 含 type=5; YouleNexus Login_Layer.prefab 中唯一一个 cc.Sprite._type=1 (SLICED) 节点的 _contentSize 是 370×170, 严格匹配 Layer00002 Spirit159 Width=370 Height=170 — 同一个节点, 1:1 对应; YouleNexus Layer609_Setting.prefab 中 cc.Sprite._type=1 对应 Layer00609 '设置背景' (9-slice 边缘切片背景); 4 个边缘宽度正是 9-slice 缩放 slice 区域定义"
|
||
}
|
||
},
|
||
"size_calc_mode": {
|
||
"_comment": "55 个 Layer 全量解析: 只观察到 SizeCalcMode = 0 和 2 两种值; 0 直接读 Width/Height, 2 通过 SizeParentID 引用父 Spirit 尺寸再乘以 SizeRelaWidth/SizeRelaHeight (万分比) 比率; WidthCalcMode/HeightCalcMode=1 表示启用相对宽度/高度 (SizeRelaXxx 字段), =0 表示使用 Width/Height 自身.",
|
||
"0": {
|
||
"formula": "_contentSize = { width: parseFloat(Spirit.Width), height: parseFloat(Spirit.Height) }",
|
||
"rationale": "直接读精灵自身 Width/Height 字段作为 _contentSize; gameabc.min.js 中 SizeCalcMode=0 是最简路径 (背景图 Layer00001/00002 全屏 1280×720 即此路径)"
|
||
},
|
||
"2": {
|
||
"formula": "image_natural_size = lookup gameabc_Image.json ImageFileList[imgResID === Spirit.ImgResID].w_all/h_all; parent_size = { width: image_natural_size.width, height: image_natural_size.height }; _contentSize = { width: parent_size.width * Spirit.SizeRelaWidth / 10000, height: parent_size.height * Spirit.SizeRelaHeight / 10000 }; 当 WidthCalcMode=0 时回退到 Spirit.Width (parseFloat), 当 WidthCalcMode=1 时用 SizeRelaWidth 公式; HeightCalcMode 同理",
|
||
"rationale": "Layer00001 '友乐背景' (SizeCalcMode=2, SizeParentID=21, SizeRelaWidth=10000) / Layer00002 '微信登录背景' (SizeCalcMode=2, SizeParentID=20, SizeRelaWidth=10000) 全量采样: 全部 WidthCalcMode=1, HeightCalcMode=1, SizeRelaWidth=10000, SizeRelaHeight=10000; 即按 100% 比例继承父 spirit 尺寸; 这种 pattern 用于 '充满父容器' 的背景 (1280×720 全屏背景), SizeParentID 指向另一个 1280×720 的 spirit"
|
||
}
|
||
},
|
||
"width_calc_mode": {
|
||
"0": "use Spirit.Width directly (直接读 Width)",
|
||
"1": "use parent_size.width * Spirit.SizeRelaWidth / 10000 (按父尺寸比例计算)"
|
||
},
|
||
"height_calc_mode": {
|
||
"0": "use Spirit.Height directly (直接读 Height)",
|
||
"1": "use parent_size.height * Spirit.SizeRelaHeight / 10000 (按父尺寸比例计算)"
|
||
},
|
||
"coord_self_pos": {
|
||
"_note": "原 X, Y 是精灵左上角绝对屏幕坐标 (基于 1280x720); Cocos 用中心锚点",
|
||
"cocos_lpos_x": "original_X + original_W/2 - 640",
|
||
"cocos_lpos_y": "360 - (original_Y + original_H/2)",
|
||
"coord_self_pos_mode": {
|
||
"_note": "CoordSelfPos=0 在 55 个 Layer 全量中占绝对多数; CoordSelfPos > 0 的精灵 (例如相对父节点的偏移) 暂未观察到案例, 公式留 follow-up",
|
||
"0": "use X/Y 作为相对父节点偏移 (直接读, 见 coord_self_pos 公式)"
|
||
}
|
||
},
|
||
"anchor_point": {
|
||
"cocos_default": { "x": 0.5, "y": 0.5 },
|
||
"original_default": "左上角 (0, 0)",
|
||
"evidence": "Login_Layer '渠道logo' 节点 (原 734,143,59,148) → Cocos _lpos (123.5, 143, 0) 1:1 匹配, 锚点 (0.5, 0.5) 验证通过"
|
||
}
|
||
}
|