zijunchiang
|
6238873312
|
chore(accept): accept-integration.sh 拒绝未知参数
首跑时把 --expect <path> 当成位置参数传进来,被静默忽略(期望值路径只认
EXPECT_PATH 环境变量),于是 --skip-seed 时找不到期望值文件才报错 —— 属于
「参数写错却先跑一半」的糟糕体验。现在除 --skip-seed 外一律报错退出。
不影响发布产物(accept-integration.sh 不在 zip 内),故不新发版本。
|
2026-09-17 05:21:54 +08:00 |
|
zijunchiang
|
a78a536476
|
feat(integration): 跨端集成验收(包内客户端 × 真实 Web 服务端)+ 修两个真实缺陷(v0.2.3)
单测打的是假 HTTP 夹具,Web 端测试只验自己那一侧 —— 两端各自绿灯不代表契约字段
真的对得上。本版加了跨端集成验收,并在首次运行就抓到两个真实缺陷。
一、跨端集成验收(T-WIN-019)
* build/integration/probe-integration.gd:只加载**包内**代码
(`godot --main-pack <pck> --script <探针>` + res://),打真实服务端并逐项断言:
/health 六个契约版本、catalog/version 指纹、catalog/export 解析出的四类资源与
defaultModelId;**场景物理参数逐项比对**(重力/基础风/阵风/风坐标系/地面摩擦坡度/
碰撞体/出生点/相机/环境)+ Wind.sample(0) + 场景 GLB 可下载;
动作 NDJSON → 客户端解析帧数 == 服务端帧数、33 点、每帧服务端关节角、
推导帧率 30 fps、时长 96.67 s;缩略图 PNG;模型 VRM 可下载。
* build/integration/seed-catalog.mjs:用**真实素材**播种目录
(示例文件/ 下的真 VMD → 内部标准 33 点;真 PMX → VRM;场景 GLB + 物理参数),
并把期望值(含从 /health 取的契约版本)写成 JSON。
* build/accept-integration.sh:编排「服务端可达 → 播种 → 包内探针 → 汇报」。
实测(v0.2.3 包内 pck × 真实 Web v0.7.4 + 真实 MySQL):全部通过。
二、探针抓到的两个真实缺陷
1. `CatalogTypes.Motion` 缺 `thumbnail_url`:服务端 catalog/export 从
data-models 0.6.0 起一直在发 thumbnailUrl(Model/Scene 都有),客户端默默丢掉。
已补字段与解析(缺失为 ""),新增 tests/test_catalog_types.gd(4 项 20 断言)
用**服务端真实报文形状**锁住三个资源类型的覆盖,并显式记录一处刻意不消费的差异
(Model.usable/unusableReason —— 目录只下发可用模型,恒为 true)。
2. `ApiClient._request()` 对**所有**响应无条件 `raw.get_string_from_utf8()`:
数据本身没错(二进制路径返回原始字节),但每下载一个文件都会打印
「Unicode parsing error … Invalid UTF-8 leading byte (N)」噪声,并把整个文件
(模型可达数十 MB)解码成 String 拷贝后丢弃。改为只在需要文本时解码。
三、顺带修掉测试里的写死契约版本
tests/test_api_integration.gd 断言 rest-api/websocket-keypoints/skeleton-topology
均为 "0.1.0"。该用例只在服务端可达时才跑,平时一直 skip,所以契约升到 0.5.0 后
没有任何地方发现它。改为从仓库 contracts/VERSION 读期望值并与 /health 比对
(顺带成为「客户端契约快照 vs 服务端」的跨端校验)。
证据:verify.sh 全绿(820 通过 / 0 失败,比上版 +46,因为服务端在线时 API 集成组
真的跑了);包内 pck 跨端集成探针全部通过;check-version/PE 版本资源 = 0.2.3。
|
2026-09-17 05:18:03 +08:00 |
|
zijunchiang
|
e4e534f2a2
|
test(accept): 发布包级端到端验收(读包内 pck 而非源码)+ T-WIN-018
`build/verify.sh` 跑的是仓库源码(`godot --path .`),交付给用户的是 zip 里的
OpenDance.pck + OpenDance.exe,差别全在「导出」这一步:导出预设漏资源、pck 没
重新生成、版本号没同步、契约快照与 pck 不一致 —— 都只在包里才暴露。
本仓 v0.2.1 的 PE 版本元数据就是这么翻的车。
新增:
* build/probe-release.gd —— 包内运行时探针。用
`godot --headless --main-pack <pck> --script <探针>` 只读包内资源,断言并
quit(0/1):
1) application/config/version == 期望版本(界面版本唯一来源,§11.1);
2) AboutScreen.app_version() == 期望版本(「关于」清单真正显示的值);
3) 主场景可加载、四个 autoload 都在场景树里;
4) 15 个关键资源(UI/模型/场景/网络/评分)在包内都可加载;
5) 包内 Credits.CONTRACT_VERSIONS 与包内 contracts/VERSION 快照逐项一致
(抓「pck 用旧契约构建、快照却拷了新的」)。
* build/accept-release.sh —— 一个 zip(或已解压目录)跑完:sha256 → 解压
(deflate 用 unzip / LZMA 用 7z,并检查没有 .partN 残留)→ 文件清单 →
check-pe-version.sh → 包内 pck 启动 180 帧无 SCRIPT ERROR → 探针。
* package-release.sh 结尾打印下一步验收命令;README 补用法。
实测(对**已发布**的 v0.2.2 资产重新下载后跑):
sha256 OK;PE 版本资源 0.2.2;包内 pck 启动 180 帧无错误;
包内 version=0.2.2;AboutScreen.app_version()=0.2.2;主场景
res://scenes/main.tscn;autoload 齐备;15 项关键资源可加载;
pck 内契约表与包内 contracts/VERSION 一致 → 发布包级验收全部通过。
反向验证:
* 篡改包内 contracts/VERSION 的 rest-api=0.4.0 →
✗ ["rest-api: pck=0.5.0 快照=0.4.0"],退出码 1;
* 期望版本写 0.2.1 对 v0.2.2 的包 → 三处版本断言全失败,退出码 1。
顺带修掉脚本自身一个缺陷:SHA256SUMS 用相对路径 + cd 到包目录后被二次拼接成
dist-release/dist-release/SHA256SUMS,导致 sha256 校验假失败(其余检查仍全绿,
很容易被忽略)。首跑时正是它把「全部通过」变成了失败。
verify.sh 仍全绿(754 通过 / 0 失败 / 5 跳过)。
|
2026-09-17 04:50:40 +08:00 |
|
zijunchiang
|
ba988f6ca6
|
fix(packaging): 发布包 exe 的 PE 版本资源必须等于发布版本(v0.2.2)
缺陷(v0.2.1 实测):把 opendance-windows-v0.2.1.zip 解开、在 Windows 上
「右键 → 属性 → 详细信息」,显示的是
文件版本 0.1.0
产品版本 0.1.0
而产物名、Git tag、README 全是 v0.2.1 —— 正是文档 §11.2 要禁止的
「不可核对的发布」。
根因:export_presets.cfg 的 application/file_version /
application/product_version 被硬编码在 0.1.0,而它们**不会**跟随
project.godot 的 application/config/version 自动更新;check-version.sh 当时
只比 project.godot ↔ project.yaml(两处一致),所以静态校验全绿、产物却是错的。
漂移发生在没人看的第三个位置 —— 校验位置少一个,等于没校验。
证据:
strings -a -el OpenDance.exe -> FileVersion 0.1.0 / ProductVersion 0.1.0
VS_FIXEDFILEINFO @0x67b976c -> FileVersion 0.1.0.0 / ProductVersion 0.0.0.0
对照组:官方模板 windows_release_x86_64.exe 的 FileVersion = 4.7.2,
说明本机 rcedit 改写是生效的,问题纯粹在预设的值本身。
修复:
* build/sync-export-version.sh(新增):导出前把版本号写进导出预设,
幂等、拒绝非 X.Y.Z;
* build/check-pe-version.sh(新增):直接读 exe 的 PE 版本资源 ——
VS_FIXEDFILEINFO(签名 0xFEEF04BD 后 16 字节,grep -abo 取偏移约 40 ms)
与 StringFileInfo(strings -el,资源管理器属性页显示的就是它)。
两处都查:实测固定信息里的 ProductVersion 恒为 0.0.0.0;
* build/check-version.sh:新增导出预设两个键的校验;
* build/export-windows.sh:导出前同步、导出后直接复核产物;
* build/package-release.sh:打包前校验源 exe、解包后再校验包内 exe;
* build/verify.sh:新增步骤 1/5「产物 PE 版本资源」(未导出则跳过);
* tests/test_about.gd:新增 test_export_preset_version_matches_project_version。
反向验证:把预设 file_version 改回 0.1.0 →
check-version.sh 退出码 1(报出两处不一致);
无头测试 753 通过 / 1 失败,失败项正是
「导出预设的 file_version 与版本号唯一来源一致」。
实测 v0.2.2 产物:PE FileVersion 0.2.2.0 / StringFileInfo 0.2.2,
版本号在 project.godot / project.yaml / export_presets.cfg / exe 元数据 /
产物名 / tag 六处一致。verify.sh 全绿(754 通过 / 0 失败 / 5 跳过)。
同时把 LZMA 压缩的取舍写清楚:deflate 包 38,248,818 B 仍超 IIS
30,000,000 B 上限,故 Release 资产仍是 LZMA 整包(26,628,529 B,不拆分卷);
若上限放开或改由 Web /static 分发,用 ZIP_METHOD=deflate 重打包即可得到
资源管理器可直接双击解压的包。
|
2026-09-17 04:22:57 +08:00 |
|
zijunchiang
|
14ee5f7ec9
|
fix(scene): 包围盒沿树累乘变换(修掉入树前的 ERROR 与范围偏位)+ 21 项"真机等价"测试
缺陷:SceneRuntime._compute_aabb() 用 MeshInstance3D.global_transform 计算包围盒,
而它在 _assemble() 里调用 —— 那时运行时节点**还没入树**。两个后果:
- Godot 打一行 `ERROR: Condition "!is_inside_tree()" is true. Returning: Transform3D()`
(真机每次载入场景都刷一条,与"日志里不应有 ERROR"的排查约定冲突);
- 树外的 global_transform 返回单位变换,算出来的只是各网格的**局部** AABB,
于是重力/风 Area3D 的碰撞盒与兜底地面会偏小或偏位 —— 对把网格摆在非原点位置的
场景(导出 GLB 的常见情况)**风力可能作用不到物体上**。
修复:改为从根往下累乘 `Node3D.transform`,不依赖是否入树;挂在单位变换父节点下时
结果与旧语义一致。
新增 21 项无头"真机等价"测试(不需要设备):
- tests/test_scene_config.gd:在代码里手写合法 GLB(三角形 + BIN chunk)落盘后
**真实加载**:warnings 为空、按 colliders 三种取值分别核对碰撞体(mesh / auto 命中
*_col / auto 未命中的兜底地面 / none)、重力 Area3D 的 gravity 与方向、
SPACE_OVERRIDE_REPLACE、风力与 WIND_FORCE_SCALE 对齐,以及**带位移网格**
(translation [10,0,0])时重力区域与兜底地面都跟着位移(该缺陷的回归测试);
- tests/test_pose_server.gd:**时间维度**验证保活 —— 只发应用层 ping、不发关键点帧的
客户端在 17 秒(> 15 秒静默超时)后仍保持连接("画面里没人就掉线、疯狂重连"的根因
对照),而完全不发数据的客户端被 close(1001) 断开。
新增 build/check-version.sh:强制 project.godot 的 application/config/version
(「关于」清单与 .pck 的来源)与 project.yaml、发布版本号三者一致;已接入
build/package-release.sh(打包前)与 build/verify.sh(第 0/4 步),并做过反向验证。
此前没有任何机制保证这两个文件同步 —— 界面显示的版本可能和产物名不一致。
版本升至 0.2.1(project.godot / project.yaml / README / 产物名 / tag 全部一致),
About 清单与 .pck 内版本号均为 0.2.1(已用 strings 核对)。
验证:build/verify.sh 四步全通过(版本一致性 → 编译 → 751 项断言 → 180 帧启动无错误);
产物 opendance-windows-v0.2.1.zip(LZMA,26,627,191 B)
sha256 d49885327047f5a52de6c732431ea080cd1a030ae1c581a8bc0ec0d99bfb792c。
|
2026-09-17 03:59:29 +08:00 |
|
zijunchiang
|
86e5decd10
|
build(release): 增加 ZIP_METHOD=lzma 选项(37 MB 整包被 IIS 30 MB 上限挡住时用)
Windows v0.2.0 发布时,Gitea 站点 IIS 的 maxAllowedContentLength 仍是默认的
30,000,000 字节:16.4 MB 通过,而 38,245,602 B 的整包用**正确**的 multipart 写法
(字段名 attachment)复测依旧 HTTP 413(仅发出 917 KB 即被拒)。为不阻塞发布,
本次给打包脚本增加压缩方式开关:
ZIP_METHOD=deflate (默认)约 38 MB,Windows 资源管理器双击即可解压
ZIP_METHOD=lzma 约 26 MB,可绕过 30 MB 闸;**代价**是 Windows 10 资源管理器
不支持 LZMA(method 14) 的 zip,必须用 7-Zip / WinRAR / PeaZip
脚本细节:
- lzma 走 `7z a -tzip -mm=LZMA -mx=9`(缺 7z 时报错并给出安装提示);
- lzma 包额外做 `7z t` 完整性测试,并改用 `7z x` 做解压自检(unzip 对 method 14
支持不一致,不能用来验证);
- 超限告警里补上「可用 ZIP_METHOD=lzma 绕过」的提示。
README.md / README.txt 同时写明:v0.2.0 的 zip 是 LZMA,需要 7-Zip/WinRAR 解压;
若 IIS 上限已放开,请改用默认 deflate 包。
|
2026-09-17 03:42:05 +08:00 |
|
zijunchiang
|
5581cbe05d
|
feat(scene): 场景选择与物理落地 + 整包发布(T-WIN-012/013/014)
T-WIN-013:API 升级与场景选择
- 契约快照同步到 rest-api 0.5.0 / data-models 0.7.0 / database 0.4.0
- catalog_types.gd 新增 SceneConfig(物理/环境/出生点/相机)与 Scene;
CatalogBundle 增加 scenes[];from_dict 按契约 7.1 再收敛一次
(缺项默认、越界夹紧、非法枚举回退),与服务端 normalizeSceneConfig 同规则
- 新增 src/scene/scene_runtime.gd:GLB 载入 -> 碰撞体(mesh 三角网 /
auto 命名约定 *_col、*_colonly / none 不兜底)-> 场景级重力(Area3D
SPACE_OVERRIDE_REPLACE,不改全局 ProjectSettings)-> 风(每物理帧
apply_central_force,阵风正弦叠加,支持 local 坐标系)-> 环境光与雾
-> 出生点与相机(follow/fixed/orbit);无碰撞体时兜底地面
- CatalogStore 增加 scenes/default_scene/find_scene/ensure_scene_cached/
fetch_thumbnail(场景缓存带 sha256 指纹,避免换包后仍用旧 GLB)
- 主界面改为 2x2 四个选择器(曲目/动作/模型/场景)+ 场景参数面板
(缩略图 + 重力/摩擦/弹性/碰撞体/风摘要)
- 游戏界面载入场景并落地物理,角色落在出生点;场景缺失/下载失败/
解析失败一律回退内置空场景并提示,不阻塞开始跟练
T-WIN-012:「关于」清单展示当前版本号
- 版本唯一来源为 project.godot 的 application/config/version(v0.2.0)
- about_manifest() 输出版本/引擎/契约/协议/地址/隐私清单;
无头测试无 autoload,读取 AppConfig 走 get_node_or_null 容错
- Credits 的单个 CONTRACT_VERSION 常量改为 CONTRACT_VERSIONS 字典
(六项契约各自独立递增),并双向核对 contracts/VERSION
T-WIN-014:发布必须是单个完整包
- build/package-release.sh 重写:只产出单个 zip + SHA256SUMS,
清理历史 .partN,超限时告警而非回退分卷;新增源产物与解压后完整性
自检(PE 头 MZ / pck 魔数 GDPC / exe+pck 同目录同名)与体积-上限对比
- deploy/proxy 相关的 Gitea IIS 256MB 上限说明见 opendance-web
测试:tests/test_scene_config.gd(12 例)+ tests/test_about.gd(4 例);
无头测试 687 通过 / 0 失败(10 个套件),verify.sh 全部通过
|
2026-09-17 00:45:23 +08:00 |
|
zijunchiang
|
315cf79708
|
feat(win): T-WIN-011 Windows 打包与一键验证脚本
|
2026-09-14 20:04:54 +08:00 |
|