docs(plan): plan-001 实现单元细化为 Mac 可直接执行版——读码实证 file 清单 + 命令级验收门 + 并入 build段设计
U1-U5 逐单元补:精确 file 路径(接哪个现有类/方法)、关键决策步骤、可跑验收命令。 并入 build段双证的优化设计: - U1 运行时约定 rt 面(getEntity/spawn/input/time-random 受控/score-win-lose latch/fx 真调引擎)落 game-runtime/src/host/gd-runtime.js,接 boot.ctx 受控面 - U2 build-from-source 装配六步(strip unknown-key+ajv/内联/createRuntime/声明式渲染器/取证派生/behavior沙箱),接 SaaGenNodes.scaffold/build,解锁 deterministic modify 路(现 guard fail-loud);复用 build.mjs+九门 harness 零改 - U3 generateNode 真产 gameDefinition 落 K_SOURCE_PROJECT,SaaPrompts 新 GAMEDEF_SYSTEM 与现 SYSTEM 物理隔离;难门优化(F门/latch/I_control/约定外helper/unknown-key strip)进 prompt+gatespec;cutover 量化门=过门率≥60%(iife 现基线) - U4 多模型回退链接现 callWithTimeoutAndRetry+looseParse+救场阶梯;deepseek-v4-flash 打底 - U5 ReAct=ReactAgent.asNode,九门 verdict 强制终止,挂 ToolCallLimitHook 接线锚读码核证(SaaStudioGraph.assemble §6.2 / source-project.schema.json / AigcExecutorProperties); file 两线分组(canonical §8):U1/U2 引擎线·U3-U5 后端线;验收门给精确 mvn -Dsaa.e2e=1 命令(mini-desktop)。 只改实现单元节,KTD/HTD/背景/进展结论不动。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
771619c7da
commit
5bff11dfaf
@ -76,40 +76,78 @@ flowchart LR
|
||||
|
||||
---
|
||||
|
||||
## 实现单元(产线化 · 接 canonical 接法A)
|
||||
## 实现单元(产线化 · 接 canonical 接法A · Mac 执行)
|
||||
|
||||
### U1. 运行时访问约定迭代 + 正式化(2D 适配器契约)
|
||||
> **执行分工说明(2026-06-18 新分工)**:Mac 执行全部开发,本节细到「拿了不回问就能干」。按 canonical execution §8 两线切分,file 天然分两组——**引擎线(`game-runtime/src/` + `scripts/build.mjs` 唯一构建脚本)= U1/U2** · **后端线(SAA Java `…/saa/`)= U3/U4/U5**。交汇契约 = `contracts/agent-loop/source-project.schema.json`(已冻,gameDefinition/profile/assets 全在内)。
|
||||
>
|
||||
> **接线实证锚(读码核证,SaaStudioGraph.assemble §6.2)**:全图主链 = `render→classify→design→generate→validate ─[ok]→ scaffold→asset→build→play ─[pass]→ player→emit`;失败救场阶梯 `repair/escalate/giveup`(配置锚 `AigcExecutorProperties`:`saaMaxRepairs=5`/`saaStage2ExtraRepairs=3`/`saaMaxPlayerRounds=1`)。**现产线=iife 路**:`generateNode` 产 `factorySrc`(state key `K_FACTORY_SRC`)→`scaffoldNode` 写 `generated-factory.js`→`buildNode` 跑 `build.mjs entry-bundle.js→bundle.iife.js`。**现缺口=`buildNode` 从 `gameDir/generated-factory.js` 构建、不读 `K_SOURCE_PROJECT`**(`SaaStudioNodes.modifyNode`/`buildNode` 注释均标「从 sourceProject 真构建=B7+引擎线 E2,本期未实现」)——U2 填的就是这条。
|
||||
>
|
||||
> **现产线成功率基线(cutover 门锚)**:`SaaFullGraphE2eTest`(iife 路)实测 **60%**(execution §「现 vs 目标产线」)。U3 cutover 量化门 = gameDefinition 路过门率 **≥ 60%**。
|
||||
|
||||
- **Goal**:把 spike 产的运行时约定 v0(`rt` 对象)落成 game-runtime 产线基座,迭代 1-2 轮补 idiom(spawn helper/entity 方法/事件钩子,收 3-5 类游戏真实模型输出),再正式化为契约 `contracts/agent-loop/runtime-api-2d.{schema.json,d.ts}`。
|
||||
- **Files**:`game-runtime/src/gd-runtime.js`(运行时库)、`contracts/agent-loop/runtime-api-2d.*`(正式化后)、约定喂进 prompt。
|
||||
- **Approach**:v0 = boot.ctx 的 behaviors 友好 2D 包装(KTD 2);迭代时收集模型自造的约定外访问(如 `_spawnFood`)→ 评估纳入或 prompt 约束。**别冻早**——1-2 轮稳定后再正式化。
|
||||
- **Verification**:3-5 类游戏的 behaviors 用约定全跑通(无约定外 helper 漂移);约定喂进 prompt 后模型遵循率。
|
||||
### U1. 运行时访问约定迭代 + 正式化(2D 适配器契约 · 引擎线/Mac)
|
||||
|
||||
### U2. build-from-source 产线化
|
||||
- **Goal**:把 spike 产的运行时约定 v0(注入每个 behavior 的 `rt` 对象)落成 game-runtime 产线基座(2D 适配器的 behavior 侧 API),迭代 1-2 轮补 idiom,再正式化为契约。这是 U2 装配器编译 behavior 时 `new Function('rt','self','dt',code)` 注入的那个 `rt`。
|
||||
- **Files(精确路径 + 接哪类)**:
|
||||
- 新建 `game-runtime/src/host/gd-runtime.js`——`createRuntime(boot, gameDefinition)` 工厂,产出 `rt` 对象 + 可变世界(entities 实例)。**接现有**:`boot.ctx`(受控面,见 `entry-bundle.template.js`:`boot={ctx,mainContext,canvas,seed}`)——`rt.time/rt.random` 包 `ctx.time.nowMs()`/`ctx.random.next/range`,`rt.input` 包 `ctx.getInput().on(...)`,`rt.fx.burst/beep` 包 `ctx.getEngine().particles.spawnEmitter`/`audio.synth.synthSfx`(满 F 门=真调引擎)。
|
||||
- 正式化产物(1-2 轮后)`contracts/agent-loop/runtime-api-2d.d.ts`(rt 接口 TS 定义)+ 可选 `runtime-api-2d.md`(idiom 文字契约,U3 喂 prompt 用)。**新增第 9/10 类契约,additive,不动现 8 契约。**
|
||||
- 约定文字同步喂进 prompt → 交 U3 落 `SaaPrompts` 新 SYSTEM(本单元只交付约定文本,不改 Java)。
|
||||
- **rt 面(spike v0 起点,逐条落 KTD 2)**:
|
||||
- 实体:`rt.getEntity(id)`/`rt.entities()`/`rt.query(kind)`/`rt.spawn({x,y,vx,vy,tags,components})`/`rt.destroy(e)`;实体含 `.x.y.vx.vy.alive.components.tags` + `.get/set/destroy()`。
|
||||
- 输入:`rt.input.isDown(key)`/`justPressed(key)`/`justTapped()`/`pointer{x,y,down}`。
|
||||
- 时间随机:`rt.time.now()`/`rt.dt`/`rt.random()`/`rt.randRange(a,b)`/`rt.randInt(a,b)`——**全走 `boot.ctx` 受控种子=确定性,禁 `Math.random`/`Date.now`**(对齐 `SaaGenNodes.staticCheck` 现有 12 禁用词)。
|
||||
- 分数胜负:`rt.score`/`addScore`/`setScore` + `rt.win()`/`rt.lose()`——**置 latch 终态 `gameover`(非 emit)**,驱动 `_forensicsView().state().phase` 恒驻留(对齐现 SYSTEM「P0 latch 硬约束」)。
|
||||
- 工具特效:`rt.clamp/dist/overlap(AABB)` + `rt.fx.burst(x,y,color)`/`rt.fx.beep(kind)`(经 `ctx.getEngine` 真调引擎=满 F 门)。
|
||||
- **Approach(关键决策)**:v0 = `boot.ctx` 的 behaviors 友好 2D 包装。**迭代别冻早**——收 3-5 类游戏(覆盖 realtime 躲避 / paddle-intercept 打砖块 / tap-targets 井字棋 / event 点击器 / runner)真实模型输出,把模型自造的约定外 helper(spike 实测 M3 自造 `rt._spawnFood`)评估纳入 idiom 或写进 prompt 约束;1-2 轮稳定后才正式化为契约。
|
||||
- **Verification(可跑命令)**:
|
||||
- `cd game-runtime && node --test test/unit/gd-runtime.test.mjs`——单测断言:`rt.random` 同种子可复现(确定性)、`rt.win()` 后 `phase` latch 驻留不可逆、`rt.fx.burst` 真触发 `ctx.getEngine` 调用(mock 引擎记 call-ID)。
|
||||
- 3-5 类游戏的 behaviors 用约定全跑通、零约定外 helper 漂移(收敛判据)。
|
||||
|
||||
- **Goal**:把 spike PoC(`build-from-source.mjs` 装配)产线化,接 SAA 编排 + 落库。
|
||||
- **Files**:`game-runtime/scripts/build-from-source.mjs`(产线版)、`game-cloud/.../saa/SaaGenNodes.java`(build 节点接 build-from-source,替现 factorySrc→esbuild)、`SaaStudioNodes.java`(移 build-from-source guard)。
|
||||
- **Approach**:① **ajv 严格校验**(替 PoC 轻量校验)② **behavior 沙箱+超时+错误回灌生成质量信号** ③ **渲染器扩**(精灵/图集/动画,现仅 rect/circle/fill)④ driver 形状标准化(_forensicsView 取证)⑤ 接 SAA build 节点 + 落库。复用九门 harness(零改)。
|
||||
- **Verification**:门控 e2e:gameDefinition→build-from-source→九门过门率 ≥ spike 基线;同 buildInputHash 字节等价(从源可复现)。
|
||||
### U2. build-from-source 产线化(引擎线/Mac · 唯一构建脚本不动)
|
||||
|
||||
### U3. generate 真产 gameDefinition(替现 iife 空壳)
|
||||
- **Goal**:把 spike PoC(gameDefinition→可玩 bundle 装配)产线化为 `game-runtime/src/` 的 2D 适配器(canonical §E1/§C7「唯一构建实现」),接 SAA build 节点,**解锁 deterministic modify 路**(现 `modifyNode` deterministic 分支 guard fail-loud,正是等这条管线)。
|
||||
- **Files(精确路径 + 接哪类)**:
|
||||
- 新建 `game-runtime/src/host/build-from-source.mjs`——核心函数 `assembleFactoryFromSource(sourceProject) → factorySrcString`(产出对齐现装载契约的 `generated-factory.js` 文本:`export default function createGame(opts){…return {init,update,render,destroy,_forensicsView}}`)。
|
||||
- **接现有(零改)**:产出文本 → `SaaGenNodes.scaffoldNode` 落 `generated-factory.js` → `scripts/build.mjs`(esbuild 锁参,**唯一构建脚本不动**)→ `bundle.iife.js` → `serve-and-play.sh` + `play.cdp.cjs` 九门(**harness 零改**)。`entry-bundle.template.js` 不动(它 `import './generated-factory.js'`,装配器只换 generated-factory.js 的来源)。
|
||||
- 改 `game-cloud/.../saa/SaaGenNodes.java`:`buildNode`/`scaffoldNode` 增「从 `K_SOURCE_PROJECT` 装配」路——scaffold 前若 `sourceProject` 非空则先调 `build-from-source.mjs`(node 子进程,复用 `runProcess` 统一运行器)产 `generated-factory.js`,再走现 esbuild;`factorySrc` 路保留为回退(见 U3 flag)。
|
||||
- 改 `game-cloud/.../saa/SaaStudioNodes.java`:`modifyNode` deterministic 分支 + `modifyRouter` 解除 fail-loud(现注释 `TODO(B7/engine-E2)`),deterministic→真路由 build(届时 sourceProject 改动生效)。
|
||||
- **装配步骤(落 build段实证设计 KTD 3,逐条)**:
|
||||
1. **strip unknown-key + 轻校验**:按 `source-project.schema.json` 白名单剥未知键(**产线容错必做**——spike 实证模型会塞 schema 外键),引用完整性校验(entity.components 引用存在、scene.entityRefs 存在);产线版用 **ajv 严格校验**替 PoC 轻量校验。
|
||||
2. **内联**:gameDefinition 内联进 `generated-factory.js`(default export `GameHostFactory`,对齐现装载契约)。
|
||||
3. **createRuntime**:`init` 调 U1 的 `createRuntime(boot, gameDefinition)` 建可变世界——entities 实例化 + behaviors 经 `new Function('rt','self','dt',code)` 编译 + rules 编 JS 布尔表达式。
|
||||
4. **内置声明式渲染器**:逐实体按 `components`(kind=render)画 rect/circle/fill(**behaviors 只写逻辑不画**);渲染器扩精灵/图集/动画为 additive(现仅 rect/circle/fill,消费 `assets[].ref` 属引擎线 E2/E3 后续)。
|
||||
5. **取证派生**:`_forensicsView().state()` 暴露 `phase/score/remaining` + 自动从 gameDefinition 派生 harness driver 形状(tap-targets/paddle-intercept,对齐 `SaaPrompts.extractGatespec` 的 driver 契约)。
|
||||
6. **behavior 沙箱**:`new Function` 编译加 try/catch + 超时,behavior 抛错回灌为生成质量信号(喂 repair feedback)。
|
||||
- **Verification(可跑命令)**:
|
||||
- 装配器单测:`cd game-runtime && node --test test/unit/build-from-source.test.mjs`——金样 gameDefinition → 装配 → `node --check` 过 + 含 `export default` + 四方法 + `_forensicsView`。
|
||||
- 端到端门控(mini-desktop):`SaaHarnessDriveTest` 改喂金样 gameDefinition(替金样 factory),`mvn -pl game-cloud/game-module-aigc/game-module-aigc-server test -Dtest=SaaHarnessDriveTest -DGAME_RUNTIME_DIR=/root/game-staging/repo/game-runtime` → gameDefinition→build-from-source→九门过门率 **≥ spike 基线(deepseek-v4-flash 3/4 款过门)**。
|
||||
- 确定性:同 `buildInputHash`(=`sha256(sourceHash+buildProfile)`,见 schema)字节等价(从源可复现)。
|
||||
|
||||
- **Goal**:generate 节点产出从 iife `factorySrc` 改为结构化 gameDefinition(喂运行时约定),落 `sourceProject.gameDefinition`。
|
||||
- **Files**:`SaaPrompts.java`(gameDefinition-producing SYSTEM,喂 U1 约定;与现 factory SYSTEM **物理隔离**)、`SaaStudioNodes.java`(generateNode 产 gameDefinition + unknown-key strip)。
|
||||
- **Approach**:prompt 喂 schema + 运行时约定 + 品类 prompt 模板(玩法模板);**additive**:迁移期 flag 二选一保现路;cutover 量化门(过门率 ≥ 现基线)。worker `prompt.py` 同步(W-G1 协调,否则 split-brain)。
|
||||
- **Verification**:真 LLM 产 gameDefinition 过 schema+引用完整性,经 U2 build→九门过门率 ≥ 现 factorySrc 基线。
|
||||
### U3. generate 真产 gameDefinition(替现 iife 空壳 · 后端线/Mac)
|
||||
|
||||
### U4. 模型可靠性兜底
|
||||
- **Goal**:`generateNode` 产出从 iife `factorySrc` 改为结构化 gameDefinition,落 `K_SOURCE_PROJECT`(state key 已存在,现 asset/modify 写、build 读),喂 U1 运行时约定。
|
||||
- **Files(精确路径 + 接哪类)**:
|
||||
- 改 `game-cloud/.../saa/SaaPrompts.java`:新增 `GAMEDEF_SYSTEM`(产 gameDefinition 的 SYSTEM)+ `buildGameDefMessages(...)`,**与现 `SYSTEM`(iife factory)物理隔离**(并存,不改现 SYSTEM 一字,公平性铁律)。新 SYSTEM 喂:① `source-project.schema.json` 结构 ② U1 运行时约定(rt 面 idiom)③ 品类 prompt 模板(玩法模板,据 `K_ARCHETYPE` 注入,见 KTD 6)。
|
||||
- 改 `game-cloud/.../saa/SaaStudioNodes.java`:`generateNode` 增「产 gameDefinition」路——抽 JSON(复用 `looseParse` 脏 JSON 容错)→ **unknown-key strip(产线容错必做)**→ 落 `K_SOURCE_PROJECT`。`validateNode` 同步:`factorySrc` 路走现 `staticCheck`,gameDefinition 路改校 schema + 引用完整性(交 U2 的 ajv 或 Java 侧 schema 校验)。
|
||||
- 改 worker `prompt.py`(W-G1 协调,**否则 split-brain**——SAA 与外置 worker 两条 prompt 必须同源)。
|
||||
- **Approach(关键决策)**:**additive 迁移**——`generateNode` 据 flag(复用 `AigcExecutorProperties`,如 `saaSourceMode=factory|gamedef`,默认 `factory` 保现路)二选一,cutover 由量化门把关。**cutover 量化门 = gameDefinition 路 `SaaFullGraphE2eTest` 过门率 ≥ 60%(iife 现基线)**;达标才切默认。
|
||||
- **难门优化(落 build段实证,逐条进 prompt + gatespec)**:① **F 门**:prompt 明确「每次碰撞/得分必调 `rt.fx`」;② **latch**:prompt 明确「单命/球落底即 `rt.lose()`」(置终态非 emit);③ **I_control**:输入要真驱动实体;④ **约定外 helper**:U1 约定补 idiom + 本 prompt 把约定喂全(治 spike 的 `rt._spawnFood` 漂移);⑤ **unknown-key strip 必做**。
|
||||
- **Verification(可跑命令)**:
|
||||
- 窄链(无 harness):`mvn -pl game-cloud/game-module-aigc/game-module-aigc-server test -Dtest=SaaNewApiGenerateSmokeTest -Dsaa.smoke=1`(需 `NEWAPI_KEY`)→ 真 LLM 产 gameDefinition 过 schema + 引用完整性。
|
||||
- 全链(mini-desktop):`NEWAPI_KEY=sk-… timeout 6000 mvn -pl game-cloud/game-module-aigc/game-module-aigc-server test -Dtest=SaaFullGraphE2eTest -Dsaa.e2e=1 -DGAME_RUNTIME_DIR=/root/game-staging/repo/game-runtime -Dsurefire.failIfNoSpecifiedTests=false` → gameDefinition→U2 build→九门过门率 **≥ 60%**。
|
||||
|
||||
- **Goal**:产线稳态——重试 + 多模型回退 + JSON 修复。
|
||||
- **Approach**:deepseek-v4-flash 打底(本批最稳 5/5);MiniMax 超时/返空/JSON 截断 → 重试 + 回退链 + JSON 修复;接现救场阶梯。
|
||||
- **Verification**:批量生成成功率(含可靠性兜底)稳定 ≥ 目标。
|
||||
### U4. 模型可靠性兜底(后端线/Mac · 多接现成)
|
||||
|
||||
### U5. ReAct 演进(接法B · 地基稳后)
|
||||
- **Goal**:产线稳态——重试 + 多模型回退链 + JSON 修复。
|
||||
- **Files(精确路径 + 接哪类)**:`game-cloud/.../saa/SaaStudioNodes.java`——**接现成**:`callWithTimeoutAndRetry`(已有:单次 180s 超时 + ≤3 重试,只重 429/5xx/IO/timeout)+ `looseParse`(已有:三关脏 JSON 救活)。**本单元增量 = 多模型回退链**:`generateNode` 主模型(deepseek-v4-flash)耗尽重试后,回退到备选模型(M3/M2.7/DS-V4)再试;模型档与 `K_MODEL_TIER`(stage1/stage2)救场升档协同(escalate 已有)。
|
||||
- **Approach(关键决策)**:**deepseek-v4-flash 打底最稳(本批 5/5)**;MiniMax 超时 / M2.5 返空 / deepseek 偶发 JSON 截断 → 重试(已有)+ **多模型回退链(本单元增)**+ JSON 修复(`looseParse` 已有)。回退链接现救场阶梯(`okElseRepairOrEscalateOrGiveup`),不另起一套限次。
|
||||
- **Verification(可跑命令)**:批量 `SaaFullGraphE2eTest -Dsaa.e2e.n=10`(mini-desktop,10 条多品类)→ 含可靠性兜底后成功率稳定 ≥ 目标;单测断言回退链:主模型构造异常 → 自动切备选(mock ChatModel 抛 `TransientAiException`,断言切到备选模型名)。
|
||||
|
||||
- **Goal**:generate/repair 节点 → ReactAgent 自治 tool-use loop(写源/build/跑九门/读错/改 config-asset 为 tools),主 agent 据品类动态调度子 agent。
|
||||
- **Approach**:SAA 原生 ReactAgent/asNode/subAgents(能力够,见 [[saa-agentic-infra-decision]]);**九门 verdict 作强制终止条件**(自治在门内、裁决在门外,不破反 Goodhart 铁律);挂 ModelCallLimitHook/ToolCallLimitHook(ReAct 默认无限);依赖坑(agent-framework Boot 版本)前置 `dependency:tree` 核。
|
||||
- **Verification**:agentic loop 过门率/成本 vs 接法A;便宜模型 tool-use 可靠性实测(未知,需验)。
|
||||
### U5. ReAct 演进(接法B · 后端线/Mac · 地基稳后)
|
||||
|
||||
- **Goal**:`generate`/`repair` 节点 → SAA `ReactAgent` 自治 tool-use loop(写源/build/跑九门/读错/改 config-asset 为 tools),主 agent 据品类动态调度子 agent。
|
||||
- **Files(精确路径 + 接哪类)**:`game-cloud/.../saa/`——`SaaStudioGraph.assemble` 把 `generate`/`repair` 单发节点(现 `node_async(SaaStudioNodes.generateNode(...))`)换成 `ReactAgent.asNode`;tools 包装现有节点逻辑(`buildNode`/`playNode`/`build-from-source`/读 verdict/改 sourceProject config)为 SAA `ToolCallback`。
|
||||
- **Approach(关键决策)**:SAA 原生 `ReactAgent`/`asNode`/`subAgents`(能力够,见 [[saa-agentic-infra-decision]],GA v1.1.2.2);**九门 verdict 作强制终止条件**(自治在门内、裁决在门外,不破反 Goodhart 铁律,review §10.5 留口);挂 `ModelCallLimitHook`/`ToolCallLimitHook`(ReAct 默认无限,必挂);依赖坑(SAA 要 Boot 3.5.8 vs 项目版本,见 [[saa-agentic-infra-decision]])前置 `mvn dependency:tree` 核。
|
||||
- **Verification(可跑命令)**:`SaaFullGraphE2eTest`(ReAct 路)过门率/成本 vs 接法A;单测断言 `ToolCallLimitHook` 命中即终止(防无限 loop)。**便宜模型 tool-use 可靠性实测(未知,需验)。**
|
||||
- **Note**:地基(U1-U4)稳后才上;先只对九门测不了的品类(如 narrative)真需自治。
|
||||
|
||||
---
|
||||
@ -143,4 +181,4 @@ flowchart LR
|
||||
| 生成可靠(R-WORKER 稳态) | U4 |
|
||||
| agent-native 工作室(创始人愿景) | U5(接法B) |
|
||||
|
||||
> **执行姿势**:U1(约定基座,先行)→ U2(build 产线化)→ U3(generate 真产,接 U1/U2)→ U4(可靠性)→ 地基稳 → U5(ReAct 演进)。每单元 codex 评审。测试机 mini-desktop。架构 SoT 见 canonical(固定架构与SAA-agentic-studio,现归本 session)。
|
||||
> **执行姿势**:**U1(约定基座,先行)→ U2(build 产线化,接 U1)→ U3(generate 真产,接 U1/U2)→ U4(可靠性)→ 地基稳 → U5(ReAct 演进)**。依赖:U2 编译 behavior 注入 U1 的 `rt`;U3 的 gameDefinition 经 U2 装配过门。**file 两线分组(canonical §8)**:U1/U2=引擎线(`game-runtime/src/` + `scripts/build.mjs` 不动);U3/U4/U5=后端线(SAA Java `…/saa/`);交汇=`source-project.schema.json`。Mac 全执行,可按两线并行(U1→U2 与 U3 prompt 起草不强串)。每单元 codex 一轮评审(实现已过 2 轮评审的 spec,单轮即可)。**测试机 mini-desktop**(harness 需 node+esbuild+Chrome+端口 4320/9222;`GAME_RUNTIME_DIR=/root/game-staging/repo/game-runtime`)。架构 SoT 见 canonical(固定架构与SAA-agentic-studio,现归本 session)。
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user