修复发行资源路径与审核试玩 Cookie
Project CI / Backend tests (pull_request) Failing after 29s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 1m48s
Project CI / Frontend tests (pull_request) Failing after 1m11s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Failing after 3m18s
Project CI / Repository checks (pull_request) Failing after 42s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Failing after 4m13s
Project CI / AI game creator shell web tests (pull_request) Successful in 2m15s
Project CI / Native shell tests (pull_request) Successful in 6m37s
Project CI / Backend tests (pull_request) Failing after 29s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 1m48s
Project CI / Frontend tests (pull_request) Failing after 1m11s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Failing after 3m18s
Project CI / Repository checks (pull_request) Failing after 42s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Failing after 4m13s
Project CI / AI game creator shell web tests (pull_request) Successful in 2m15s
Project CI / Native shell tests (pull_request) Successful in 6m37s
归一化发行包根绝对资源引用并兼容已有发行包,修复正式运行时素材请求跑到本地 Vite 的问题。 审核预览仅拒绝真实平台 refresh Cookie,保留版本绑定 Token 和私有缓存隔离。
This commit is contained in:
@@ -83,13 +83,13 @@
|
||||
### 真实发行包与资料合同
|
||||
|
||||
1. AGC 发布取当前 npm 工程已成功构建的 `dist/` 内容,重新检查入口和实际字节;ZIP 内部必须把 `dist/index.html` 归一化为根 `index.html`,其余路径相对发行根保持不变。不得上传整个项目、源码快照或仅发送本地路径。网页 ZIP 同样要求根 `index.html`,不猜测并自动剥离多层目录。
|
||||
2. 所有运行依赖都必须在发行包内。资源 URL 使用与发行版本目录兼容的相对地址;前导 `/assets`、本地文件 URL、外部脚本/样式/媒体/字体地址均不属于可接受发行合同。客户端给出可操作错误,服务器仍独立校验;静态校验不能代替运行时 CSP 阻断。
|
||||
2. 所有运行依赖都必须在发行包内。资源 URL 使用与发行版本目录兼容的相对地址;前导 `/assets`、本地文件 URL、外部脚本/样式/媒体/字体地址均不属于可接受发行合同。AGC 发布归一化阶段只把包内已知根路径 `/assets/`、`/game/`、`/ui/` 转成相对引用,不修改项目源码;其它外部绝对地址仍由客户端/服务器拒绝,静态校验不能代替运行时 CSP 阻断。
|
||||
3. 建议首版限额:压缩包 100 MiB、展开总量 250 MiB、单文件 64 MiB、最多 10,000 个文件、展开/压缩比不超过 100。服务端拒绝加密 ZIP、重复或大小写冲突路径、绝对路径、`..`、符号链接/重解析点、设备文件和嵌套压缩包;拒绝 `.agent`、版本控制目录、`node_modules`、凭据文件与源码映射文件。超限返回明确错误,不截断后继续发布。
|
||||
4. 提交声明 ZIP 的 SHA-256 与字节数,服务端对收到的真实 ZIP 重新计算,再对展开文件建立相对路径、字节数和 SHA-256 清单。摘要不一致、缺文件或入口损坏时停止;只有 metadata 而没有已确认完整对象的提交必须失败。
|
||||
5. 游戏资料随发行版本冻结:标题 2–40 字、短简介不超过 120 字、详细介绍不超过 2,000 字、一个分类、最多 5 个标签(每个不超过 20 字)、必需封面、最多 6 张截图、操作方式不超过 240 字。分类首版为休闲、益智、动作、冒险、模拟、策略、其他;封面/截图复用平台图片上传与归属校验,不接受任意外链作为审核图片。作者不需要自己构建或打 ZIP:AGC 发布时对 `game/` 子工程按需执行 `npm install` 和 `npm run build`,将 `dist` 归一化为根 `index.html` ZIP;为兼容 AGC 上传素材的运行 URL,会补入项目根 `assets/**` 中 dist 未包含的文件,同路径以 dist 构建产物为准,不修改项目源码。
|
||||
6. `supportedDevices` 至少包含 `desktop` 或 `mobile`;`inputModes` 来自 `keyboard`、`mouse`、`touch`;声明移动端必须包含 `touch`。`orientation` 为 `landscape`、`portrait` 或 `responsive`。这些是待人工复核的作者声明,目录只显示已经随版本审核通过的值。
|
||||
7. 原始 ZIP、未审核展开目录、审核资料均为私有对象;公开版本不暴露源码镜像键、本地路径、访问凭据或私有账号元数据。运行文件只能由发行网关按游戏、版本和文件白名单读取,不能绕过网关访问公开 OSS bucket。
|
||||
8. 现役发行网关由 `api-server` 提供:`GET /api/game-distribution/releases/{gameId}`(含尾斜杠)等价于该游戏的 `index.html`,`GET /api/game-distribution/releases/{gameId}/{assetPath}` 只服务当前已公开版本包内的文件,私有 ZIP 与未公开版本不因知道 ID 而可读。响应按扩展名白名单设定内容类型,未知扩展名返回 404;全部响应带 `X-Content-Type-Options: nosniff`、`Cross-Origin-Resource-Policy: cross-origin` 与不带 credentials 的 `Access-Control-Allow-Origin: *`(发行文档运行在 `allow-scripts` 的 opaque origin 沙箱里,`same-origin` 会让游戏自己的脚本被浏览器拦下),HTML 追加最小权限 CSP,并在游戏脚本前注入隔离的运行期 `localStorage` / `sessionStorage` 兼容层,避免游戏直接读取 opaque origin 原生 storage 时抛 `SecurityError`。兼容层只在当前运行实例内存中有效,不读取平台 Cookie、主站 DOM 或账号数据。带平台 `Cookie` 的请求一律 `403`;边缘在转发到发行网关前清空 `Cookie`。发行包按对象键在进程内做有界缓存,单个超预算包不进入缓存。
|
||||
8. 现役发行网关由 `api-server` 提供:`GET /api/game-distribution/releases/{gameId}`(含尾斜杠)等价于该游戏的 `index.html`,`GET /api/game-distribution/releases/{gameId}/{assetPath}` 只服务当前已公开版本包内的文件,私有 ZIP 与未公开版本不因知道 ID 而可读。响应按扩展名白名单设定内容类型,未知扩展名返回 404;全部响应带 `X-Content-Type-Options: nosniff`、`Cross-Origin-Resource-Policy: cross-origin` 与不带 credentials 的 `Access-Control-Allow-Origin: *`(发行文档运行在 `allow-scripts` 的 opaque origin 沙箱里,`same-origin` 会让游戏自己的脚本被浏览器拦下),HTML 追加最小权限 CSP,并在游戏脚本前注入隔离的运行期 `localStorage` / `sessionStorage` 兼容层,避免游戏直接读取 opaque origin 原生 storage 时抛 `SecurityError`。兼容层只在当前运行实例内存中有效,不读取平台 Cookie、主站 DOM 或账号数据。公开发行与审核预览只拒绝真实平台 refresh Cookie;审核预览 Token 绑定单个版本且短期有效。发行包按对象键在进程内做有界缓存,单个超预算包不进入缓存。
|
||||
9. 发行入口既不由管理员填写,也不需要部署侧配置:审核通过时 `api-server` 按 gameId 派生**平台同源路径** `/games/{gameId}/` 写入公开投影,dev / release / 预览环境口径完全一致,不再需要发行域名、通配 DNS 或通配证书。gameId 必须是服务端生成的稳定标识(只允许 `[A-Za-z0-9_-]`),派生失败时审核通过直接失败,不回落主站其它路径、内网地址或任意外部地址。客户端读取该字段时按当前 origin 解析成绝对地址再交给 iframe;历史数据里的绝对 URL(非当前源的 https)继续兼容,新写入只用相对路径。路径到发行网关的映射由边缘 nginx 的同源发行入口 location 完成。
|
||||
|
||||
### 身份、状态、审核与更新
|
||||
|
||||
Reference in New Issue
Block a user