Files
Spine_lab/viewpanel/src/com/spineview/Obf.java
T
tianmo d9ea449b64 面板增删改查 + Inspector + 可识别源码版(src-named)
面板(viewpanel/src/com/spineview/)
- ObjectPanel:Refresh / New Bone / New Slot / New BBox / New Path / Delete / Rename / Inspect + 名字输入框 + 对象列表(点行=选中)+ 状态行,全英文。
- SceneObjects:查(Tree 控件按层级/扁平列全部对象)、选中(VZ.D(Tree.Node,boolean) —— VZ.D(Object) 内部只是 Selection.L(),不真选中)、读当前选择(VZ.B())。
- SceneActions:增/删/改 + 撤销包装(un.D()/un.B())+ 树节点重建(VZ.D(GP,true,true));
  统一在编辑器渲染线程执行(OG.B(Runnable);OG.I() 有线程断言,非渲染线程会抛 RuntimeException);
  输入名字对话框自动化:找到『有 TextField 字段 + L(Object)V 回调』的对话框对象 → 填名字 → 调 L(true)。
- 实测:骨骼新建自动编号(bone7/bone8);模型层允许重名、按名字查只返回第一个;删父骨骼连子节点一起删;
  不能在渲染线程里 sleep(有些创建是下一帧做的)。
- 探针:-Dspine.probe=objects|panels|select|crud|matrix|panel。

可识别源码版(工具)
- tools/deobf/Renamer.java:ASM Remapper 只改成员名不改类名(indy 运行时要用加密串里的类名反射查)。
- tools/deobf/anchors.tsv(手动 14 条有证据的锚点)+ anchors-libgdx.tsv(MapMethods 对 gdx-1.11.0 指纹自动生成 178 条)→ names.tsv 192 条。
- 产物 ~/Desktop/spine398/src-named(4176 类全量,原 src-readable 不动);已验证 Table.add/clearChildren、SelectBox.getSelected/setSelected/setSelectedIndex、Gp.name。
- 文档:混淆名对照表.md 新增第六节(工具链 + 已验证 + 已知限制)。
2026-10-16 15:25:02 +08:00

