游戏分发与在线游玩:封面/截图冻结、网页可见可玩与 AGC 发布接入 #466

Merged
kdletters merged 16 commits from codex/game-distribution into master 2026-09-22 17:27:00 +08:00
Member

这次改动解决什么

把「游戏分发 + 在线游玩」从特性分支交付到可上线状态:AGC 客户端能一键把游戏发布到平台,网页端能看到并在线游玩,资料(必需封面 + ≤6 张截图)随版本冻结、审核通过后生效。

主要行为

  • 发布链路:网页 /games/publish 与 AGC 发布面板都要求封面必选、截图可选(≤6),复用平台图片直传与归属校验;封面/截图素材 ID 随版本冻结,审核通过后整体生效到游戏行。
  • 公开投影/api/game-distribution/games 返回封面与截图的对象键,不泄露素材 ID;只有已公开且存在有效活动版本的游戏,其素材才在 /api/assets/read-url 获得匿名读授权。
  • 展示与游玩:广场卡片、详情页 hero 与截图缩略图条换签展示真实封面;发行网关按游戏/版本白名单提供 index.html 与包内资源,网页以 allow-scripts 沙盒 iframe 在线游玩。
  • 作者续发:版本回读(作者/管理员)返回 frozenMetadata,更新版本时可复用同一批素材,不必重新上传封面。
  • AGC 新聊天架构接线:Project Supervisor 退役后,发布入口落在 DirectProject 聊天头的「发布到游戏广场」按钮,导出试玩包与发布面板仍由工作台壳持有。

验证

  • 全量 npm test:395 文件 / 4399 用例通过(含 appSurface、chatDialogFrameLayout、游戏分发与发布面板用例)。
  • cargo test -p api-server game_distribution(17)、cargo test -p module-game-distribution --lib(11)、cargo check(api-server / spacetime-module / spacetime-client / AGC 壳)。
  • 真实本地栈 E2E:npm run check:game-distribution-media-e2e 27 项通过(真实素材直传 OSS → 冻结 → 送审 → 管理员通过 → 公开投影 → 匿名换签读 → 发行网关 200)。
  • 真实浏览器:桌面 1280×900 与移动 390×844 下发布页上传封面、广场与详情页展示真实封面与截图缩略图(截图存于本地验证记录)。
  • npm run check:repository-ci -- origin/master HEAD 全绿(lint → AGC appSurface → web/admin-web 构建 → diff check)。

上线前置与风险

  • 生产侧仍依赖部署项:独立发行域名与通配 TLS、CDN TTL ≤60 秒与 purge 失败处置、回滚演练与对象清理策略;这些在 docs/【开发运维】 与实施计划「尚未完成」中记录。
  • AGC 桌面端的真实 OSS 直传需要在装有客户端的机器上补跑一次(能力作用域与打包已静态验证)。
  • 发布写入受灰度开关 game-distribution:publish 控制,必要时可先关投稿保在线。
