Files
Spine_lab/tools/deobf/anchors.tsv
T
tianmo f40979f965 对照表:补 WidgetGroup 尺寸读取(min/pref/maxW/H) + 对话框显示不全/闪左下角的两个修正
- 弹窗建出来默认 150x150,正文和按钮被裁 → 显式设 width/height=max(pref,min,下限) 再 invalidate
- '先左下角再跳中间' = addActor 后过一帧才居中;改成尺寸+居中在同一次渲染回调里做完
names.tsv 338 条,payload-named.zip 已重产(5617 处引用)
2026-10-16 19:31:04 +08:00

353 lines
18 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 名字映射锚点(只放**已确定**的;每条都要能说清依据,依据写进 混淆名对照表.md)
# 列:owner name desc newName (desc 写 * 表示该 owner 下所有同名成员)
#
# ---- libGDX:Table(载荷名 et);依据 Obf.java + 直读字节码 ----
et D (Ldl;)LdR; add
et D ([Ldl;)Let; addAll
et I ()LdR; row
et Z (Z)V setFillParent
et SourceFile ()V clearChildren
et D (Ljava/lang/CharSequence;)LdR; addLabel
# ---- libGDX:Cell(载荷名 dR)----
dR StackMapTable ()LdR; expand
dR D ()LdR; fill
dR C ()LdR; left
dR S ()LdR; top
# ---- libGDX:Button / Label(保名类)----
com/badlogic/gdx/scenes/scene2d/ui/Button String ()Z isChecked
com/badlogic/gdx/scenes/scene2d/ui/Button I (Z)V setChecked
com/badlogic/gdx/scenes/scene2d/ui/Button B (ZZ)V setCheckedAndFire
com/badlogic/gdx/scenes/scene2d/ui/Button a_ (Z)V setDisabled
com/badlogic/gdx/scenes/scene2d/ui/Label D (Ljava/lang/CharSequence;)V setText
com/badlogic/gdx/scenes/scene2d/ui/Label D ()Ljava/lang/StringBuilder; getTextBuilder
# ---- libGDX:SelectBox(载荷名 KP);依据 DumpSites 解出的 (Ljava/lang/String;)V ----
KP B (Ljava/lang/String;)V setSelected
KP B ()Ljava/lang/String; getSelected
KP B (I)V setSelectedIndex
# ---- 场景模型:Gp = 骨骼;依据 gp_2.java 的 toString()/D(String,boolean)V ----
Gp D Ljava/lang/String; name
Gp D (Ljava/lang/String;Z)V setName
# ---- 场景模型:Gp = 骨骼的变换字段 ----
# 证据:用户在编辑器里把 root 转到 341.456 / 平移(-168,-116) / 缩放(0.8799,0.572) / 斜切(-52.221,-28.63),
# 面板 Inspector 同步显示 Z=-168.00009 V=-116.0 F=33.676704 Code=0.8799178 SourceFile=0.5720396
# StackMapTable=-52.220505 LineNumberTable=-28.629883 —— 一一对应,故确定语义。
Gp Z F x
Gp V F y
Gp F F rotation
Gp Code F scaleX
Gp SourceFile F scaleY
Gp StackMapTable F shearX
Gp LineNumberTable F shearY
# 【已作废·未定】静止姿态(rest pose)那一组(D/B/L/I/S/C 的 float)原本只是"值与默认姿态吻合"的推断,
# 2026-10-16 被 JSON 导出器证伪:导出器写 length 用的就是 Gp.C:F(见文件末尾"JSON 导出器"一节)。
# C 只能是 length,故整组推断不成立;这些字段的语义**目前未定**,不写进表里(宁可显示混淆名也不写错名)。
# Gp D F setupX
# Gp B F setupY
# Gp L F setupRotation
# Gp I F setupScaleX
# Gp S F setupScaleY
# 引用类字段:skeleton 由 hd.D(set, bone.D)+GP.D(LGp;) 的用法确定;parent 由创建骨骼时 bone.D=parent 确定
Gp D LGP; skeleton
Gp D LGp; parent
Gp B Lcom/badlogic/gdx/graphics/Color; color
# ---- 2026-10-16 setup pose 实测补充(用户拍照:root/bone/slot/region 四种对象)----
# 【已作废·未定】原写 Gp.Class:F=length / Ljava,java=worldScale*:都是"数值相等"的弱证据,
# 其中 length 已被 JSON 导出器改成 Gp.C:F(导出器写 length 时读的就是 C)。
# 剩下 Class/Ljava/java/init/String 这几个 float 导出器一个都没用,语义未定,不写进表。
# GU(插槽):面板 Slot 属性只有 Name/Color;Inspector 里 String D=mega_dg4、Gp D=所属骨骼
GU D Ljava/lang/String; name
GU D LGp; bone
# GO(region 附件 mega_dg4):面板只有 Image path/Color;Inspector 六个 float 与
# Region 附件的 旋转49.00014 / 缩放(1.997,1.335) / 宽高(157,154) 一一对应
GO S F rotation
GO L F scaleX
GO I F scaleY
GO C F width
GO Z F height
# ---- ScrollPane(保名类 com/badlogic/gdx/scenes/scene2d/ui/ScrollPane)----
# 依据:MapMethods 对 gdx-1.11.0 指纹比对(tools/deobf/anchors-libgdx.tsv 自动生成),
# 并且**踩过一次**:一直以为 B(ZZ)V 是 setForceScroll,传了 (false,true),
# 结果纵向滚动被关掉(那其实是 setScrollingDisabled(x,y))—— 现象就是"列表滚不动"。
com/badlogic/gdx/scenes/scene2d/ui/ScrollPane B (ZZ)V setScrollingDisabled
com/badlogic/gdx/scenes/scene2d/ui/ScrollPane L (FFFF)V scrollTo
com/badlogic/gdx/scenes/scene2d/ui/ScrollPane D (Ldl;)V addActor
com/badlogic/gdx/scenes/scene2d/ui/ScrollPane D (Ldl;Z)Z removeActor
# ---- ScrollPane / Cell 的滚动与尺寸方法(用于把面板列表改成可滚动;依据:MapMethods 指纹比对)----
# ScrollPane:B(ZZ)V=setScrollingDisabled、I(ZZ)V=setForceScroll、L(ZZ)V=setOverscroll
#(候选顺序 size/… 已核对;踩坑:把 B(ZZ) 当 setForceScroll 用,等于关掉纵向滚动)
com/badlogic/gdx/scenes/scene2d/ui/ScrollPane I (ZZ)V setForceScroll
com/badlogic/gdx/scenes/scene2d/ui/ScrollPane L (ZZ)V setOverscroll
# Cell 的 (F)LdR; 成组按声明顺序:B=size L=width I=height S=minWidth C=minHeight Z=prefWidth V=prefHeight
dR B (F)LdR; size
dR L (F)LdR; width
dR I (F)LdR; height
dR S (F)LdR; minWidth
dR C (F)LdR; minHeight
dR Z (F)LdR; prefWidth
dR V (F)LdR; prefHeight
# ---- Actor 的 Touchable(点击/进入命中相关;用于让 ScrollPane 收到鼠标进入→拿到 scroll focus)----
# 定位方式(不靠名字):`Actor.getTouchable()` = **无参且返回枚举**的那个方法;枚举类 = dv;
# libGDX Touchable 声明顺序 enabled/disabled/childrenOnly → 第 0 个常量就是 enabled。
# 现象佐证:ScrollPane 默认 childrenOnly 时自己不是命中目标,收不到 enter → 滚轮事件不会送到它,
# 但程序化 scrollY() 是生效的(实测 before=0 after=200)。
dl L (Ldv;)V setTouchable
# ---- Cell.height(2026-10-16 实测确认)----
# 依据:对 Cell 的候选 (float) 方法依次调用 900,等一帧后量"根表格高度":
# Cell.I(900) -> root 高度 580 -> 1080(其它候选 L/B/Z/V/C/S/F 都没这个效果)
# => Cell.I(float) 就是 height(float);现象佐证:设了它之后列表区出现滚动条、可滚。
dR I (F)LdR; height
# ---- Stage 宽高(2026-10-16 实测)----
# 依据:编辑器窗口 4K 下读 Stage 的无参 float 只有两个:B=2044、D=3726(高<宽),
# 故 B()F = getHeight、D()F = getWidth。
dt B ()F getHeight
dt D ()F getWidth
# ---- 图片附件 GO 的 7 个 float 字段(2026-10-16 确认,两条独立证据)----
# 证据 1:编辑器自己的 JSON 写入器 sb_0.java:669-675(写 region 时依次读)
# x=GO.D y=GO.B scaleX=GO.L scaleY=GO.I rotation=GO.S width=GO.C height=GO.Z
# 旁证:width/height 与图片实际像素一致(mega_dg4.png = 157x154,运行时读到的 C=157.0 Z=154.0)
# 证据 2:GO 自己的 setTransform 字节码 javap -c GO 的 D(FFFFF)V:
# putfield D(第1个参数) -> putfield B(2) -> putfield S(3) -> putfield L(4) -> putfield I(5)
# => D(float) = x、B(float) = y(这两个字段名与别的字段重复,必须按类型取 float 那个)
GO D F x
GO B F y
# 图片附件的"设置变换"入口(编辑器自己用的):setTransform(x, y, rotation, scaleX, scaleY)
GO D (FFFFF)V setTransform
# 图片附件没有 shear 字段:region 只有 x/y/rotation/scaleX/scaleY(+ 只读的 width/height)
# ---- 附件删除(编辑器自己的删除流程)----
# 证据:javap -c Gn 的 L()V => this.GU.skeleton.removeAttachment(this, true, true)
# GP 的 D(Gn,ZZ)V 字节码里 getfield L:LfI; fI.B(Object,boolean) 把它从附件表移除,
# 并同步清掉 GU 上指向它的引用(同一方法里遍历 Z:LfI 即插槽表)。
Gn L ()V delete
GP L (LGn;ZZ)V removeAttachment
GP L LfI attachments
GP Z LfI slots
# ---- 附件种类 / 占位附件 ----
# 证据:可读源码 hi_2.java(= 载荷类 Hi)的 I() 直接 return "placeholder";
# 它出现在骨架附件表里但"既不是当前附件也不是静止附件",就是 skin/占位附件。
Gn I ()Ljava/lang/String; type
# 附件上指向自己所属占位附件的引用:GP.removeAttachment 的占位分支按它级联删除
Gn D LHi; placeholderRef
# ============================================================================
# 【权威来源】编辑器自带的 JSON 导出器(载荷类 sB,2026-10-16)
# ----------------------------------------------------------------------------
# 为什么权威:导出 JSON 时**每个 key 后面紧跟被读的那个字段**,key 名就是字段语义。
# 证据链(两处独立,顺序逐条一致):
# 1) 可读载荷 ~/Desktop/spine398/spine398.jar(DecAll 产出:ldc 密文已换明文、解密调用已换 nop)
# `javap -p -c -cp spine398.jar sB` → `ldc "rotation"` 紧跟 `getfield Gp.F:F`,全部可读;
# 2) 未解密载荷 (payload-public.zip) 的 strings.tsv(class sB, method D):同一(类,方法)内
# 密文顺序 = 字节码顺序,281 条与可读副本里的 key 顺序逐条对得上(含三组解密器)。
# 导出器方法:sB.D(GP,boolean,boolean,gy,StringBuilder)=骨架;sB.D(gy,String,Gn,boolean)=附件。
# 字段名重复(D/B/L/I/S…)时**必须按描述符取**,表里已经带描述符。
# ============================================================================
# ---- Gp = 骨骼(导出器写 "bones" 段时读的就是这些)----
Gp C F length
# ^ length 是 C(之前写的 Class:F 是错的,已作废)
Gp D LiC; transform
# ^ iC = 继承模式枚举(normal/onlyTranslation/noScale…)
Gp String Z skinOverride
# ^ 导出器写 key="skin"(布尔:该骨骼是否覆盖当前 skin)
# ---- GU = 插槽(导出器写 "slots" 段)----
GU B Lcom/badlogic/gdx/graphics/Color; color
# ^ 写 key="color" 读的是 B(不是 D)
GU I Lcom/badlogic/gdx/graphics/Color; darkColor
# ^ 写 key="dark"
GU I Z hasDarkColor
# ^ 写 "dark" 之前先看这个布尔开关
GU B LGn; attachment
# ^ 写 key="attachment" 读的是 B(不是 D)
GU D Liz; blend
# ^ iz = 混合模式枚举
# ---- Gn = 附件基类 ----
Gn D Ljava/lang/String; name
# ---- GO = 图片(region)附件 ----
GO D Lcom/badlogic/gdx/graphics/Color; color
GO B Ljava/lang/String; path
# ^ 导出器写 key="path",值取自静态取值器 GO.B(GO)
# ---- GE = 点(point)附件 ----
GE B Lcom/badlogic/gdx/graphics/Color; color
GE D F x
GE B F y
GE L F rotation
# ---- Gx = 网格(mesh / linkedmesh)附件 ----
Gx B Lcom/badlogic/gdx/graphics/Color; color
Gx B Ljava/lang/String; path
Gx D Lga; uvs
Gx D Lhp; triangles
Gx B LHl; vertices
Gx L I hull
# ^ 导出器写 hull = Gx.L / 2
Gx D Lgf; edges
Gx StackMapTable Z deform
Gx D F width
# ^ 只在导出器带 extra 标志时写
Gx B F height
Gx D LGx; parentMesh
# ^ 写 "parent" 时先取它(父网格附件)
Gx D LGT; skin
# ^ 写 "skin" 时取父网格的 skin
Gx D LHi; parentPlaceholder
# ^ 父网格的占位附件(Hi)
Gx D Ljava/lang/String; parentName
# ^ 写 "parent"(非 linkedmesh 分支)
# ---- Gr = 包围盒(boundingbox)附件 ----
Gr I Lga; vertexCount
Gr B LHl; vertices
Gr B Lcom/badlogic/gdx/graphics/Color; color
# ---- Gs = 裁剪(clipping)附件 ----
Gs I Lga; vertexCount
Gs B LHl; vertices
Gs B Lcom/badlogic/gdx/graphics/Color; color
Gs B LGU; end
# ^ 裁剪结束的那个插槽
# ---- Gw = IK 约束 ----
Gw D Ljava/lang/String; name
Gw D LGp; target
Gw D F mix
Gw L F softness
Gw F Z uniform
Gw S Z stretch
Gw Z Z compress
# ---- GX = 变换(transform)约束 ----
GX D Ljava/lang/String; name
GX B LGp; target
GX SourceFile F rotation
GX S Z local
GX C Z relative
GX L F x
GX I F y
GX StackMapTable F scaleX
GX init F scaleY
GX LineNumberTable F shearY
GX S F rotateMix
GX D F translateMix
GX Z F scaleMix
GX F F shearMix
# ---- GD = 路径(path)约束 ----
GD D Ljava/lang/String; name
GD D LGU; target
GD D Ljm; positionMode
GD D Ljo; spacingMode
GD D Ljn; rotateMode
GD Z F rotation
GD D F position
GD V F spacing
GD S F rotateMix
GD L F translateMix
# ============================================================================
# 【面板/新按钮用到的"操作类" API】(2026-10-16 热更实测通过:不重启、纯编辑器自身 API)
# 场景:点面板按钮 → 弹名称输入面板 → 按名字匹配附件 → 在当前选中骨骼下建 15 根骨骼,
# 每根 1 插槽 1 附件(输入的附件名),位移 xy 0~500 随机、缩放 1、旋转/斜切 0,
# 插槽 alpha 0.5~1 随机、blend normal/additive 随机、附件在插槽上变换 0/0/0/1/1。
# 证据:`javap -p -c` 字节码 + attach 到运行进程逐条实测(每个 API 都真跑过并核对过结果)。
# ============================================================================
# ---- 建对象(编辑器自己的"加"API)----
# UH = OG 的模型编辑助手(OG.D:LUH;)。下面两个都实测建出来过:
UH D (LGU;LGp;Z;LfI;)LGU; addSlot
# ^ 加插槽:参数(插槽模板, 父骨骼, ?, 不重名用列表)。⚠️ 它会把模板插槽**整个复制**,连模板插槽上挂的附件一起复制(实测踩到过)
UH D (LGn;LGU;ZZLfI;)LGn; addAttachmentCopy
# ^ 加附件:参数(附件模板, 插槽, ?, ?, 列表);内部就是 `Gn.D(LGP;)LGn;` 复制一份模板附件,并挂到该插槽
GP D (LGp;)V addBone
# ^ 加骨骼:字节码 `bone.B = array.size; array.add(bone)`(骨架的骨骼表)
OG D (Ljava/lang/String;LfI;LGU;)Ljava/lang/String; uniqueName
# ^ 编辑器自己的不重名生成器:`OG.D("bone", 骨骼数组, null)` 会给出 bone7 这种名字
GU D (LGn;Z)V setAttachment
# ^ 设插槽的当前附件:第二参=是否记撤销;内部按 `Editor.V`(animate/setup)只写 `D:LGn;` 或 `B:LGn;` 其中一个 ——
# 所以要"两种模式都覆盖"就直接写两个字段(本次就是这么做的)
GU D LGn; attachmentAnimate
# ^ 与 `GU.B:LGn;` 成对:`D` 是 animate 模式用的当前附件,`B` 是 setup/非 animate 用的(JSON 导出器读的是 B)
VZ D (LGP;ZZ)V refresh
# ^ 改完模型重建层级树节点(本次每批建完都调它)
un D ()V undoBegin
un B ()V undoCommit
# ^ 撤销帧的 开始/提交(改模型前 D()、改完 B())
un Z ()V undo
# ^ ★ 撤销一步:实测有效(`up.D:` 栈 23→22、redo 栈 0→1,场景对象数同步回退)。
# 本次误删骨骼后就是用连点 un.Z() 一键一键撤回来的。另外 un.S()/un.C()/un.V()/un.I() 不是撤销:
# S=跳到历史某下标、C=置标志、V=按当前下标重放、I=up.D()(无效果)
# ---- 名称输入面板(编辑器自带的那套对话框)----
xl L (Ljava/lang/Object;)V onOkCancel
# ^ 对话框的 OK/Cancel 总回调:收到 Boolean(TRUE=OK、FALSE=Cancel)。
# OK 时它会读名字框、去重校验,然后调下面的抽象方法;Cancel 直接 return
xl L (Ljava/lang/String;)V onNameEntered
# ^ **抽象方法**:OK 且名字合法时被调用,参数就是输入的名字。想拿名字就子类化它(本次是 ASM 现生成子类)
xl D (Ldt;)LvH; show
# ^ 显示对话框。⚠️ 实测:**光调它窗口不会挂进 Stage**(parent 一直 null、屏幕上什么都不出现),
# 必须再显式 `dt.D(Ldl;)V`(Stage.addActor)挂上去,然后自己 setPosition
xl D LKp; nameField
# ^ 对话框里的名字输入框(Kp = TextField 子类):构造时会用它填入默认名,OK 时从它读名字
vH B (Ljava/lang/Object;)V okPressed
# ^ OK 按钮的回调:唯一会去调 `L(Object)` 的地方(javap -c vH 可见)
vH L (Ljava/lang/Object;)V onOkCancelNoop
# ^ 空实现(xl 覆盖了它)
Kp B ()Ljava/lang/String; getText
Kp B (Ljava/lang/String;)V setText
# ^ 名字框取/填文字(xl/xp 的构造与 L(Object) 里就是这么用的)
# ---- Actor / Stage / WidgetGroup(定位、挂载、删除)----
dt D (Ldl;)V addActor
# ^ Stage.addActor:字节码就是 `this.D:Ldo;.addActor(actor)`(root.addActor)。
# ⚠️ 用它把对话框挂上屏幕(配合 xl.D(dt));也踩过坑:它会把 Actor 从原父级摘走(当年把面板列表搬出面板就是它)
dl D Ldo; parent
dl D Ldt; stage
# ^ Actor 上的两个同名字段:`do` 类型的是父控件,`dt` 类型的是所在 Stage。按类型取,别按名字取
dl D ()Ldt; getStage
dl b_ ()Z remove
# ^ 把 Actor 从父级摘掉。⚠️ `eX.b_()V`(invalidate)与它同名不同描述符 —— `getMethod("b_")` 会取到 void 那个,
# 结果就是"调了删除却没删掉"(本次踩到)
eX b_ ()V invalidate
eX V (Z)V setFillParent
dl c_ ()F getX
dl d_ ()F getY
dl L ()F getWidth
dl I ()F getHeight
dl S ()F getTop
dl C ()F getRight
# ^ Actor 的几何读取(都在 dl 上用 `javap -p -c` 对出来的:c_=x、d_=y、L=width、I=height、S=y+h、C=x+w)。
# ⚠️ `et`(Table) 自己还声明了 `int L()`/`int I()`(列数/行数),所以按名字取必须**同时按返回类型 float 过滤**
dl D (FFI)V setPosition
# ^ setPosition(x, y, alignment):**align=0 时是"以 (x,y) 为中心"**(b1 不是 left/right 就按 center 处理)。
# 本次要把对话框摆屏幕正中就是靠这个:直接传 Stage 中心即可
# ---- 混合模式枚举(插槽 blend)----
iz D Liz; normal
iz B Liz; additive
iz L Liz; multiply
iz I Liz; screen
# ^ `iz`(=BlendMode) 的常量顺序取自 `iz.<clinit>`:依次 new iz("normal",0,770,1,771)、("additive",1,770,1,1)、
# ("multiply",2,774,774,771)、("screen",3,1,1,769) —— 名字是常量池里的明文
# ---- 面板自己那套(本次复用的)----
com.spineview.ObjectPanel wire (Ljava/lang/ClassLoader;Ljava/lang/Object;Ljava/lang/Runnable;)V wireButton
# ^ 把按钮接上点击(轮询 isChecked + 路由线程)——新按钮直接复用它,不用自己写监听
com.spineview.SceneObjects listAllNodes (Ljava/lang/ClassLoader;)Ljava/util/List; listAllNodes
com.spineview.SceneActions delete (Ljava/lang/ClassLoader;Ljava/lang/Object;)Z delete
# ^ 面板自己的"罗列场景对象 / 删除对象"(走编辑器删除流程,自带撤销)——清理误建对象时用它
# ---- WidgetGroup 的尺寸读取(本次用来把对话框撑到合适大小)----
eX LineNumberTable ()F getMinWidth
eX String ()F getMinHeight
eX StackMapTable ()F getPrefWidth
eX init ()F getPrefHeight
eX Ljava ()F getMaxWidth
eX Class ()F getMaxHeight
# ^ 六个 Layout 方法按 eX 声明顺序对应 minWidth/minHeight/prefWidth/prefHeight/maxWidth/maxHeight
# (面板日志里一直用的 `init` 读出来就是 prefHeight;本次实测对话框 pref=399x166)
# ^ ⚠️ 窗口刚建出来时的尺寸是默认的 150x150(所以正文/按钮会被裁),
# 要显式 `Actor.width/height = max(pref, min, 下限)` + `eX.b_()V`(invalidate) 才会按 pref 撑开