129 lines
6.1 KiB
Java
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.
package com.spineview;
/**
* Spine 3.8.99 载荷里**被混淆成员的对照表**(推导过程见仓库根目录 `混淆名对照表.md`)。
*
* 推导办法(可复现,不是猜的):
* 1) `tools/obfmap/MapMethods.java`:把载荷类与上游 libGDX 同签名方法做
* "忽略名字的字节码指纹"比对(操作码序列 + 常量 + 成员的描述符);
* 2) 拿上游 libGDX 1.11.0 的源码逐条核对方法体语义。
*
* ⚠️ 这套载荷用了"**同名不同描述符**"的混淆手法:类里同时存在
* `D(Ldl;)LdR;`、`D()LdR;`、`D(F)LdR;`… 全部叫 `D`。所以任何一处都必须
* **名字 + 描述符一起判断**,只看名字一定会读错。
*/
public final class Obf {
// ======================= 类 =======================
/** com.badlogic.gdx.scenes.scene2d.Actor */
public static final String ACTOR = "dl";
/** com.badlogic.gdx.scenes.scene2d.Group(do extends dl) */
public static final String GROUP = "do";
/** com.badlogic.gdx.scenes.scene2d.ui.WidgetGroup(eX extends do) */
public static final String WIDGET_GROUP = "eX";
/** com.badlogic.gdx.scenes.scene2d.ui.Table(et extends eX) */
public static final String TABLE = "et";
/** com.badlogic.gdx.scenes.scene2d.ui.Cell(implements Poolable) */
public static final String CELL = "dR";
/** com.badlogic.gdx.scenes.scene2d.Stage 的实现(uk extends dt) */
public static final String STAGE = "dt";
/** com.badlogic.gdx.scenes.scene2d.ui.Value */
public static final String VALUE = "eN";
/** com.badlogic.gdx.utils.Array */
public static final String ARRAY = "fI";
// ======================= Button =======================
// 类名保留(TextButton 继承它),但方法名被混淆了。
/** com.badlogic.gdx.scenes.scene2d.ui.Button */
public static final String BUTTON = "com.badlogic.gdx.scenes.scene2d.ui.Button";
/** `isChecked() -> boolean`(体是 `return isChecked;`,读第 1 个 boolean 字段) */
public static final String BUTTON_IS_CHECKED = "String";
/** `setChecked(boolean)` */
public static final String BUTTON_SET_CHECKED = "I";
/** `setChecked(boolean, boolean)`(第二个参数是否派发事件) */
public static final String BUTTON_SET_CHECKED_FIRE = "B";
/** `setDisabled(boolean)` */
public static final String BUTTON_SET_DISABLED = "a_";
// ======================= Label =======================
/** com.badlogic.gdx.scenes.scene2d.ui.Label */
public static final String LABEL = "com.badlogic.gdx.scenes.scene2d.ui.Label";
/**
* `setText(CharSequence) -> void`。
* ⚠️ Label 上还有一个 `D(CharSequence) -> boolean`,那是 `textEquals(CharSequence)`
* —— 只按"一个 CharSequence 参数"去找方法会挑中它,现象是**日志说读取成功、面板文字却不变**。
*/
public static final String LABEL_SET_TEXT = "D";
/** `getText() -> StringBuilder` */
public static final String LABEL_GET_TEXT = "D";
// ======================= Table =======================
/** `add(Actor) -> Cell` */
public static final String TABLE_ADD = "D";
/** `add(Actor...) -> Table`(varargs 版,谨慎别选错) */
public static final String TABLE_ADD_VARARGS = "D";
/** `row() -> Cell` —— 换行的关键,不调用的话所有控件都挤在第一行 */
public static final String TABLE_ROW = "I";
/**
* `clearChildren() -> void`(体 = 逐个 actor.remove() + cells.clear() + rows/columns 归零)。
* 重建列表时用它把旧行清掉。
*/
public static final String TABLE_CLEAR_CHILDREN = "SourceFile";
/** `setFillParent(boolean)`(WidgetGroup 的,让面板铺满停靠框) */
public static final String TABLE_SET_FILL_PARENT = "Z";
/** `setClip(boolean)` */
public static final String TABLE_SET_CLIP = "C";
/** `setDebug(boolean)` —— 会把单元格描出彩色边框,别误当成 setFillParent */
public static final String TABLE_SET_DEBUG = "B";
/** `top() -> Table`(表格内容整体对齐) */
public static final String TABLE_TOP = "I";
/** `left() -> Table` */
public static final String TABLE_LEFT = "S";
/** `center() / bottom() / right() -> Table` */
public static final String TABLE_CENTER = "L";
public static final String TABLE_BOTTOM = "C";
public static final String TABLE_RIGHT = "Z";
/** `align(int) -> Table` */
public static final String TABLE_ALIGN = "D";
/** `pad(float) / pad(float×4) -> Table` */
public static final String TABLE_PAD = "D";
/** `padTop/padLeft/padBottom/padRight(float) -> Table` */
public static final String TABLE_PAD_TOP = "B";
public static final String TABLE_PAD_LEFT = "L";
public static final String TABLE_PAD_BOTTOM = "I";
public static final String TABLE_PAD_RIGHT = "S";
// ======================= Cell =======================
/** `fill() -> Cell`(fillX = fillY = 1,撑满单元格) */
public static final String CELL_FILL = "D";
/** `fill(boolean)` */
public static final String CELL_FILL_BOOL = "D";
/** `expand() -> Cell`(expandX = expandY = 1,占掉剩余空间) */
public static final String CELL_EXPAND = "StackMapTable";
/** `expandX() / expandY() -> Cell` */
public static final String CELL_EXPAND_X = "init";
public static final String CELL_EXPAND_Y = "LineNumberTable";
/** `fillX() / fillY() -> Cell` */
public static final String CELL_FILL_X = "B";
public static final String CELL_FILL_Y = "L";
/** `grow() / growX() / growY() -> Cell` */
public static final String CELL_GROW = "F";
public static final String CELL_GROW_X = "Code";
public static final String CELL_GROW_Y = "SourceFile";
/**
* 对齐:`top() / left() / bottom() / right() / center()`。
* 载体是 `align |= X & ~Y` 的形式,位掩码取自 libGDX 的 Align:
* center=1、top=2、bottom=4、left=8、right=16。
*/
public static final String CELL_TOP = "S";
public static final String CELL_LEFT = "C";
public static final String CELL_BOTTOM = "Z";
public static final String CELL_RIGHT = "V";
public static final String CELL_CENTER = "I";
/** `align(int) -> Cell` */
public static final String CELL_ALIGN = "D";
private Obf() {
}
}