Commit Graph
67 Commits
Author SHA1 Message Date
tianmo 8fefcb76c4 run.sh 改用 python subprocess.Popen(start_new_session=True) 启动:nohup 方式会让编辑器挂在启动它的会话下,会话结束就被收掉 2026-10-16 16:04:26 +08:00
tianmo 1333e3d89c 面板内容区合并为一个滚动区:列表/Inspector 在上、日志块在下(不再用两个单元格,顺序不会再反) 2026-10-16 16:00:46 +08:00
tianmo 9e318f3361 下段提示区:包进 ScrollPane + 固定 90px 高度,保证任意停靠高度下三段都各占一块 2026-10-16 15:58:32 +08:00
tianmo 1cfd5e13cd 面板改为上/中/下三段:上=按钮(自适应)、中=列表(expand+fill 吃掉剩余)、下=实时提示(保留最近6条,多行) 2026-10-16 15:57:36 +08:00
tianmo 7f5ee1f00e 面板布局再修:按钮直接进根表格(两列多行),列表区是唯一 expand+fill 的行;列表内容 Table 设 top()+left(),否则 ScrollPane 里控件比视口小时会居中显示,看着像'列表跑到下面' 2026-10-16 15:51:46 +08:00
tianmo f4cf713ded 修面板布局:根表格与按钮子表 top(),按钮行/状态行不再 fill(否则控件被拉伸挤到停靠框下方) 2026-10-16 15:49:29 +08:00
tianmo 1f8a3b4dae 加可双击的 viewpanel/重启编辑器.command(Finder 双击即重启编辑器) 2026-10-16 15:47:58 +08:00
tianmo e5461cbf12 加 viewpanel/run.sh:一条命令手动重启编辑器(先杀旧实例、按需 rebuild、日志写 /tmp/spineview.log) 2026-10-16 15:46:40 +08:00
tianmo 15468829ae 按 setup pose 实测补锚点:Gp.length/worldScale、GU.name/bone/attachment/color、GO 附件的 rotation/scale/width/height
用户用四张 setup pose 截图给出对照:Gp(root/bone)、GU(插槽)、GO(region 附件)。
- Gp:面板 Length 与 float Class 一致 → length;Ljava/java 与 Code/SourceFile 相等 → 世界缩放。
- GU:String D=名字、Gp D=所属骨骼、Gn D=附件、Color D=颜色。
- GO:六个 float 对上 Region 附件的 旋转/缩放XY/宽高。
names.tsv 合并后 222 行,Renamer 重新产出 payload-named.zip。
2026-10-16 15:44:31 +08:00
tianmo e197a6883a Spine View 启动自动打开(等价 Views 菜单勾选),不用每次手点
- ViewInstaller.showView():面板 Actor 填好后调 Fx.D(us.spineView) —— 菜单 'Tree View' 的动作体就是
  Fx.D(us.Tree)(og.java:23),是编辑器自己的'显示/停靠视图'入口。
- 为什么之前每次都要手点:视图可见状态写在 views.json,只有正常退出才落盘;而我们一直用 SIGTERM
  杀编辑器进程,状态没写回去。启动时主动开一次就绕过了这个。
- 列表区仍按设计需要点一次 Refresh(面板是编辑器 UI 搭好之前就建的,那时场景树还是空的)。
2026-10-16 15:36:42 +08:00
tianmo 9a6913e610 骨骼字段语义命名(实测证据)+ 逐类反编译避免大小写撞名
- anchors.tsv:按用户实测把这批字段钉死 ——
  Z/V=x/y、F=rotation、Code/SourceFile=scaleX/scaleY、StackMapTable/LineNumberTable=shearX/shearY
  (证据:编辑器里 Rotate=341.456 / Translate(-168,-116) / Scale(0.8799,0.572) / Shear(-52.221,-28.63)
   与 Inspector 显示值一一对应);D/B/L/I/S/C = 静止姿态组(推断);D:LGP;=skeleton、D:LGp;=parent、B:Color=color。
- names.tsv 合并后 208 条,Renamer 改名 2867 处成员引用。
- src-named 改为**每个类单独反编译、用载荷类名当文件名**:CFR 直接输出会把 GP.java/Gp.java
  这类只差大小写的类写到同一个文件(macOS 文件系统不区分大小写),必须逐类产出。
- 注:CFR 对同名成员的自动改名(var_xxx 风格)不要开(--renamedupmembers),否则会盖掉我们的语义名。
2026-10-16 15:35:33 +08:00
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
tianmo 7fbb042aa6 编辑器交互/数据 API 调研完成:解出 KP=SelectBox、选中链路、增删改真实落点与撤销栈
- 新工具 tools/decrypt/DumpSites.java:逐 indy 站点解出『类.方法 + 描述符』(带描述符,
  解决 rewrite_source.py 丢描述符导致的重载混淆);ResolveSites.java 走运行时 CallSite 交叉验证。