## 这次改动解决什么 把「游戏分发 + 在线游玩」从特性分支交付到可上线状态:AGC 客户端能一键把游戏发布到平台,网页端能看到并在线游玩,资料(必需封面 + ≤6 张截图)随版本冻结、审核通过后生效。 ## 主要行为 - **发布链路**:网页 `/games/publish` 与 AGC 发布面板都要求封面必选、截图可选(≤6),复用平台图片直传与归属校验;封面/截图素材 ID 随版本冻结,审核通过后整体生效到游戏行。 - **公开投影**:`/api/game-distribution/games` 返回封面与截图的对象键,不泄露素材 ID;只有已公开且存在有效活动版本的游戏,其素材才在 `/api/assets/read-url` 获得匿名读授权。 - **展示与游玩**:广场卡片、详情页 hero 与截图缩略图条换签展示真实封面;发行网关按游戏/版本白名单提供 `index.html` 与包内资源,网页以 `allow-scripts` 沙盒 iframe 在线游玩。 - **作者续发**:版本回读(作者/管理员)返回 `frozenMetadata`,更新版本时可复用同一批素材,不必重新上传封面。 - **AGC 新聊天架构接线**:Project Supervisor 退役后,发布入口落在 DirectProject 聊天头的「发布到游戏广场」按钮,导出试玩包与发布面板仍由工作台壳持有。 ## 验证 - 全量 `npm test`:395 文件 / 4399 用例通过(含 appSurface、chatDialogFrameLayout、游戏分发与发布面板用例)。 - `cargo test -p api-server game_distribution`(17)、`cargo test -p module-game-distribution --lib`(11)、`cargo check`(api-server / spacetime-module / spacetime-client / AGC 壳)。 - 真实本地栈 E2E:`npm run check:game-distribution-media-e2e` 27 项通过(真实素材直传 OSS → 冻结 → 送审 → 管理员通过 → 公开投影 → 匿名换签读 → 发行网关 200)。 - 真实浏览器:桌面 1280×900 与移动 390×844 下发布页上传封面、广场与详情页展示真实封面与截图缩略图(截图存于本地验证记录)。 - `npm run check:repository-ci -- origin/master HEAD` 全绿(lint → AGC appSurface → web/admin-web 构建 → diff check)。 ## 上线前置与风险 - 生产侧仍依赖部署项:独立发行域名与通配 TLS、CDN TTL ≤60 秒与 purge 失败处置、回滚演练与对象清理策略;这些在 `docs/【开发运维】` 与实施计划「尚未完成」中记录。 - AGC 桌面端的真实 OSS 直传需要在装有客户端的机器上补跑一次(能力作用域与打包已静态验证)。 - 发布写入受灰度开关 `game-distribution:publish` 控制,必要时可先关投稿保在线。
kdletters added 13 commits 2026-09-22 16:58:10 +08:00
- 主站:游戏广场、详情、在线游玩、网页发布与作者中心,以及共享契约与客户端服务
- 后端:module-game-distribution 领域层、SpacetimeDB 表/迁移/绑定、spacetime-client facade、api-server 路由与发行网关
- 后台:游戏审核页(待审列表、通过/拒绝、安全下架)
- AGC:发布面板、本地导出包读取命令与发布服务,含默认跳过的真实链路测试
- 运维:发行来源 nginx 模板与门禁、game-distribution:publish 灰度发布开关、OSS PutObject 受控重试
- 文档:主规范、里程碑与实施计划、决策日志与踩坑记录
- 用 CDP Input.dispatchTouchEvent 向游玩页 iframe 派发真实 touchStart/touchEnd,沙箱内探测包收到 touchstart/touchend/pointerdown(pointerType=touch)/click 并命中目标元素
- 记录触摸模拟必须在 iframe 文档创建前启用的踩坑口径
- 用 rustfmt 修正 AGC Tauri 导出包测试的断言排版
- 按 simple-import-sort 修正 AGC App.tsx 导入顺序与 packages/shared 导出顺序
- api-server 游戏分发模块新增 package_confirmed/package_rejected/version_submitted/version_cancelled 事件,带 request_id、game_id、version_id、耗时与体积/文件数(不记录凭据、URL 与文件内容)
- 新增 review_backlog_listed(审核积压)、review_decided(审核结论与公开修订号)、game_unpublished/game_suspended(撤销传播)与 publish_switch_blocked/unavailable(开关拦截)事件
- 发行网关拒绝路径补 debug 级 release_rejected(cookie、扩展名、未公开、非公开版本)便于排查发行 4xx
- 运维文档给出可直接 grep 的事件名与关键字段,实施计划记录真实栈复跑证据
- 服务端:游戏表追加可空 cover_object_key / screenshots_json,版本表追加可空 metadata_json,创建版本时校验必需封面、最多 6 张截图与图片素材归属,并从素材记录派生对象键生成冻结资料。
- 服务端:审核通过时把冻结资料整体生效到游戏行;只有已公开且存在有效活动版本的游戏,其封面/截图素材才在 /api/assets/read-url 获得匿名读授权。
- 服务端:作者与管理员回读版本时追加 frozenMetadata,带回封面与截图素材 ID 供续发复用,公开投影仍只暴露对象键。
- 网页:/games/publish 新增「封面与截图」区,复用平台图片直传与 confirm 通道,缺封面或截图超量在发请求前拦截,更新版本时按冻结资料回填且不要求重新上传。
- 网页:游戏广场卡片与详情页 hero 换签展示真实封面,详情页新增可点击的截图缩略图条,无素材或换签失败时静默回退原有渐变占位。
- AGC:发布面板支持封面必选与截图最多 6 张,新增素材直传服务并在创建游戏前拦截缺封面,同一文件重复提交复用素材 ID。
- AGC:http 能力作用域新增阿里云 OSS 直传地址,客户端同时校验直传目标必须是平台素材存储。
- 契约与文档:同步 shared-contracts、packages/shared 契约,更新 SpacetimeDB 迁移注释、后端架构、玩法链路与实施计划文档,并补齐网页端与 AGC 定向测试。
- 服务端:抽出 `resolve_owned_game_media`,创建游戏与创建版本复用同一素材校验;不存在的素材返回 400,借用他人素材返回 403,避免游戏行先落一个无效素材 ID。
- 脚本:新增 `npm run check:game-distribution-media-e2e`(`scripts/check-game-distribution-media-e2e.mjs`),在本地 dev 栈上跑真实素材直传、冻结、审核生效、匿名换签读与发行网关的可重复检查。
- 文档:后端数据契约补充创建游戏的素材复核口径,实施计划记录真实本地栈 27 项媒体验证与真实浏览器封面/截图展示证据。
- 网页发布页:封面与截图改用透明 input 覆盖自定义胶囊按钮,点击命中原生控件;上传后不再出现「未选择任何文件」与「已选择」互相矛盾的状态。
- AGC 发布面板:同一处理,按钮文案随状态在「选择封面图片 / 更换封面图片」「添加截图 / 截图已满 6 张」之间切换。
- 文档:实施计划补充真实浏览器发布链路证据(网页上传封面 → my-games 待审 → 版本 frozenMetadata 指向本次上传素材)与交互打磨记录。
- AGC:直传对象存储抛错(能力作用域拒绝、网络不可达、请求被取消)时统一转成中文可操作文案,不再把英文插件错误原样暴露给作者。
- 测试:新增直传抛错的单测,确认失败时不再登记素材。
- 文档:记录用 tauri-plugin-http 同一套 urlpattern 逻辑验证 `https://*.aliyuncs.com/*` 命中 dev/生产 OSS 桶且拒绝无关主机,并说明桌面端真实执行仍需在装有 AGC 的机器上补跑。
- `.eslintrc.cjs`:`src/services/gameDistributionClient.ts` 及其测试加入活跃服务白名单,不再被遗留忽略列表吞掉。
- 客户端:按仓库规则修掉排序与未使用类型导入(顺带移除两个只在 re-export 中出现的多余导入)。
- 修复 `scripts/vite-retired-css-plugin.test.ts` 的边界门禁:活跃模块不得停留在 ESLint 忽略名单里。
- 合并 origin/master(含 429f991bd 定向回滚、Godot 原生绑定迁移与策划 Agent 模型控件)。
- 回滚提交删除的游戏分发代码按功能面补回:SpacetimeDB 模块注册与迁移表、api-server 路由与权限映射、后台审核页、AGC 发布命令与 payload 类型、SelectionStage 的 games 阶段、ProjectSupervisorView 的 overlay 挂载点、主站路由与标题、Cargo 依赖与锁、vite/vitest 代理与 tailwind source。
- 保留 master 的 Godot C++ 迁移(移除旧 vendored GDExtension、新的 composer 控件布局)与其它 master 侧改动。
- 修正 master 自带的红灯断言:/api/creation-entry 已被 api-server 列入退役路由,dev 中间件按退役路径 404,测试改为断言不进入代理。
- 验证:cargo check(api-server / spacetime-module / spacetime-client / AGC 壳)、cargo test(api-server 游戏分发 17、module-game-distribution 11、AGC 本地导出 7)、全量 vitest 4557 passed、两端 typecheck、eslint、rustfmt、编码、文档索引与 SpacetimeDB schema guard。
- 合并 origin/master(304 个提交:DirectProject 聊天容器重构、Project Supervisor 退役、策划附件导入、CI 隔离编译缓存等)。
- 接受 master 对 ProjectSupervisorView / SupervisorChatOnlyView 的退役与预览快捷测试收敛;发布入口改由 DirectProject 聊天头承载。
- DirectProjectChatHeader 新增「发布到游戏广场」入口(无回调不渲染、回合忙态禁用),DirectProjectChatView 透传 onRequestGamePublish。
- App.tsx 继续由工作台壳持有试玩包导出与 GameDistributionPublishPanel,沿用 project.export_package 权限确认队列;check-config 把该命令从 native-only 清单移回 App invoke。
- 后台游戏审核 API / 类型 / 路由测试与 master 新增的 AGC 模板管理按双方保留合并,并修掉拼接造成的接口与用例闭合缺陷。
- 修正 master 自带的 viteProxyConfig 断言:/api/creation-entry 属退役路由,测试改为断言不进入代理。
- 记录合并踩坑:语法结构内部的冲突不能简单按「双方保留」拼接,必须按某一侧骨架重建并跑 tsc 与单文件测试。
- 验证:全量 vitest 393 文件 / 4374 用例通过,root / AGC / admin-web 三端 typecheck,cargo check 与游戏分发 Rust 测试,encoding、doc-index、rustfmt、SpacetimeDB schema guard。
合并 master:DirectProject 回合三态与 AGC release 每日调度
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust smoke (pull_request) Has been cancelled
Project CI / AI game creator shell Rust crates (pull_request) Has been cancelled
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled
d047b16b91
- 合并 origin/master 11 个提交(DirectProject 回合三态与投影 memo、宿主崩掉后的回合收口、权限拒绝后的忙态、策划对话布局修复、AGC release 每日调度)。
- 本次自动合并无冲突;游戏分发发布入口(App 的 requestGamePublish、DirectProjectChatView 透传、聊天头「发布到游戏广场」按钮)在新聊天状态机下保持接线。
- 验证:root / AGC / admin-web 三端 typecheck、全量 vitest、游戏分发 Rust 测试、encoding、doc-index、rustfmt 与 SpacetimeDB schema guard。
kdletters added 1 commit 2026-09-22 17:01:27 +08:00
合并 master:AGC 项目快照整目录上传
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust smoke (pull_request) Has been cancelled
Project CI / AI game creator shell Rust crates (pull_request) Has been cancelled
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Has been cancelled
1bd5fe9ff0
- 合并 origin/master(bba4f0eb2:项目快照整目录上传 .agent,保留项目身份与 Agent 历史)。
- 自动合并无冲突;共享记忆与实施计划文档经复核保留双方条目,游戏分发功能面未受影响。
- 同步目的:Gitea PR 门禁要求 PR head 包含目标分支最新提交,合并后重新推送触发 Project CI。
kdletters added 1 commit 2026-09-22 17:15:35 +08:00
发布入口接入灰度开关
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust smoke (pull_request) Has been cancelled
Project CI / AI game creator shell Rust crates (pull_request) Has been cancelled
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled
e5460280ce
- 后端:GET /api/runtime/frontend-config 新增 gameDistributionPublishEnabled,复用 `game-distribution:publish` 判据(未配置或 enabled=false 时对已登录作者默认开放,显式收紧后只放行白名单/灰度命中用户,匿名恒为 false),前端入口与写入口共用同一事实源。
- 后端用例:新增 frontend_runtime_config_game_distribution_publish_is_scoped_to_authenticated_gate,覆盖默认开放、enabled=true 无白名单、白名单命中、deny 名单、enabled=false 回退与 rolloutPercent=100。
- 网页:平台壳按灰度隐藏「发布游戏 / 发布新版本」入口;/games/publish 直接访问时渲染「发布功能正在灰度中」并提供重新检查;读取失败按放行处理,由后端写入口把关并返回可读文案。
- AGC:新增 readGamePublishAvailability(同一运行时配置字段),只有命中才把发布回调交给 DirectProject 聊天头;字段缺失或读取失败按不开放处理。
- 文档:玩法链路、后端数据契约与实施计划记录灰度口径、入口行为与验证命令。
kdletters added 1 commit 2026-09-22 17:26:53 +08:00
Merge branch 'master' into codex/game-distribution
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust smoke (pull_request) Has been cancelled
Project CI / AI game creator shell Rust crates (pull_request) Has been cancelled
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled
c0c5255b31
kdletters merged commit 67e95eee4e into master 2026-09-22 17:27:00 +08:00
kdletters deleted branch codex/game-distribution 2026-09-22 17:27:00 +08:00
Sign in to join this conversation.