diff --git a/tools/deobf/anchors.tsv b/tools/deobf/anchors.tsv index b5a34bf..c85fc8f 100644 --- a/tools/deobf/anchors.tsv +++ b/tools/deobf/anchors.tsv @@ -27,3 +27,25 @@ 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)那一组:值与默认姿态吻合(0,0,0,1,1,0),且未改动时与上面那组相等 —— 推断,留注释待复核 +Gp D F setupX +Gp B F setupY +Gp L F setupRotation +Gp I F setupScaleX +Gp S F setupScaleY +Gp C F setupShear +# 引用类字段: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 diff --git a/tools/deobf/names.tsv b/tools/deobf/names.tsv index b57615c..1e0e3ba 100644 --- a/tools/deobf/names.tsv +++ b/tools/deobf/names.tsv @@ -1,7 +1,23 @@ -# 合并后的名字映射表:先由 MapMethods 指纹自动生成,再用手动锚点覆盖 +# 合并后的名字映射表:MapMethods(gdx-1.11.0) 指纹自动生成 + 手动锚点覆盖 # owner name desc newName +Gp B F setupY +Gp B Lcom/badlogic/gdx/graphics/Color; color +Gp C F setupShear +Gp Code F scaleX Gp D (Ljava/lang/String;Z)V setName +Gp D F setupX +Gp D LGP; skeleton +Gp D LGp; parent Gp D Ljava/lang/String; name +Gp F F rotation +Gp I F setupScaleX +Gp L F setupRotation +Gp LineNumberTable F shearY +Gp S F setupScaleY +Gp SourceFile F scaleY +Gp StackMapTable F shearX +Gp V F y +Gp Z F x KP B ()Ljava/lang/String; getSelected KP B (I)V setSelectedIndex KP B (Ljava/lang/String;)V setSelected diff --git a/viewpanel/src/com/spineview/ObjectPanel.java b/viewpanel/src/com/spineview/ObjectPanel.java index ab72840..0e9d9ef 100644 --- a/viewpanel/src/com/spineview/ObjectPanel.java +++ b/viewpanel/src/com/spineview/ObjectPanel.java @@ -36,6 +36,7 @@ public final class ObjectPanel { ClassLoader loader; Object skin; Object listTable; + Object listScroll; Object status; Object nameField; List objects = new ArrayList(); @@ -61,6 +62,7 @@ public final class ObjectPanel { Object rows = tableClass.getConstructor().newInstance(); state.listTable = tableClass.getConstructor().newInstance(); Object scroll = scrollClass.getConstructor(actorClass, skinClass).newInstance(state.listTable, skin); + state.listScroll = scroll; state.status = label(loader, skin, "Press Refresh to list scene objects."); state.nameField = fieldClass.getConstructor(String.class, skinClass) .newInstance("particle_bone", skin); @@ -217,6 +219,7 @@ public final class ObjectPanel { setStatus(state, "List build failed: " + error); return; } + invalidateList(state); setStatus(state, objects.size() + " scene objects" + (state.target == null ? "" : "; target = " + SceneObjects.kind(state.target) + " " + SceneObjects.nameOf(state.target))); @@ -331,6 +334,24 @@ public final class ObjectPanel { return simple; } + /** + * 列表内容变了以后,必须让 `Table` 与 `ScrollPane` 重新算一遍尺寸 —— + * 否则 ScrollPane 里缓存的高度还是旧的,表现为"内容多了却不能滚"。 + * `b_()V` = `invalidate()`(来源:MapMethods 对 gdx-1.11.0 的指纹比对)。 + */ + private static void invalidateList(final State state) { + try { + call(state.listTable, "b_", new Class[0], void.class); + } catch (Throwable ignored) { + // 名字对不上就算了 + } + try { + call(state.listScroll, "b_", new Class[0], void.class); + } catch (Throwable ignored) { + // 同上 + } + } + /** 用纯文本行填列表区(行不可点)。 */ private static void fillTextRows(final State state, List lines) { try { @@ -344,6 +365,7 @@ public final class ObjectPanel { layoutCell(cell, Obf.CELL_LEFT); call(state.listTable, Obf.TABLE_ROW, new Class[0], cellClass); } + invalidateList(state); } catch (Throwable error) { System.err.println("[panel] inspector 填充失败: " + error); }