- 结论改正:KP = libGDX SelectBox,KP.B(String)V = setSelected;XW/acW/acK/Yr 是
  『属性面板控件』而不是场景数据;场景对象是树节点上的 GP/Gp/GU/GO。
- 补齐:当前选择怎么设(VZ.D(Object))、谁刷新界面(VZ.D(GP,ZZ) / rW.B / fC.C)、
  撤销栈(载荷类 un 的 D()/B() 成对包一层)、删除边界(root 的删除按钮本来就是 disabled)、
  查/选/改名/删除/导出的真实实现与出处。
- 新增运行时探针 -Dspine.probe=objects(SceneObjects.java),实测打印整棵场景对象树。
- 文档:编辑器交互与数据API.md 重写;混淆名对照表.md 增补类/方法对照与大小写同名类坑。
2026-10-16 14:38:25 +08:00
tianmo 2b23ce59db 新增《编辑器交互与数据API》调研文档
- 交互层:工具注册(Create Tool 等)与视口交互入口
- 层级树:VZ(视图) / uo_2(节点) / xw_2(骨架) / gp_2(骨) / acK(插槽) 包装模型
- 当前选择:og_1.D.D 的读取点与菜单动作的依赖关系
- 数据层:所有 New X 都落到 KP.B(父级, 类型名),以及 KP 真实类名待解
- 改删查命令清单、撤销注意点、skeleton/root 删除边界、下一步 5 条
2026-10-16 14:22:48 +08:00
tianmo a0080428f9 场景对象增删改查调研:命令系统入口 + 新建对象的真实落点
- Commands.java:Editor -> pE(命令系统) -> void D(String) 按名字执行命令
- Launcher:新增 -Dspine.runCommand="<命令名>" 便于验证
- SceneReader:Tree/选中项探针(actor 树按 SnapshotArray 结构遍历)
- 混淆名对照表.md:补命令系统一节、可执行命令名单、skeleton/root 删除边界、
  以及 New X 最终落到静态 KP.B(target, 类型名) 的结论与待办
2026-10-16 14:20:45 +08:00
tianmo 8f7b72271f 阶段四收尾:面板两行布局(row/expand/fill)+ 英文输出 + 混淆名对照表
- ViewInstaller:用 Table.row()/Cell.expand()+fill()/setFillParent 排出"
  按钮一行、可滚动文字区一行"的面板;修掉把 setDebug 当成 setFillParent 的误用
- Scene2dPanel:按钮 isChecked/setChecked 与 Label.setText 改用对照表定名,
  修掉"点一次反复触发"与"文字不刷新"两个 bug
- SceneReader:面板输出改英文(编辑器缺中文字形,中文会渲染成方块)
- 新增 tools/obfmap/MapMethods.java:载荷 vs 上游 libGDX 的字节码指纹比对工具
- 新增 混淆名对照表.md:类/方法/字段映射、推导办法、已踩的坑、验证状态
2026-10-16 14:06:42 +08:00
tianmo 2e7ab7c33c 阶段四:Spine 3.8.99 编辑器里挂上自建视图面板
目标:在 Spine 编辑器窗口内部加一个自己的视图面板(按钮 + 文字显示),
点击读取场景对象,并像原生面板一样出现在 Views 菜单、可停靠可折叠。

本轮打通:
1. 编辑器在我们自己的进程里完整启动
   - 类加载器必须是 URLClassLoader 本身(自检要求)
   - Editor.main 必须在 AWT EDT 上调用
   - jvm.cfg 第 21 行要以两个空格结尾 + -DSpineJava
   - Editor.D:I 版本号、fonts/、/tzax 资源、Java8 版 launcher.Launcher 替身
2. 3.8.99 全量解密 → 可读源码
   - 字符串 17251/17461(伪造同名调用帧对齐 key)
   - 混淆动态派发还原 53871 处(调引导方法取 MemberName)
3. 自建视图
   - agent 在内存里给 us 枚举加 spineView 常量(不改磁盘,避开完整性自检)
   - 面板 Actor 由外部反射填进 us.spineView.D
   - 复用已有图标做别名(不新建图片资源)
   最终 "Spine View" 出现在 Views 菜单,可与 Tree 并排停靠、折叠展开

另外:
- ViewPatcher/ViewAgent:视图枚举与面板挂载的字节码插桩
- DecAll/ObMap/rewrite_source:字符串解密、派发还原、可读源码生成
- 阶段四-视图面板挂载.md:完整记录做法与踩过的坑

不纳入版本管理:rea/(独立仓库)、tools 下的 JDK/Ghidra 工具链、
Spine.app 与 spine-lab 副本、从载荷派生的批量产物。
2026-10-16 13:34:18 +08:00