受限发布产物恢复边界
restore 只是一条受限的本地故障恢复路径,不是 FairyGUI 的常规创作入口、第三方发布物导入器或源码还原承诺。本文档记录其安全使用范围,以及当前仓库已经验证过、无法仅凭发布产物稳定恢复的内容。
使用范围与安全边界
| 项目 | 当前口径 |
|---|---|
| 输入 | 仅处理可信的本地发布目录;不把未知来源 .fui / _fui.bytes 视为安全输入 |
| 输出 | 必须是独立工程目录,不接受 .fairy 单文件目标 |
| 路径约束 | 拒绝资源路径、包名、分支名、文件名中的路径逃逸;发布目录内资源若解析到输入目录外也会失败 |
| 覆盖行为 | 先在相邻暂存目录完成工程和资源写入,再替换目标;--force 不会在二进制解析或资源重建前删除旧输出 |
| 不代表 | 不是恶意文件检测器,也不保证第三方产物能够安全或完整恢复 |
这里的“不可还原”指:
| 项目 | 含义 |
|---|---|
| 输入范围 | 仅使用发布目录中的 .fui / _fui.bytes、图集 PNG、以及同目录 loose 资源 |
| 判定标准 | 不能稳定、通用、无外部辅助地恢复回原工程语义或原始 XML 文本 |
| 不包含 | 仍可通过补协议、补 writer 规则、补测试继续收敛的普通实现问题 |
总结
| 结论 | 说明 |
|---|---|
| 受限恢复目标 | 在可信输入下生成一个可重读、可打开、结构自洽的 FairyGUI 工程 |
| 不保证目标 | 还原成与原工程逐字节一致的源码工程 |
| 主要原因 | 发布产物会丢失一部分编辑器阶段信息,或把原始值降精度到运行时格式 |
当前已确认的不可还原项
1. 发布包中根本不存在的资源或动作
| 类别 | 不可还原内容 | 原因 | 当前样本证据 |
|---|---|---|---|
| 组件资源 | 原工程存在、但发布包未携带的组件 XML | 发布产物没有资源定义,restore 无法凭空生成真实内容 | HitTest/component1.xml、PullToRefresh/Button1.xml、PullToRefresh/Button2.xml、TurnPage/Button3.xml |
| Transition item | 原工程存在、但二进制 transition block 未携带的 item | 二进制里没有对应时间轴项,无法可靠反推 | Transition/BOSS.xml 中 target="n3" 的 6 个 item |
说明:这类内容如果强行补出,只能生成占位内容,不能声称是“还原原工程”。
2. 原始资源文件名与扩展名
| 类别 | 不可还原内容 | 原因 | 当前样本证据 |
|---|---|---|---|
| 普通图片资源 | 原工程使用的真实文件扩展名与双后缀命名 | 发布包只保留运行时资源名,不稳定保留工程文件名 | change.jpg -> change.png、Paper.jpg -> Paper.png、i3.png.png -> i3.png |
| 部分 loose 资源 | 若发布名与工程名完全脱钩,且缺少稳定映射线索 | 发布目录只提供发布后文件名,原工程命名信息已经丢失 | 仍可能出现少量发布名残留 |
说明:当前实现已经尽量把“资源 id 命名”还原回工程名,但对原始扩展名并不能做通用、可靠的反推。
3. Transition path 的原始文本精度
| 类别 | 不可还原内容 | 原因 | 当前样本证据 |
|---|---|---|---|
| 路径字符串 | 编辑器 XML 中 path 的原始小数位数与文本格式 | 发布二进制只保存 float32 数值;写回时只能输出数值等价的字符串 | Transition/PathDemo.xml 的 path |
说明:这类路径通常还能恢复到相同几何轨迹,但不能保证与原 XML 的字符串完全一致。
4. 被降级为运行时默认值的编辑器信息
| 类别 | 不可还原内容 | 原因 | 当前样本证据 |
|---|---|---|---|
| Transition easing | 原工程中的特定 ease 名称 | 当前样本对应二进制读出的就是默认 easing,无法证明原工程曾写过哪个非默认 ease | Transition/BOSS.xml、TRAP.xml、GoodHit.xml 中部分 Expo.Out / Back.Out / Bounce.Out |
| 简单 Group 节点 | 仅用于编辑器分组、但没有额外运行时语义的 GGroup 节点 | 当前样本中的发布组件数据会直接裁掉这类 group,二进制 child list 里既没有 group 节点,也没有可稳定回推的 group 归属索引 | Basics/Demo_Clip&Scroll.xml、Emoji/Main.xml、TurnPage/Book.xml |
| Group 高级模式 | 原工程 XML 中的 group.advanced="true" | 发布 group block写出的是布局与间距等运行时数据,不单独保留编辑器里的高级模式开关;当前样本中二进制读回的 group 会直接落成 advanced=false | Basics/Demo_Grid.xml、Transition/Main.xml、Transition/PowerUp.xml |
| Controller 当前选中页 | 原工程 XML 中的 controller.selected 当前页状态 | 发布 controller block稳定保存的是 homePageType/homePage 发布首页信息;当前样本中的二进制常写成 default,并不保留编辑器工程里当时的非零当前页 | TurnPage/Main.xml 的 bookPos="2"、TurnPage/Page.xml 的 style="1" / side="1"、FrontCover.xml / BackCover.xml 的 side="1" |
| Controller 导出标记 | 原工程 XML 中的 controller.exported="true" | 当前样本对应的 controller 发布 block只写 name/pages/homePageType/homePage/actions,没有独立写出 exported | TurnPage/BackCover.xml、TurnPage/FrontCover.xml、TurnPage/Page.xml |
| 默认值显式性 | 原工程是否显式写出默认属性 | 发布包只保留语义值,不保留“这个默认值当时是否显式写在 XML 里” | 如 xy="0,0"、空文本、默认布尔值等 |
说明:这类信息恢复后通常仍然语义可用,但无法保证与原工程的编辑器写法逐项一致。
5. 编辑器工程本地设置
| 类别 | 不可还原内容 | 原因 |
|---|---|---|
| 工程标识 | 原始 projectId | restore 会生成新的工程标识 |
| 工程设置 | 原始 .objs / workspace / 编辑器本地状态 | 发布目录不包含这些本地工程文件 |
| 初始化设置之外的项目配置 | 原工程的非发布产物配置 | 当前 restore 按初始化默认值生成工程设置,而不是恢复源工程工作区状态 |
说明:当前 restore 的目标是“重建可用工程”,不是恢复编辑器本地工作环境。
6. 原工程 XML 的文本级细节
| 类别 | 不可还原内容 | 原因 |
|---|---|---|
| 属性顺序 | 原标签属性排列顺序 | XML 语义不依赖属性顺序,发布产物也不保留该信息 |
| 格式风格 | 换行、缩进、是否自闭合、空格风格 | 这是 writer 生成结果,不是发布产物协议内容 |
| 大小写风格 | 某些颜色值、小数文本风格 | 发布包保留的是数值语义,不是原文本样式 |
说明:当前实现会尽量贴近 FairyGUI 编辑器写法,但不会把这类文本风格视为“可从发布产物逆推出的正式数据”。
当前恢复输出范围
| 项目 | 当前口径 |
|---|---|
| 工程目标 | 在可信输入下生成可读、可打开、可继续编辑的 FairyGUI 工程 |
| 资源目标 | 尽量恢复包内素材、组件 XML、字体派生图与 .jta / .fnt 等正式资源 |
| 不承诺 | 与原工程一模一样的文件名、文本格式、局部编辑器状态 |
何时需要外部辅助信息
若目标不是“重建可用工程”,而是“尽量贴近原工程文本或命名”,则需要额外输入:
| 额外输入 | 作用 |
|---|---|
| 原工程目录 | 作为命名、路径、缺失资源、文本样式的真实基准 |
| 编辑器工作区文件 | 恢复 .objs、workspace、本地工程状态 |
| 发布前清单或映射表 | 回填发布名与工程名之间的脱钩关系 |
当前样本下仍然成立的判断
| 判断 | 说明 |
|---|---|
| 可以从发布产物重建“可工作的工程” | 是 |
| 可以从发布产物重建“原工程的源码真迹” | 否 |
| 还原结果是否应该继续优化 | 可以,但应只优化“发布产物里确实有证据的部分” |