Preserve partial creation replies on stream failure
Some checks failed
CI / verify (push) Has been cancelled
Some checks failed
CI / verify (push) Has been cancelled
This commit is contained in:
@@ -1,4 +0,0 @@
|
|||||||
interface:
|
|
||||||
display_name: "新增玩法入口"
|
|
||||||
short_description: "把新增玩法入口的文档、配置、路由和验证流程一次收口"
|
|
||||||
default_prompt: "Use $genarrative-gameplay-entry-type to add a new gameplay entry type end to end in Genarrative."
|
|
||||||
@@ -13,12 +13,14 @@
|
|||||||
重点补充:RPG 创作与运行时脚本职责地图见 [RPG_CREATION_AND_RUNTIME_SCRIPT_RESPONSIBILITY_MAP_2026-04-28.md](./reference/RPG_CREATION_AND_RUNTIME_SCRIPT_RESPONSIBILITY_MAP_2026-04-28.md)。
|
重点补充:RPG 创作与运行时脚本职责地图见 [RPG_CREATION_AND_RUNTIME_SCRIPT_RESPONSIBILITY_MAP_2026-04-28.md](./reference/RPG_CREATION_AND_RUNTIME_SCRIPT_RESPONSIBILITY_MAP_2026-04-28.md)。
|
||||||
- [埋点查询](./tracking/README.md):埋点原始事件与聚合投影的本地 SQL 查询。
|
- [埋点查询](./tracking/README.md):埋点原始事件与聚合投影的本地 SQL 查询。
|
||||||
- [运营查询](./operations/README.md):任务、领奖、钱包对账等后台核查查询。
|
- [运营查询](./operations/README.md):任务、领奖、钱包对账等后台核查查询。
|
||||||
- [PRD](./prd):产品需求与阶段计划;后台管理独立前端工程见 [ADMIN_WEB_CONSOLE_PRD_2026-04-30.md](./prd/ADMIN_WEB_CONSOLE_PRD_2026-04-30.md),新增 RPG 开场动画方案见 [AI_NATIVE_RPG_OPENING_ANIMATION_PRD_2026-04-25.md](./prd/AI_NATIVE_RPG_OPENING_ANIMATION_PRD_2026-04-25.md),新增抓大鹅 Match3D 玩法方案见 [AI_NATIVE_MATCH3D_CREATOR_AND_GAMEPLAY_SYSTEM_PRD_2026-04-30.md](./prd/AI_NATIVE_MATCH3D_CREATOR_AND_GAMEPLAY_SYSTEM_PRD_2026-04-30.md)。
|
- [PRD](./prd):产品需求与阶段计划;后台管理独立前端工程见 [ADMIN_WEB_CONSOLE_PRD_2026-04-30.md](./prd/ADMIN_WEB_CONSOLE_PRD_2026-04-30.md),新增 RPG 开场动画方案见 [AI_NATIVE_RPG_OPENING_ANIMATION_PRD_2026-04-25.md](./prd/AI_NATIVE_RPG_OPENING_ANIMATION_PRD_2026-04-25.md),新增抓大鹅 Match3D 玩法方案见 [AI_NATIVE_MATCH3D_CREATOR_AND_GAMEPLAY_SYSTEM_PRD_2026-04-30.md](./prd/AI_NATIVE_MATCH3D_CREATOR_AND_GAMEPLAY_SYSTEM_PRD_2026-04-30.md),方洞挑战创作、发布与试玩闭环见 [AI_NATIVE_SQUARE_HOLE_CREATOR_AND_GAMEPLAY_SYSTEM_PRD_2026-05-04.md](./prd/AI_NATIVE_SQUARE_HOLE_CREATOR_AND_GAMEPLAY_SYSTEM_PRD_2026-05-04.md)。
|
||||||
|
|
||||||
生产部署切换到 systemd + Nginx + SpacetimeDB 自托管的总方案见 [PRODUCTION_DEPLOYMENT_PLAN_2026-05-02.md](./technical/PRODUCTION_DEPLOYMENT_PLAN_2026-05-02.md),该文档也是当前生产 Jenkinsfile 的唯一入口。SpacetimeDB 表结构变更、自动迁移边界和保留旧数据的分阶段迁移流程见 [SPACETIMEDB_SCHEMA_CHANGE_CONSTRAINTS.md](./technical/SPACETIMEDB_SCHEMA_CHANGE_CONSTRAINTS.md);private 表迁移 JSON 导入导出、HTTP 413 分片导入和旧数据库迁移流水线经验见 [SPACETIMEDB_JSON_STRING_MIGRATION_PROCEDURE_2026-04-27.md](./technical/SPACETIMEDB_JSON_STRING_MIGRATION_PROCEDURE_2026-04-27.md) 与 [JENKINS_SPACETIMEDB_DATABASE_MIGRATION_PIPELINES_2026-04-29.md](./technical/JENKINS_SPACETIMEDB_DATABASE_MIGRATION_PIPELINES_2026-04-29.md);后台管理独立前端工程技术方案见 [ADMIN_WEB_CONSOLE_TECHNICAL_SOLUTION_2026-04-30.md](./technical/ADMIN_WEB_CONSOLE_TECHNICAL_SOLUTION_2026-04-30.md)。
|
生产部署切换到 systemd + Nginx + SpacetimeDB 自托管的总方案见 [PRODUCTION_DEPLOYMENT_PLAN_2026-05-02.md](./technical/PRODUCTION_DEPLOYMENT_PLAN_2026-05-02.md),该文档也是当前生产 Jenkinsfile 的唯一入口。SpacetimeDB 表结构变更、自动迁移边界和保留旧数据的分阶段迁移流程见 [SPACETIMEDB_SCHEMA_CHANGE_CONSTRAINTS.md](./technical/SPACETIMEDB_SCHEMA_CHANGE_CONSTRAINTS.md);private 表迁移 JSON 导入导出、HTTP 413 分片导入和旧数据库迁移流水线经验见 [SPACETIMEDB_JSON_STRING_MIGRATION_PROCEDURE_2026-04-27.md](./technical/SPACETIMEDB_JSON_STRING_MIGRATION_PROCEDURE_2026-04-27.md) 与 [JENKINS_SPACETIMEDB_DATABASE_MIGRATION_PIPELINES_2026-04-29.md](./technical/JENKINS_SPACETIMEDB_DATABASE_MIGRATION_PIPELINES_2026-04-29.md);后台管理独立前端工程技术方案见 [ADMIN_WEB_CONSOLE_TECHNICAL_SOLUTION_2026-04-30.md](./technical/ADMIN_WEB_CONSOLE_TECHNICAL_SOLUTION_2026-04-30.md)。
|
||||||
|
|
||||||
SpacetimeDB 表结构变更、自动迁移边界和保留旧数据的分阶段迁移流程见 [SPACETIMEDB_SCHEMA_CHANGE_CONSTRAINTS.md](./technical/SPACETIMEDB_SCHEMA_CHANGE_CONSTRAINTS.md)。
|
SpacetimeDB 表结构变更、自动迁移边界和保留旧数据的分阶段迁移流程见 [SPACETIMEDB_SCHEMA_CHANGE_CONSTRAINTS.md](./technical/SPACETIMEDB_SCHEMA_CHANGE_CONSTRAINTS.md)。
|
||||||
|
|
||||||
|
创作 Agent 问答流式失败时保留已显示回复、并透出更具体上游错误的契约见 [CREATION_AGENT_STREAM_FAILURE_RETENTION_FIX_2026-05-05.md](./technical/CREATION_AGENT_STREAM_FAILURE_RETENTION_FIX_2026-05-05.md)。
|
||||||
|
|
||||||
## 推荐阅读顺序
|
## 推荐阅读顺序
|
||||||
|
|
||||||
1. 先看 [经验沉淀](./experience/README.md),快速建立这个项目的开发共识。
|
1. 先看 [经验沉淀](./experience/README.md),快速建立这个项目的开发共识。
|
||||||
|
|||||||
@@ -0,0 +1,278 @@
|
|||||||
|
# AI 原生方洞挑战玩法创作工具与玩法系统 PRD
|
||||||
|
|
||||||
|
更新时间:`2026-05-04`
|
||||||
|
|
||||||
|
## 0. 文档目的
|
||||||
|
|
||||||
|
这份 PRD 用于在当前平台内新增一条“方洞挑战”玩法类型,并先冻结它从入口占位到完整可创建闭环的产品边界。
|
||||||
|
|
||||||
|
本玩法来自参考视频中的核心反差:玩家看到不同形状的积木与多个洞口,会本能判断“形状应放入对应洞口”,但演示不断把不同形状都放进同一个方洞,形成“规则预期被打破”的喜剧张力。
|
||||||
|
|
||||||
|
本次不是简单复制视频内容,也不是只新增一个前端小游戏。正式版本需要把这种反直觉机制抽象成平台内可创作、可试玩、可发布的玩法类型。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. 一句话定义
|
||||||
|
|
||||||
|
“方洞挑战”是一个反直觉形状分拣玩法:百梦主通过 Agent 设定形状主题、洞口规则、误导节奏和反差演出,系统生成一个移动端优先的单局挑战;玩家在限时内把连续出现的形状投入正确洞口,后端根据当前关卡的真实兼容规则裁决成功、失败和连击。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 当前接入级别
|
||||||
|
|
||||||
|
根据 `genarrative-play-type-integration` 的接入分级,本次落地到 **完整玩法闭环**:
|
||||||
|
|
||||||
|
1. 新增玩法 ID:`square-hole`。
|
||||||
|
2. 新增展示名称:`方洞挑战`。
|
||||||
|
3. 新增子标题:`反直觉形状分拣`。
|
||||||
|
4. 在新建作品入口、创作类型弹层、结果页、运行态和作品架展示。
|
||||||
|
5. 支持 Agent 创作、草稿生成、结果页编辑、试玩、发布和公开运行。
|
||||||
|
6. 后端以 `server-rs + Axum + SpacetimeDB` 为真相源,前端只渲染快照与交互。
|
||||||
|
|
||||||
|
不允许把运行规则临时写成前端本地真相,也不复用 `server-node`、Express 或 PostgreSQL。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. 产品定位
|
||||||
|
|
||||||
|
## 3.1 模板名称
|
||||||
|
|
||||||
|
1. 对外模板名称:`方洞挑战`。
|
||||||
|
2. 对外子标题:`反直觉形状分拣`。
|
||||||
|
3. 开发代号:`SquareHole`。
|
||||||
|
4. 工程玩法域:`square-hole`。
|
||||||
|
5. 后端模块命名预期:`square_hole`。
|
||||||
|
|
||||||
|
## 3.2 核心乐趣
|
||||||
|
|
||||||
|
1. 玩家先根据形状轮廓做直觉判断。
|
||||||
|
2. 关卡通过洞口、提示、视觉遮挡和演出制造误导。
|
||||||
|
3. 真实规则可以是“方洞万能”“指定洞口万能”“颜色优先于形状”“本轮只看尺寸”等反直觉规则。
|
||||||
|
4. 玩家通过连续试探和反馈理解规则,形成短局重复挑战。
|
||||||
|
|
||||||
|
## 3.3 与现有玩法的区别
|
||||||
|
|
||||||
|
1. 不等同于拼图:不切图、不交换、不合并拼块。
|
||||||
|
2. 不等同于抓大鹅:不做三消备选栏,不做堆叠遮挡点击。
|
||||||
|
3. 不等同于大鱼吃小鱼:不做摇杆移动、吞噬、成长等级。
|
||||||
|
4. 不复用 RPG 的世界、角色、章节或剧情推进结构。
|
||||||
|
5. 运行态只保留“当前形状 + 洞口选择 + 后端裁决”,不在前端写正式规则真相。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. 完整闭环目标
|
||||||
|
|
||||||
|
本次完整闭环必须补齐:
|
||||||
|
|
||||||
|
1. 平台创作入口选择“方洞挑战”。
|
||||||
|
2. Agent 对话收集玩法锚点。
|
||||||
|
3. 生成方洞挑战草稿。
|
||||||
|
4. 进入结果页编辑作品名、标签、封面、形状数量、反差规则和视觉主题。
|
||||||
|
5. 支持发布前试玩。
|
||||||
|
6. 发布作品。
|
||||||
|
7. 玩家从作品详情或广场进入运行态。
|
||||||
|
8. 后端初始化单局形状队列、洞口兼容规则和计分状态。
|
||||||
|
9. 玩家拖拽或点击形状投入洞口。
|
||||||
|
10. 后端裁决投入结果、连击、扣时、失败、胜利和成绩。
|
||||||
|
11. 前端只渲染后端快照与即时反馈,不承接正式规则真相。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. 创作锚点设计
|
||||||
|
|
||||||
|
Agent 型创作版本至少收集下面 5 个锚点:
|
||||||
|
|
||||||
|
| 锚点 | 字段建议 | 用途 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| 主题外观 | `themePrompt` | 决定玩具、洞板、背景、形状材质和色彩风格。 |
|
||||||
|
| 反差规则 | `twistRule` | 决定“为什么不是按形状匹配”的真实判定规则。 |
|
||||||
|
| 洞口组 | `holeSet` | 决定本局出现的洞口种类、数量、位置和视觉误导强度。 |
|
||||||
|
| 形状队列 | `shapeSequence` | 决定连续出现的形状、颜色、大小和难度递增。 |
|
||||||
|
| 反馈节奏 | `feedbackRhythm` | 决定成功、错误、连击、惊讶和结算演出风格。 |
|
||||||
|
|
||||||
|
Agent 需要把玩家一句灵感收束为上述锚点,不允许逐项盘问低价值字段。
|
||||||
|
|
||||||
|
## 5.1 Agent AI 生成契约
|
||||||
|
|
||||||
|
方洞挑战的创作对话必须接入 `api-server` 的现有 LLM 能力,不能把用户输入解析成固定模板后直接写回会话。工程实现以 `state.llm_client()` 为唯一模型入口,通过方洞专属 Agent turn 生成回复与下一轮配置。
|
||||||
|
|
||||||
|
单轮模型输出必须是严格 JSON:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"replyText": "",
|
||||||
|
"progressPercent": 0,
|
||||||
|
"nextConfig": {
|
||||||
|
"themeText": "",
|
||||||
|
"twistRule": "",
|
||||||
|
"shapeCount": 12,
|
||||||
|
"difficulty": 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
落地约束:
|
||||||
|
|
||||||
|
1. `replyText` 是直接展示给百梦主的中文回复,不得出现 JSON、字段名、内部结构等说明。
|
||||||
|
2. `nextConfig` 必须是完整配置,不允许只输出 patch;缺失字段只能由后端用当前会话配置兜底。
|
||||||
|
3. `shapeCount` 由后端限制在 `6` 到 `24`,`difficulty` 限制在 `1` 到 `10`。
|
||||||
|
4. `quickFillRequested=true` 时,模型应直接补齐剩余配置,后端把 `progressPercent` 固定为 `100`。
|
||||||
|
5. 模型不可用或结果无法解析时,接口返回明确错误,不允许用确定性模板伪装成 AI 回复。
|
||||||
|
6. 非流式消息接口和 SSE 流式消息接口都必须走同一套方洞 Agent turn,SSE 只额外负责把 `replyText` 增量回传。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. 运行规则设计
|
||||||
|
|
||||||
|
## 6.1 单局结构
|
||||||
|
|
||||||
|
1. 单局默认 `60` 秒。
|
||||||
|
2. 每局默认 `12` 个形状。
|
||||||
|
3. 洞口数量默认 `4` 到 `6` 个。
|
||||||
|
4. 玩家每次只能操作当前形状。
|
||||||
|
5. 正确投入后进入下一个形状。
|
||||||
|
6. 错误投入扣除时间或清空连击。
|
||||||
|
7. 全部形状完成即胜利。
|
||||||
|
8. 时间归零即失败。
|
||||||
|
|
||||||
|
## 6.2 真实兼容规则
|
||||||
|
|
||||||
|
首版可支持下面几类规则:
|
||||||
|
|
||||||
|
1. `shape_match`:形状轮廓匹配。
|
||||||
|
2. `square_hole_priority`:方洞兼容所有形状,其他洞口只作为误导。
|
||||||
|
3. `color_match`:颜色优先于形状。
|
||||||
|
4. `size_match`:尺寸优先于形状。
|
||||||
|
5. `round_prompt`:本轮按后端给出的短提示规则判定。
|
||||||
|
|
||||||
|
其中 `square_hole_priority` 是参考视频核心反差的首选默认规则。
|
||||||
|
|
||||||
|
## 6.3 前端表现
|
||||||
|
|
||||||
|
1. 竖屏优先,桌面端居中显示游戏台。
|
||||||
|
2. 当前形状位于屏幕下半区域,洞板位于上半区域。
|
||||||
|
3. 只显示必要状态:剩余时间、连击、当前进度。
|
||||||
|
4. 不默认展示长篇规则说明。
|
||||||
|
5. 错误反馈用短促动画、颜色闪烁和轻量文字状态,不堆解释。
|
||||||
|
6. 点击按钮弹出的配置或结算必须使用独立面板,不在当前面板下方展开。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. 后端分层边界
|
||||||
|
|
||||||
|
完整实现时必须遵循当前 `server-rs + Axum + SpacetimeDB` 路线:
|
||||||
|
|
||||||
|
1. `server-rs/crates/module-square-hole`
|
||||||
|
- 纯领域规则、形状队列生成、兼容性裁决、分数计算。
|
||||||
|
- 不依赖 Axum、SpacetimeDB、OSS 或 LLM。
|
||||||
|
2. `server-rs/crates/shared-contracts`
|
||||||
|
- 暴露 Agent、作品、运行态 DTO。
|
||||||
|
3. `server-rs/crates/spacetime-module`
|
||||||
|
- 存储 session、message、work profile、runtime run。
|
||||||
|
- 表结构变化必须同步 `migration.rs` 与表目录。
|
||||||
|
4. `server-rs/crates/spacetime-client`
|
||||||
|
- 提供 api-server 调用 SpacetimeDB 的 typed facade。
|
||||||
|
5. `server-rs/crates/api-server`
|
||||||
|
- 暴露 `/api/creation/square-hole/*` 与 `/api/runtime/square-hole/*`。
|
||||||
|
- 处理鉴权、错误 envelope、LLM turn 和 HTTP facade。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. 数据模型
|
||||||
|
|
||||||
|
## 8.1 创作 session
|
||||||
|
|
||||||
|
1. `sessionId`
|
||||||
|
2. `ownerUserId`
|
||||||
|
3. `currentTurn`
|
||||||
|
4. `progressPercent`
|
||||||
|
5. `stage`
|
||||||
|
6. `config`
|
||||||
|
7. `draft`
|
||||||
|
8. `messages`
|
||||||
|
9. `lastAssistantReply`
|
||||||
|
10. `publishedProfileId`
|
||||||
|
|
||||||
|
## 8.2 结果页 work profile
|
||||||
|
|
||||||
|
1. `workId`
|
||||||
|
2. `profileId`
|
||||||
|
3. `ownerUserId`
|
||||||
|
4. `sourceSessionId`
|
||||||
|
5. `gameName`
|
||||||
|
6. `themeText`
|
||||||
|
7. `twistRule`
|
||||||
|
8. `summary`
|
||||||
|
9. `tags`
|
||||||
|
10. `coverImageSrc`
|
||||||
|
11. `shapeCount`
|
||||||
|
12. `difficulty`
|
||||||
|
13. `publicationStatus`
|
||||||
|
14. `playCount`
|
||||||
|
15. `updatedAt`
|
||||||
|
16. `publishedAt`
|
||||||
|
|
||||||
|
## 8.3 运行态 run snapshot
|
||||||
|
|
||||||
|
1. `runId`
|
||||||
|
2. `profileId`
|
||||||
|
3. `ownerUserId`
|
||||||
|
4. `status`
|
||||||
|
5. `snapshotVersion`
|
||||||
|
6. `startedAtMs`
|
||||||
|
7. `durationLimitMs`
|
||||||
|
8. `remainingMs`
|
||||||
|
9. `totalShapeCount`
|
||||||
|
10. `completedShapeCount`
|
||||||
|
11. `combo`
|
||||||
|
12. `bestCombo`
|
||||||
|
13. `score`
|
||||||
|
14. `ruleLabel`
|
||||||
|
15. `currentShape`
|
||||||
|
16. `holes`
|
||||||
|
17. `lastFeedback`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. API 设计
|
||||||
|
|
||||||
|
## 9.1 创作接口
|
||||||
|
|
||||||
|
1. `POST /api/creation/square-hole/sessions`
|
||||||
|
2. `GET /api/creation/square-hole/sessions/{sessionId}`
|
||||||
|
3. `POST /api/creation/square-hole/sessions/{sessionId}/messages`
|
||||||
|
4. `POST /api/creation/square-hole/sessions/{sessionId}/messages/stream`
|
||||||
|
5. `POST /api/creation/square-hole/sessions/{sessionId}/actions`
|
||||||
|
6. `POST /api/creation/square-hole/sessions/{sessionId}/compile`
|
||||||
|
7. `GET /api/creation/square-hole/works`
|
||||||
|
8. `GET /api/creation/square-hole/works/{profileId}`
|
||||||
|
9. `PUT /api/creation/square-hole/works/{profileId}`
|
||||||
|
10. `POST /api/creation/square-hole/works/{profileId}/publish`
|
||||||
|
11. `DELETE /api/creation/square-hole/works/{profileId}`
|
||||||
|
|
||||||
|
## 9.2 运行接口
|
||||||
|
|
||||||
|
1. `GET /api/runtime/square-hole/gallery`
|
||||||
|
2. `GET /api/runtime/square-hole/gallery/{profileId}`
|
||||||
|
3. `POST /api/runtime/square-hole/works/{profileId}/runs`
|
||||||
|
4. `GET /api/runtime/square-hole/runs/{runId}`
|
||||||
|
5. `POST /api/runtime/square-hole/runs/{runId}/drop`
|
||||||
|
6. `POST /api/runtime/square-hole/runs/{runId}/stop`
|
||||||
|
7. `POST /api/runtime/square-hole/runs/{runId}/restart`
|
||||||
|
8. `POST /api/runtime/square-hole/runs/{runId}/time-up`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. 验收标准
|
||||||
|
|
||||||
|
1. `src/config/newWorkEntryConfig.ts` 中存在 `square-hole` 类型且开放创建。
|
||||||
|
2. 新建作品入口和创作类型弹层能展示“方洞挑战”。
|
||||||
|
3. 能进入 `square-hole` Agent 工作台。
|
||||||
|
4. 能生成草稿并进入结果页。
|
||||||
|
5. 能编辑结果页并保存、发布。
|
||||||
|
6. 能从作品详情或广场进入运行态。
|
||||||
|
7. 能点击或拖拽当前形状投入洞口。
|
||||||
|
8. 后端裁决命中规则、连击、失败和胜利。
|
||||||
|
9. 刷新后可恢复作品与运行态快照。
|
||||||
|
10. `docs/technical/NEW_WORK_ENTRY_CONFIG_2026-05-01.md` 记录该入口开放状态。
|
||||||
|
11. 后端改动完成后必须执行 `npm run api-server:maincloud`,以 `GET /healthz` 返回 `200` 作为主云配置启动 smoke 通过标准,并在 smoke 后清理本次启动进程。
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
# 创作 Agent 流式失败保留可见回复修复 2026-05-05
|
||||||
|
|
||||||
|
## 1. 问题
|
||||||
|
|
||||||
|
方洞挑战等轻量玩法复用 `usePlatformCreationAgentFlowController` 与 `creationAgentSse.ts` 消费 `reply_delta / session / error`。当上游 LLM 已经返回部分 `replyText`,但后续因为超时、上游断流、SSE 解析或最终 JSON 解析失败而发送 `error` 事件时,前端会在 `finally` 里退出流式态。
|
||||||
|
|
||||||
|
旧 UI 只在 `isStreamingReply=true` 时展示临时 assistant 气泡,因此用户会先看到一段回答,然后回答突然消失,只剩错误提示。
|
||||||
|
|
||||||
|
## 2. 目标
|
||||||
|
|
||||||
|
1. 已经展示给用户的流式回复不能因为最终失败从聊天区消失。
|
||||||
|
2. SSE `error` 仍然终止本轮提交,并保留错误提示。
|
||||||
|
3. 后端错误不能只压成 `上游服务请求失败`,应优先把 LLM 流错误原因放到业务 `message`。
|
||||||
|
4. 不修改 SpacetimeDB schema、消息表结构或玩法运行规则。
|
||||||
|
|
||||||
|
## 3. 前端契约
|
||||||
|
|
||||||
|
`readCreationAgentSessionFromSse()` 在收到 `reply_delta` 后再收到 `error` 时,必须先触发 `onUpdate(text)`,再抛出错误。调用方可以从最近一次可见文本中恢复 UI。
|
||||||
|
|
||||||
|
`usePlatformCreationAgentFlowController.submitMessage()` 的失败收尾规则:
|
||||||
|
|
||||||
|
1. 提交时仍先追加 optimistic user message。
|
||||||
|
2. 每次 `onUpdate` 同步更新 `streamingReplyText` 与最近可见回复引用。
|
||||||
|
3. 如果 `streamMessage()` 抛错且最近可见回复非空,把该文本追加为本地 assistant `warning` 消息。
|
||||||
|
4. 再设置 `error`,最后关闭 `isStreamingReply`。
|
||||||
|
5. 成功拿到最终 session 时,以后端 session snapshot 为准,并清空最近可见回复。
|
||||||
|
|
||||||
|
这条本地 `warning` 消息只用于失败态 UI 保留,不代表该 assistant 消息已经写入 SpacetimeDB。
|
||||||
|
|
||||||
|
## 4. 后端契约
|
||||||
|
|
||||||
|
`creation_agent_llm_turn` 在 `LlmClient::stream_text()` 失败时,返回:
|
||||||
|
|
||||||
|
```text
|
||||||
|
<玩法 generation_failed 文案>:<LlmError Display>
|
||||||
|
```
|
||||||
|
|
||||||
|
同时写 `warn` 日志,便于结合 `logs/llm-raw` 定位上游原始输入输出。
|
||||||
|
|
||||||
|
方洞挑战 SSE 错误提取优先级:
|
||||||
|
|
||||||
|
1. `error.details.message`
|
||||||
|
2. `error.message`
|
||||||
|
3. 其它嵌套 JSON message
|
||||||
|
4. 原始 body 文本
|
||||||
|
5. 状态码兜底
|
||||||
|
|
||||||
|
## 5. 验收
|
||||||
|
|
||||||
|
1. `reply_delta` 后收到 `error` 时,测试应断言 `onUpdate` 已经收到可见文本。
|
||||||
|
2. 控制器测试应断言失败后本地消息列表包含 user 消息和 assistant warning 消息。
|
||||||
|
3. `cargo check -p api-server` 通过。
|
||||||
|
4. `npm run typecheck` 与编码检查通过。
|
||||||
@@ -22,6 +22,7 @@
|
|||||||
| 大鱼吃小鱼 | 否 | 是 | 功能仍保留,不在新建作品入口展示 |
|
| 大鱼吃小鱼 | 否 | 是 | 功能仍保留,不在新建作品入口展示 |
|
||||||
| 拼图 | 是 | 是 | 点击后进入拼图 Agent 共创工作台 |
|
| 拼图 | 是 | 是 | 点击后进入拼图 Agent 共创工作台 |
|
||||||
| 抓大鹅 | 是 | 是 | 点击后进入抓大鹅 Agent 共创工作台 |
|
| 抓大鹅 | 是 | 是 | 点击后进入抓大鹅 Agent 共创工作台 |
|
||||||
|
| 方洞挑战 | 是 | 是 | 点击后进入方洞挑战 Agent 共创工作台,支持草稿、结果页、发布、试玩、作品架与广场 |
|
||||||
| AIRP | 是 | 否 | 保留入口,显示敬请期待 |
|
| AIRP | 是 | 否 | 保留入口,显示敬请期待 |
|
||||||
| 视觉小说 | 是 | 否 | 保留入口,显示敬请期待 |
|
| 视觉小说 | 是 | 否 | 保留入口,显示敬请期待 |
|
||||||
|
|
||||||
@@ -31,3 +32,4 @@
|
|||||||
2. 隐藏玩法不触发入口预加载,也不出现在新建作品入口中。
|
2. 隐藏玩法不触发入口预加载,也不出现在新建作品入口中。
|
||||||
3. 未开放玩法点击态保持禁用,不应进入鉴权或创建会话链路。
|
3. 未开放玩法点击态保持禁用,不应进入鉴权或创建会话链路。
|
||||||
4. 已开放玩法点击后必须进入对应创建链路;若用户未登录,先走登录保护。
|
4. 已开放玩法点击后必须进入对应创建链路;若用户未登录,先走登录保护。
|
||||||
|
5. 方洞挑战作品发布后应生成 `SH-` 作品号,并能从作品架、广场详情和试玩 runtime 回到同一作品详情。
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ spacetime sql <db> "SELECT * FROM custom_world_gallery_entry"
|
|||||||
| 世界创作 | `custom_world_profile`, `custom_world_session`, `custom_world_agent_session`, `custom_world_agent_message`, `custom_world_agent_operation`, `custom_world_draft_card`, `custom_world_gallery_entry` |
|
| 世界创作 | `custom_world_profile`, `custom_world_session`, `custom_world_agent_session`, `custom_world_agent_message`, `custom_world_agent_operation`, `custom_world_draft_card`, `custom_world_gallery_entry` |
|
||||||
| 拼图 | `puzzle_agent_session`, `puzzle_agent_message`, `puzzle_work_profile`, `puzzle_event`, `puzzle_runtime_run`, `puzzle_leaderboard_entry` |
|
| 拼图 | `puzzle_agent_session`, `puzzle_agent_message`, `puzzle_work_profile`, `puzzle_event`, `puzzle_runtime_run`, `puzzle_leaderboard_entry` |
|
||||||
| 抓大鹅 Match3D | `match3d_agent_session`, `match3d_agent_message`, `match3d_work_profile`, `match3d_runtime_run` |
|
| 抓大鹅 Match3D | `match3d_agent_session`, `match3d_agent_message`, `match3d_work_profile`, `match3d_runtime_run` |
|
||||||
|
| 方洞挑战 | `square_hole_agent_session`, `square_hole_agent_message`, `square_hole_work_profile`, `square_hole_runtime_run` |
|
||||||
| 大鱼吃小鱼 | `big_fish_creation_session`, `big_fish_agent_message`, `big_fish_asset_slot`, `big_fish_event`, `big_fish_runtime_run` |
|
| 大鱼吃小鱼 | `big_fish_creation_session`, `big_fish_agent_message`, `big_fish_asset_slot`, `big_fish_event`, `big_fish_runtime_run` |
|
||||||
| 资产 | `asset_object`, `asset_entity_binding`, `asset_event` |
|
| 资产 | `asset_object`, `asset_entity_binding`, `asset_event` |
|
||||||
| AI 任务 | `ai_task`, `ai_task_stage`, `ai_text_chunk`, `ai_result_reference`, `ai_task_event` |
|
| AI 任务 | `ai_task`, `ai_task_stage`, `ai_text_chunk`, `ai_result_reference`, `ai_task_event` |
|
||||||
@@ -669,6 +670,53 @@ SELECT * FROM match3d_runtime_run WHERE owner_user_id = '<user_id>' ORDER BY upd
|
|||||||
SELECT * FROM match3d_runtime_run WHERE profile_id = '<profile_id>';
|
SELECT * FROM match3d_runtime_run WHERE profile_id = '<profile_id>';
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## 方洞挑战表
|
||||||
|
|
||||||
|
### `square_hole_agent_session`
|
||||||
|
|
||||||
|
- 作用:方洞挑战创作 Agent 会话表,保存种子、配置 JSON、草稿 JSON 和发布 profile 指针。
|
||||||
|
- 结构:`session_id PK: String`, `owner_user_id: String`, `seed_text: String`, `current_turn: u32`, `progress_percent: u32`, `stage: String`, `config_json: String`, `draft_json: String`, `last_assistant_reply: String`, `published_profile_id: String`, `created_at: Timestamp`, `updated_at: Timestamp`。
|
||||||
|
- 索引:`owner_user_id`。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SELECT * FROM square_hole_agent_session WHERE session_id = '<session_id>';
|
||||||
|
SELECT * FROM square_hole_agent_session WHERE owner_user_id = '<user_id>' ORDER BY updated_at DESC;
|
||||||
|
```
|
||||||
|
|
||||||
|
### `square_hole_agent_message`
|
||||||
|
|
||||||
|
- 作用:方洞挑战创作 Agent 消息流水。
|
||||||
|
- 结构:`message_id PK: String`, `session_id: String`, `role: String`, `kind: String`, `text: String`, `created_at: Timestamp`。
|
||||||
|
- 索引:`session_id`。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SELECT * FROM square_hole_agent_message WHERE session_id = '<session_id>' ORDER BY created_at ASC;
|
||||||
|
```
|
||||||
|
|
||||||
|
### `square_hole_work_profile`
|
||||||
|
|
||||||
|
- 作用:方洞挑战作品主表,保存作品基础信息、反直觉规则、配置、发布状态和游玩次数。
|
||||||
|
- 结构:`profile_id PK: String`, `work_id: String`, `owner_user_id: String`, `source_session_id: String`, `author_display_name: String`, `game_name: String`, `theme_text: String`, `twist_rule: String`, `summary_text: String`, `tags_json: String`, `cover_image_src: String`, `shape_count: u32`, `difficulty: u32`, `config_json: String`, `publication_status: String`, `play_count: u32`, `updated_at: Timestamp`, `published_at: Option<Timestamp>`。
|
||||||
|
- 索引:`owner_user_id`, `publication_status`。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SELECT * FROM square_hole_work_profile WHERE profile_id = '<profile_id>';
|
||||||
|
SELECT * FROM square_hole_work_profile WHERE owner_user_id = '<user_id>' ORDER BY updated_at DESC;
|
||||||
|
SELECT * FROM square_hole_work_profile WHERE publication_status = 'Published';
|
||||||
|
```
|
||||||
|
|
||||||
|
### `square_hole_runtime_run`
|
||||||
|
|
||||||
|
- 作用:方洞挑战单局运行态表,保存后端权威快照、快照版本、胜负状态和成绩基础字段。
|
||||||
|
- 结构:`run_id PK: String`, `owner_user_id: String`, `profile_id: String`, `status: String`, `snapshot_version: u64`, `started_at_ms: i64`, `duration_limit_ms: i64`, `finished_at_ms: i64`, `elapsed_ms: i64`, `total_shape_count: u32`, `completed_shape_count: u32`, `score: u32`, `snapshot_json: String`, `created_at: Timestamp`, `updated_at: Timestamp`。
|
||||||
|
- 索引:`owner_user_id`, `profile_id`。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SELECT * FROM square_hole_runtime_run WHERE run_id = '<run_id>';
|
||||||
|
SELECT * FROM square_hole_runtime_run WHERE owner_user_id = '<user_id>' ORDER BY updated_at DESC;
|
||||||
|
SELECT * FROM square_hole_runtime_run WHERE profile_id = '<profile_id>';
|
||||||
|
```
|
||||||
|
|
||||||
## 大鱼吃小鱼表
|
## 大鱼吃小鱼表
|
||||||
|
|
||||||
### `big_fish_creation_session`
|
### `big_fish_creation_session`
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
"admin-web:preview": "npm --prefix apps/admin-web run preview --",
|
"admin-web:preview": "npm --prefix apps/admin-web run preview --",
|
||||||
"spacetime:generate": "node scripts/generate-spacetime-bindings.mjs",
|
"spacetime:generate": "node scripts/generate-spacetime-bindings.mjs",
|
||||||
"api-server": "node scripts/api-server-dev.mjs",
|
"api-server": "node scripts/api-server-dev.mjs",
|
||||||
|
"api-server:maincloud": "node scripts/api-server-maincloud.mjs",
|
||||||
"deploy:rust:remote": "node scripts/run-bash-script.mjs scripts/deploy-rust-remote.sh",
|
"deploy:rust:remote": "node scripts/run-bash-script.mjs scripts/deploy-rust-remote.sh",
|
||||||
"build:production-release": "node scripts/run-bash-script.mjs scripts/build-production-release.sh",
|
"build:production-release": "node scripts/run-bash-script.mjs scripts/build-production-release.sh",
|
||||||
"build:rust:ubuntu": "node scripts/run-bash-script.mjs scripts/deploy-rust-remote.sh",
|
"build:rust:ubuntu": "node scripts/run-bash-script.mjs scripts/deploy-rust-remote.sh",
|
||||||
|
|||||||
100
packages/shared/src/contracts/squareHoleAgent.ts
Normal file
100
packages/shared/src/contracts/squareHoleAgent.ts
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
/**
|
||||||
|
* 方洞挑战创作 Agent 共享契约。
|
||||||
|
* 字段按 HTTP facade 的 camelCase DTO 命名,后端领域层 snake_case 字段由 facade 映射。
|
||||||
|
*/
|
||||||
|
export type SquareHoleCreationStage =
|
||||||
|
| 'collecting_config'
|
||||||
|
| 'draft_ready'
|
||||||
|
| string;
|
||||||
|
|
||||||
|
export type SquareHoleAnchorStatus =
|
||||||
|
| 'confirmed'
|
||||||
|
| 'missing'
|
||||||
|
| 'inferred'
|
||||||
|
| string;
|
||||||
|
|
||||||
|
export interface CreateSquareHoleSessionRequest {
|
||||||
|
seedText?: string;
|
||||||
|
themeText?: string;
|
||||||
|
twistRule?: string;
|
||||||
|
shapeCount?: number;
|
||||||
|
difficulty?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SendSquareHoleMessageRequest {
|
||||||
|
clientMessageId: string;
|
||||||
|
text: string;
|
||||||
|
quickFillRequested?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ExecuteSquareHoleActionRequest {
|
||||||
|
action: string;
|
||||||
|
gameName?: string;
|
||||||
|
summary?: string;
|
||||||
|
tags?: string[];
|
||||||
|
coverImageSrc?: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SquareHoleAnchorItemResponse {
|
||||||
|
key: string;
|
||||||
|
label: string;
|
||||||
|
value: string;
|
||||||
|
status: SquareHoleAnchorStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SquareHoleAnchorPackResponse {
|
||||||
|
theme: SquareHoleAnchorItemResponse;
|
||||||
|
twistRule: SquareHoleAnchorItemResponse;
|
||||||
|
shapeCount: SquareHoleAnchorItemResponse;
|
||||||
|
difficulty: SquareHoleAnchorItemResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SquareHoleCreatorConfig {
|
||||||
|
themeText: string;
|
||||||
|
twistRule: string;
|
||||||
|
shapeCount: number;
|
||||||
|
difficulty: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SquareHoleResultDraft {
|
||||||
|
profileId: string;
|
||||||
|
gameName: string;
|
||||||
|
themeText: string;
|
||||||
|
twistRule: string;
|
||||||
|
summary: string;
|
||||||
|
tags: string[];
|
||||||
|
shapeCount: number;
|
||||||
|
difficulty: number;
|
||||||
|
publishReady: boolean;
|
||||||
|
blockers: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SquareHoleAgentMessage {
|
||||||
|
id: string;
|
||||||
|
role: 'user' | 'assistant' | 'system' | string;
|
||||||
|
kind: 'chat' | 'summary' | 'action_result' | 'warning' | string;
|
||||||
|
text: string;
|
||||||
|
createdAt: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SquareHoleSessionSnapshot {
|
||||||
|
sessionId: string;
|
||||||
|
currentTurn: number;
|
||||||
|
progressPercent: number;
|
||||||
|
stage: SquareHoleCreationStage;
|
||||||
|
anchorPack: SquareHoleAnchorPackResponse;
|
||||||
|
config: SquareHoleCreatorConfig;
|
||||||
|
draft?: SquareHoleResultDraft | null;
|
||||||
|
messages: SquareHoleAgentMessage[];
|
||||||
|
lastAssistantReply?: string | null;
|
||||||
|
publishedProfileId?: string | null;
|
||||||
|
updatedAt: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SquareHoleSessionResponse {
|
||||||
|
session: SquareHoleSessionSnapshot;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SquareHoleActionResponse {
|
||||||
|
session: SquareHoleSessionSnapshot;
|
||||||
|
}
|
||||||
99
packages/shared/src/contracts/squareHoleRuntime.ts
Normal file
99
packages/shared/src/contracts/squareHoleRuntime.ts
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
/**
|
||||||
|
* 方洞挑战运行态共享契约。
|
||||||
|
* 后端负责当前形状、洞口兼容、胜负和连击真相;前端只提交洞口选择并渲染快照。
|
||||||
|
*/
|
||||||
|
export type SquareHoleRunStatus =
|
||||||
|
| 'running'
|
||||||
|
| 'won'
|
||||||
|
| 'failed'
|
||||||
|
| 'stopped'
|
||||||
|
| string;
|
||||||
|
export type SquareHoleShapeKind =
|
||||||
|
| 'square'
|
||||||
|
| 'circle'
|
||||||
|
| 'triangle'
|
||||||
|
| 'star'
|
||||||
|
| 'arch'
|
||||||
|
| 'diamond'
|
||||||
|
| string;
|
||||||
|
export type SquareHoleHoleKind =
|
||||||
|
| 'square'
|
||||||
|
| 'circle'
|
||||||
|
| 'triangle'
|
||||||
|
| 'star'
|
||||||
|
| 'arch'
|
||||||
|
| 'diamond'
|
||||||
|
| string;
|
||||||
|
export type SquareHoleDropRejectReason =
|
||||||
|
| 'run_not_active'
|
||||||
|
| 'snapshot_version_mismatch'
|
||||||
|
| 'hole_not_found'
|
||||||
|
| 'incompatible'
|
||||||
|
| 'time_up'
|
||||||
|
| string;
|
||||||
|
|
||||||
|
export interface SquareHoleShapeSnapshot {
|
||||||
|
shapeId: string;
|
||||||
|
shapeKind: SquareHoleShapeKind;
|
||||||
|
label: string;
|
||||||
|
color: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SquareHoleHoleSnapshot {
|
||||||
|
holeId: string;
|
||||||
|
holeKind: SquareHoleHoleKind;
|
||||||
|
label: string;
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SquareHoleRunSnapshot {
|
||||||
|
runId: string;
|
||||||
|
profileId: string;
|
||||||
|
ownerUserId: string;
|
||||||
|
status: SquareHoleRunStatus;
|
||||||
|
snapshotVersion: number;
|
||||||
|
startedAtMs: number;
|
||||||
|
durationLimitMs: number;
|
||||||
|
remainingMs: number;
|
||||||
|
totalShapeCount: number;
|
||||||
|
completedShapeCount: number;
|
||||||
|
combo: number;
|
||||||
|
bestCombo: number;
|
||||||
|
score: number;
|
||||||
|
ruleLabel: string;
|
||||||
|
currentShape?: SquareHoleShapeSnapshot | null;
|
||||||
|
holes: SquareHoleHoleSnapshot[];
|
||||||
|
lastFeedback?: SquareHoleDropFeedback | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StartSquareHoleRunRequest {
|
||||||
|
profileId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DropSquareHoleShapeRequest {
|
||||||
|
runId?: string;
|
||||||
|
holeId: string;
|
||||||
|
clientSnapshotVersion: number;
|
||||||
|
clientEventId: string;
|
||||||
|
droppedAtMs: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StopSquareHoleRunRequest {
|
||||||
|
clientActionId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SquareHoleDropFeedback {
|
||||||
|
accepted: boolean;
|
||||||
|
rejectReason?: SquareHoleDropRejectReason | null;
|
||||||
|
message: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SquareHoleDropResponse {
|
||||||
|
feedback: SquareHoleDropFeedback;
|
||||||
|
run: SquareHoleRunSnapshot;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SquareHoleRunResponse {
|
||||||
|
run: SquareHoleRunSnapshot;
|
||||||
|
}
|
||||||
50
packages/shared/src/contracts/squareHoleWorks.ts
Normal file
50
packages/shared/src/contracts/squareHoleWorks.ts
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/**
|
||||||
|
* 方洞挑战作品读写共享契约。
|
||||||
|
* 作品字段只表达结果页可编辑信息;运行规则真相由后端 runtime 快照负责。
|
||||||
|
*/
|
||||||
|
export type SquareHoleWorkPublicationStatus = 'draft' | 'published' | string;
|
||||||
|
|
||||||
|
export interface PutSquareHoleWorkRequest {
|
||||||
|
gameName: string;
|
||||||
|
themeText?: string;
|
||||||
|
twistRule: string;
|
||||||
|
summary: string;
|
||||||
|
tags: string[];
|
||||||
|
coverImageSrc?: string | null;
|
||||||
|
shapeCount: number;
|
||||||
|
difficulty: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SquareHoleWorkSummary {
|
||||||
|
workId: string;
|
||||||
|
profileId: string;
|
||||||
|
ownerUserId: string;
|
||||||
|
sourceSessionId?: string | null;
|
||||||
|
gameName: string;
|
||||||
|
themeText: string;
|
||||||
|
twistRule: string;
|
||||||
|
summary: string;
|
||||||
|
tags: string[];
|
||||||
|
coverImageSrc?: string | null;
|
||||||
|
shapeCount: number;
|
||||||
|
difficulty: number;
|
||||||
|
publicationStatus: SquareHoleWorkPublicationStatus;
|
||||||
|
playCount: number;
|
||||||
|
updatedAt: string;
|
||||||
|
publishedAt?: string | null;
|
||||||
|
publishReady: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SquareHoleWorkProfile extends SquareHoleWorkSummary {}
|
||||||
|
|
||||||
|
export interface SquareHoleWorksResponse {
|
||||||
|
items: SquareHoleWorkSummary[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SquareHoleWorkDetailResponse {
|
||||||
|
item: SquareHoleWorkProfile;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SquareHoleWorkMutationResponse {
|
||||||
|
item: SquareHoleWorkProfile;
|
||||||
|
}
|
||||||
@@ -13,6 +13,9 @@ export * from './contracts/puzzleAgentSession';
|
|||||||
export * from './contracts/puzzleResultPreview';
|
export * from './contracts/puzzleResultPreview';
|
||||||
export * from './contracts/puzzleRuntimeSession';
|
export * from './contracts/puzzleRuntimeSession';
|
||||||
export * from './contracts/puzzleWorkSummary';
|
export * from './contracts/puzzleWorkSummary';
|
||||||
|
export * from './contracts/squareHoleAgent';
|
||||||
|
export * from './contracts/squareHoleRuntime';
|
||||||
|
export * from './contracts/squareHoleWorks';
|
||||||
export * from './contracts/rpgAgentActions';
|
export * from './contracts/rpgAgentActions';
|
||||||
export * from './contracts/rpgAgentAnchors';
|
export * from './contracts/rpgAgentAnchors';
|
||||||
export * from './contracts/rpgAgentDraft';
|
export * from './contracts/rpgAgentDraft';
|
||||||
|
|||||||
220
scripts/api-server-maincloud.mjs
Normal file
220
scripts/api-server-maincloud.mjs
Normal file
@@ -0,0 +1,220 @@
|
|||||||
|
import { execFileSync, spawn } from 'node:child_process';
|
||||||
|
import { existsSync, readFileSync } from 'node:fs';
|
||||||
|
import { resolve } from 'node:path';
|
||||||
|
import { setTimeout as delay } from 'node:timers/promises';
|
||||||
|
|
||||||
|
const repoRoot = process.cwd();
|
||||||
|
const apiServerExePath = resolve(
|
||||||
|
repoRoot,
|
||||||
|
'server-rs/target/debug/api-server.exe',
|
||||||
|
);
|
||||||
|
const defaultHealthHost = '127.0.0.1';
|
||||||
|
const defaultHealthPort = '3100';
|
||||||
|
const healthTimeoutMs =
|
||||||
|
Number(process.env.GENARRATIVE_API_SERVER_MAINCLOUD_SMOKE_TIMEOUT_SECONDS) *
|
||||||
|
1000 || 180_000;
|
||||||
|
|
||||||
|
function loadEnvFile(path, target) {
|
||||||
|
if (!existsSync(path)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const rawText = readFileSync(path, 'utf8');
|
||||||
|
for (const rawLine of rawText.split(/\r?\n/u)) {
|
||||||
|
const line = rawLine.trim();
|
||||||
|
if (!line || line.startsWith('#')) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const match = line.match(/^([A-Za-z_][A-Za-z0-9_]*)=(.*)$/u);
|
||||||
|
if (!match) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const [, key, rawValue] = match;
|
||||||
|
if (target[key] !== undefined) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
target[key] = rawValue.replace(/^['"]|['"]$/gu, '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function stopExistingWindowsApiServer() {
|
||||||
|
if (process.platform !== 'win32') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Windows 下 cargo 重编译不能覆盖正在运行的 exe,只清理本仓库 target 内的 api-server。
|
||||||
|
const command = [
|
||||||
|
'$ErrorActionPreference = "Continue"',
|
||||||
|
'$target = [System.IO.Path]::GetFullPath($env:GENARRATIVE_API_SERVER_EXE_TARGET)',
|
||||||
|
'$processes = Get-Process -Name api-server -ErrorAction SilentlyContinue | Where-Object {',
|
||||||
|
' $_.Path -and ([System.IO.Path]::GetFullPath($_.Path) -ieq $target)',
|
||||||
|
'}',
|
||||||
|
'foreach ($process in $processes) {',
|
||||||
|
' try {',
|
||||||
|
' Stop-Process -Id $process.Id -Force -ErrorAction Stop',
|
||||||
|
' Wait-Process -Id $process.Id -Timeout 5 -ErrorAction SilentlyContinue',
|
||||||
|
' Write-Output $process.Id',
|
||||||
|
' } catch {',
|
||||||
|
' Write-Error "[api-server:maincloud] 忽略旧进程清理瞬时失败 pid=$($process.Id): $($_.Exception.Message)"',
|
||||||
|
' }',
|
||||||
|
'}',
|
||||||
|
'exit 0',
|
||||||
|
].join('\n');
|
||||||
|
|
||||||
|
const output = execFileSync(
|
||||||
|
'powershell.exe',
|
||||||
|
['-NoProfile', '-ExecutionPolicy', 'Bypass', '-Command', command],
|
||||||
|
{
|
||||||
|
encoding: 'utf8',
|
||||||
|
env: {
|
||||||
|
...process.env,
|
||||||
|
GENARRATIVE_API_SERVER_EXE_TARGET: apiServerExePath,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
).trim();
|
||||||
|
|
||||||
|
if (output) {
|
||||||
|
console.log(`[api-server:maincloud] 已停止旧 api-server 进程: ${output}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function stopProcessTree(child) {
|
||||||
|
if (!child || child.exitCode !== null || child.signalCode) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (process.platform === 'win32') {
|
||||||
|
try {
|
||||||
|
execFileSync('taskkill.exe', ['/PID', String(child.pid), '/T', '/F'], {
|
||||||
|
stdio: 'ignore',
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
} catch {
|
||||||
|
// taskkill 可能已经被进程自然退出抢先;继续走兜底清理。
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
child.kill('SIGTERM');
|
||||||
|
}
|
||||||
|
|
||||||
|
async function waitForHealthz({ child, healthUrl }) {
|
||||||
|
const deadline = Date.now() + healthTimeoutMs;
|
||||||
|
let childExit = null;
|
||||||
|
child.once('exit', (code, signal) => {
|
||||||
|
childExit = { code, signal };
|
||||||
|
});
|
||||||
|
|
||||||
|
while (Date.now() < deadline) {
|
||||||
|
if (childExit) {
|
||||||
|
throw new Error(
|
||||||
|
`api-server 在 healthz 就绪前退出:code=${childExit.code ?? ''} signal=${
|
||||||
|
childExit.signal ?? ''
|
||||||
|
}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(healthUrl, {
|
||||||
|
signal: AbortSignal.timeout(1_000),
|
||||||
|
});
|
||||||
|
const body = await response.text();
|
||||||
|
if (response.status === 200) {
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// 服务启动期间连接失败是预期状态,继续轮询。
|
||||||
|
}
|
||||||
|
|
||||||
|
await delay(500);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error(`等待 /healthz 超时:${healthUrl}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const mergedEnv = { ...process.env };
|
||||||
|
loadEnvFile(resolve(repoRoot, '.env'), mergedEnv);
|
||||||
|
loadEnvFile(resolve(repoRoot, '.env.local'), mergedEnv);
|
||||||
|
loadEnvFile(resolve(repoRoot, '.env.secrets.local'), mergedEnv);
|
||||||
|
|
||||||
|
mergedEnv.GENARRATIVE_API_HOST =
|
||||||
|
mergedEnv.GENARRATIVE_API_HOST || defaultHealthHost;
|
||||||
|
mergedEnv.GENARRATIVE_API_PORT =
|
||||||
|
mergedEnv.GENARRATIVE_API_PORT || defaultHealthPort;
|
||||||
|
mergedEnv.GENARRATIVE_SPACETIME_SERVER_URL =
|
||||||
|
mergedEnv.GENARRATIVE_SPACETIME_MAINCLOUD_SERVER_URL ||
|
||||||
|
mergedEnv.GENARRATIVE_SPACETIME_SERVER_URL ||
|
||||||
|
'https://maincloud.spacetimedb.com';
|
||||||
|
mergedEnv.GENARRATIVE_SPACETIME_DATABASE =
|
||||||
|
mergedEnv.GENARRATIVE_SPACETIME_MAINCLOUD_DATABASE ||
|
||||||
|
mergedEnv.GENARRATIVE_SPACETIME_DATABASE ||
|
||||||
|
'';
|
||||||
|
mergedEnv.GENARRATIVE_SPACETIME_TOKEN =
|
||||||
|
mergedEnv.GENARRATIVE_SPACETIME_MAINCLOUD_TOKEN ||
|
||||||
|
mergedEnv.GENARRATIVE_SPACETIME_TOKEN ||
|
||||||
|
'';
|
||||||
|
|
||||||
|
if (!mergedEnv.GENARRATIVE_SPACETIME_DATABASE) {
|
||||||
|
console.error(
|
||||||
|
'[api-server:maincloud] 缺少 GENARRATIVE_SPACETIME_MAINCLOUD_DATABASE 或 GENARRATIVE_SPACETIME_DATABASE。',
|
||||||
|
);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
stopExistingWindowsApiServer();
|
||||||
|
} catch (error) {
|
||||||
|
console.error(
|
||||||
|
`[api-server:maincloud] 清理旧 api-server 进程失败: ${error.message}`,
|
||||||
|
);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`[api-server:maincloud] SpacetimeDB ${mergedEnv.GENARRATIVE_SPACETIME_DATABASE} @ ${mergedEnv.GENARRATIVE_SPACETIME_SERVER_URL}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
const child = spawn(
|
||||||
|
'cargo',
|
||||||
|
['run', '-p', 'api-server', '--manifest-path', 'server-rs/Cargo.toml'],
|
||||||
|
{
|
||||||
|
cwd: repoRoot,
|
||||||
|
env: mergedEnv,
|
||||||
|
stdio: 'inherit',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const cleanup = () => {
|
||||||
|
stopProcessTree(child);
|
||||||
|
try {
|
||||||
|
stopExistingWindowsApiServer();
|
||||||
|
} catch {
|
||||||
|
// 退出阶段只做 best-effort 清理,不能覆盖真实 smoke 结果。
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
process.once('SIGINT', () => {
|
||||||
|
cleanup();
|
||||||
|
process.exit(130);
|
||||||
|
});
|
||||||
|
process.once('SIGTERM', () => {
|
||||||
|
cleanup();
|
||||||
|
process.exit(143);
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
const healthHost =
|
||||||
|
mergedEnv.GENARRATIVE_API_HOST === '0.0.0.0'
|
||||||
|
? defaultHealthHost
|
||||||
|
: mergedEnv.GENARRATIVE_API_HOST;
|
||||||
|
const healthUrl = `http://${healthHost}:${mergedEnv.GENARRATIVE_API_PORT}/healthz`;
|
||||||
|
const body = await waitForHealthz({ child, healthUrl });
|
||||||
|
console.log(`[api-server:maincloud] /healthz 通过:${body}`);
|
||||||
|
cleanup();
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`[api-server:maincloud] smoke 失败:${error.message}`);
|
||||||
|
cleanup();
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
12
server-rs/Cargo.lock
generated
12
server-rs/Cargo.lock
generated
@@ -90,6 +90,7 @@ dependencies = [
|
|||||||
"module-runtime",
|
"module-runtime",
|
||||||
"module-runtime-item",
|
"module-runtime-item",
|
||||||
"module-runtime-story",
|
"module-runtime-story",
|
||||||
|
"module-square-hole",
|
||||||
"module-story",
|
"module-story",
|
||||||
"platform-auth",
|
"platform-auth",
|
||||||
"platform-llm",
|
"platform-llm",
|
||||||
@@ -1639,6 +1640,15 @@ dependencies = [
|
|||||||
"time",
|
"time",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "module-square-hole"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"shared-kernel",
|
||||||
|
"spacetimedb",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "module-story"
|
name = "module-story"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@@ -2681,6 +2691,7 @@ dependencies = [
|
|||||||
"module-runtime",
|
"module-runtime",
|
||||||
"module-runtime-item",
|
"module-runtime-item",
|
||||||
"module-runtime-story",
|
"module-runtime-story",
|
||||||
|
"module-square-hole",
|
||||||
"module-story",
|
"module-story",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
@@ -2708,6 +2719,7 @@ dependencies = [
|
|||||||
"module-quest",
|
"module-quest",
|
||||||
"module-runtime",
|
"module-runtime",
|
||||||
"module-runtime-item",
|
"module-runtime-item",
|
||||||
|
"module-square-hole",
|
||||||
"module-story",
|
"module-story",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ members = [
|
|||||||
"crates/module-runtime",
|
"crates/module-runtime",
|
||||||
"crates/module-runtime-story",
|
"crates/module-runtime-story",
|
||||||
"crates/module-runtime-item",
|
"crates/module-runtime-item",
|
||||||
|
"crates/module-square-hole",
|
||||||
"crates/module-story",
|
"crates/module-story",
|
||||||
"crates/platform-oss",
|
"crates/platform-oss",
|
||||||
"crates/platform-auth",
|
"crates/platform-auth",
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ module-puzzle = { path = "../module-puzzle" }
|
|||||||
module-runtime = { path = "../module-runtime" }
|
module-runtime = { path = "../module-runtime" }
|
||||||
module-runtime-story = { path = "../module-runtime-story" }
|
module-runtime-story = { path = "../module-runtime-story" }
|
||||||
module-runtime-item = { path = "../module-runtime-item" }
|
module-runtime-item = { path = "../module-runtime-item" }
|
||||||
|
module-square-hole = { path = "../module-square-hole" }
|
||||||
module-story = { path = "../module-story" }
|
module-story = { path = "../module-story" }
|
||||||
platform-auth = { path = "../platform-auth" }
|
platform-auth = { path = "../platform-auth" }
|
||||||
platform-llm = { path = "../platform-llm" }
|
platform-llm = { path = "../platform-llm" }
|
||||||
|
|||||||
@@ -119,6 +119,14 @@ use crate::{
|
|||||||
put_runtime_snapshot, resume_profile_save_archive,
|
put_runtime_snapshot, resume_profile_save_archive,
|
||||||
},
|
},
|
||||||
runtime_settings::{get_runtime_settings, put_runtime_settings},
|
runtime_settings::{get_runtime_settings, put_runtime_settings},
|
||||||
|
square_hole::{
|
||||||
|
compile_square_hole_agent_draft, create_square_hole_agent_session, delete_square_hole_work,
|
||||||
|
drop_square_hole_shape, execute_square_hole_agent_action, finish_square_hole_time_up,
|
||||||
|
get_square_hole_agent_session, get_square_hole_run, get_square_hole_work_detail,
|
||||||
|
get_square_hole_works, list_square_hole_gallery, publish_square_hole_work,
|
||||||
|
put_square_hole_work, restart_square_hole_run, start_square_hole_run, stop_square_hole_run,
|
||||||
|
stream_square_hole_agent_message, submit_square_hole_agent_message,
|
||||||
|
},
|
||||||
state::AppState,
|
state::AppState,
|
||||||
story_battles::{
|
story_battles::{
|
||||||
create_story_battle, create_story_npc_battle, get_story_battle_state, resolve_story_battle,
|
create_story_battle, create_story_npc_battle, get_story_battle_state, resolve_story_battle,
|
||||||
@@ -829,6 +837,119 @@ pub fn build_router(state: AppState) -> Router {
|
|||||||
require_bearer_auth,
|
require_bearer_auth,
|
||||||
)),
|
)),
|
||||||
)
|
)
|
||||||
|
.route(
|
||||||
|
"/api/creation/square-hole/sessions",
|
||||||
|
post(create_square_hole_agent_session).route_layer(middleware::from_fn_with_state(
|
||||||
|
state.clone(),
|
||||||
|
require_bearer_auth,
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
.route(
|
||||||
|
"/api/creation/square-hole/sessions/{session_id}",
|
||||||
|
get(get_square_hole_agent_session).route_layer(middleware::from_fn_with_state(
|
||||||
|
state.clone(),
|
||||||
|
require_bearer_auth,
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
.route(
|
||||||
|
"/api/creation/square-hole/sessions/{session_id}/messages",
|
||||||
|
post(submit_square_hole_agent_message).route_layer(middleware::from_fn_with_state(
|
||||||
|
state.clone(),
|
||||||
|
require_bearer_auth,
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
.route(
|
||||||
|
"/api/creation/square-hole/sessions/{session_id}/messages/stream",
|
||||||
|
post(stream_square_hole_agent_message).route_layer(middleware::from_fn_with_state(
|
||||||
|
state.clone(),
|
||||||
|
require_bearer_auth,
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
.route(
|
||||||
|
"/api/creation/square-hole/sessions/{session_id}/actions",
|
||||||
|
post(execute_square_hole_agent_action).route_layer(middleware::from_fn_with_state(
|
||||||
|
state.clone(),
|
||||||
|
require_bearer_auth,
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
.route(
|
||||||
|
"/api/creation/square-hole/sessions/{session_id}/compile",
|
||||||
|
post(compile_square_hole_agent_draft).route_layer(middleware::from_fn_with_state(
|
||||||
|
state.clone(),
|
||||||
|
require_bearer_auth,
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
.route(
|
||||||
|
"/api/creation/square-hole/works",
|
||||||
|
get(get_square_hole_works).route_layer(middleware::from_fn_with_state(
|
||||||
|
state.clone(),
|
||||||
|
require_bearer_auth,
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
.route(
|
||||||
|
"/api/creation/square-hole/works/{profile_id}",
|
||||||
|
get(get_square_hole_work_detail)
|
||||||
|
.patch(put_square_hole_work)
|
||||||
|
.put(put_square_hole_work)
|
||||||
|
.delete(delete_square_hole_work)
|
||||||
|
.route_layer(middleware::from_fn_with_state(
|
||||||
|
state.clone(),
|
||||||
|
require_bearer_auth,
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
.route(
|
||||||
|
"/api/creation/square-hole/works/{profile_id}/publish",
|
||||||
|
post(publish_square_hole_work).route_layer(middleware::from_fn_with_state(
|
||||||
|
state.clone(),
|
||||||
|
require_bearer_auth,
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
.route(
|
||||||
|
"/api/runtime/square-hole/gallery",
|
||||||
|
get(list_square_hole_gallery),
|
||||||
|
)
|
||||||
|
.route(
|
||||||
|
"/api/runtime/square-hole/works/{profile_id}/runs",
|
||||||
|
post(start_square_hole_run).route_layer(middleware::from_fn_with_state(
|
||||||
|
state.clone(),
|
||||||
|
require_bearer_auth,
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
.route(
|
||||||
|
"/api/runtime/square-hole/runs/{run_id}",
|
||||||
|
get(get_square_hole_run).route_layer(middleware::from_fn_with_state(
|
||||||
|
state.clone(),
|
||||||
|
require_bearer_auth,
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
.route(
|
||||||
|
"/api/runtime/square-hole/runs/{run_id}/drop",
|
||||||
|
post(drop_square_hole_shape).route_layer(middleware::from_fn_with_state(
|
||||||
|
state.clone(),
|
||||||
|
require_bearer_auth,
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
.route(
|
||||||
|
"/api/runtime/square-hole/runs/{run_id}/stop",
|
||||||
|
post(stop_square_hole_run).route_layer(middleware::from_fn_with_state(
|
||||||
|
state.clone(),
|
||||||
|
require_bearer_auth,
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
.route(
|
||||||
|
"/api/runtime/square-hole/runs/{run_id}/restart",
|
||||||
|
post(restart_square_hole_run).route_layer(middleware::from_fn_with_state(
|
||||||
|
state.clone(),
|
||||||
|
require_bearer_auth,
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
.route(
|
||||||
|
"/api/runtime/square-hole/runs/{run_id}/time-up",
|
||||||
|
post(finish_square_hole_time_up).route_layer(middleware::from_fn_with_state(
|
||||||
|
state.clone(),
|
||||||
|
require_bearer_auth,
|
||||||
|
)),
|
||||||
|
)
|
||||||
.route(
|
.route(
|
||||||
"/api/runtime/puzzle/agent/sessions",
|
"/api/runtime/puzzle/agent/sessions",
|
||||||
post(create_puzzle_agent_session)
|
post(create_puzzle_agent_session)
|
||||||
|
|||||||
@@ -64,8 +64,12 @@ where
|
|||||||
};
|
};
|
||||||
|
|
||||||
turn_output.map_err(|error| match error {
|
turn_output.map_err(|error| match error {
|
||||||
CreationAgentJsonTurnFailure::Stream(_) => {
|
CreationAgentJsonTurnFailure::Stream(error) => {
|
||||||
build_error(messages.generation_failed.to_string())
|
tracing::warn!(
|
||||||
|
error = %error,
|
||||||
|
"创作 Agent 流式 LLM 请求失败"
|
||||||
|
);
|
||||||
|
build_error(format!("{}:{error}", messages.generation_failed))
|
||||||
}
|
}
|
||||||
CreationAgentJsonTurnFailure::Parse => build_error(messages.parse_failed.to_string()),
|
CreationAgentJsonTurnFailure::Parse => build_error(messages.parse_failed.to_string()),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -61,6 +61,8 @@ mod runtime_profile;
|
|||||||
mod runtime_save;
|
mod runtime_save;
|
||||||
mod runtime_settings;
|
mod runtime_settings;
|
||||||
mod session_client;
|
mod session_client;
|
||||||
|
mod square_hole;
|
||||||
|
mod square_hole_agent_turn;
|
||||||
mod state;
|
mod state;
|
||||||
mod story_battles;
|
mod story_battles;
|
||||||
mod story_sessions;
|
mod story_sessions;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ pub(crate) mod character_visual;
|
|||||||
pub(crate) mod puzzle;
|
pub(crate) mod puzzle;
|
||||||
pub(crate) mod rpg;
|
pub(crate) mod rpg;
|
||||||
pub(crate) mod scene_background;
|
pub(crate) mod scene_background;
|
||||||
|
pub(crate) mod square_hole;
|
||||||
|
|
||||||
pub(crate) use rpg::agent_chat;
|
pub(crate) use rpg::agent_chat;
|
||||||
pub(crate) use rpg::foundation_draft;
|
pub(crate) use rpg::foundation_draft;
|
||||||
|
|||||||
164
server-rs/crates/api-server/src/prompt/square_hole.rs
Normal file
164
server-rs/crates/api-server/src/prompt/square_hole.rs
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
use serde_json::{Value as JsonValue, json};
|
||||||
|
use spacetime_client::{SquareHoleAgentMessageRecord, SquareHoleAgentSessionRecord};
|
||||||
|
|
||||||
|
use crate::creation_agent_chat::render_quick_fill_extra_rules;
|
||||||
|
|
||||||
|
/// 方洞挑战共创 Agent 的系统提示词。
|
||||||
|
///
|
||||||
|
/// 这里只定义模型职责与输出约束,具体的模型调用、解析和写库由方洞 Agent turn 负责。
|
||||||
|
pub(crate) const SQUARE_HOLE_AGENT_SYSTEM_PROMPT: &str = r#"你是一个负责和百梦主共创“方洞挑战”竖屏玩法的中文创意策划。
|
||||||
|
|
||||||
|
你要把用户灵感收束成一个反直觉形状分拣小游戏:玩家会本能把形状投入对应洞口,但真实规则可能让所有形状都优先进入方洞,形成类似参考视频“所有东西都进方洞”的喜剧反差。
|
||||||
|
|
||||||
|
你必须同时输出:
|
||||||
|
1. 一段直接发给用户的中文回复 replyText
|
||||||
|
2. 当前进度 progressPercent
|
||||||
|
3. 下一轮完整可用的 nextConfig
|
||||||
|
|
||||||
|
硬约束:
|
||||||
|
1. 只能输出 JSON,不能输出代码块或解释
|
||||||
|
2. nextConfig 必须是完整对象,不能只输出 patch
|
||||||
|
3. replyText 必须是自然中文,不能提“字段”“结构”“JSON”“后端”等内部词
|
||||||
|
4. replyText 一次最多推进一个最关键问题
|
||||||
|
5. 如果用户要求自动配置,就直接补齐可发布草稿需要的题材、反差规则、形状数量和难度,不要继续提问
|
||||||
|
6. 默认核心反差优先使用“方洞万能”或“方洞优先”,但可以根据用户题材包装成更有记忆点的规则
|
||||||
|
7. progressPercent 范围只能是 0 到 100
|
||||||
|
8. shapeCount 只能是 6 到 24 的整数,difficulty 只能是 1 到 10 的整数
|
||||||
|
"#;
|
||||||
|
|
||||||
|
const SQUARE_HOLE_AGENT_OUTPUT_CONTRACT: &str = r#"请严格按以下 JSON 输出,不要输出其他文字:
|
||||||
|
{
|
||||||
|
"replyText": "",
|
||||||
|
"progressPercent": 0,
|
||||||
|
"nextConfig": {
|
||||||
|
"themeText": "",
|
||||||
|
"twistRule": "",
|
||||||
|
"shapeCount": 12,
|
||||||
|
"difficulty": 4
|
||||||
|
}
|
||||||
|
}"#;
|
||||||
|
|
||||||
|
pub(crate) const SQUARE_HOLE_AGENT_JSON_TURN_USER_PROMPT: &str = "请按约定输出这一轮的 JSON。";
|
||||||
|
|
||||||
|
/// 方洞挑战草稿生成对话提示词脚本。
|
||||||
|
///
|
||||||
|
/// 方洞首版只需要四个可写回 SpacetimeDB 的配置项,因此提示词直接围绕配置收束,
|
||||||
|
/// 不在模型输出层引入额外锚点,避免和当前持久化 schema 产生漂移。
|
||||||
|
pub(crate) fn build_square_hole_agent_prompt(
|
||||||
|
session: &SquareHoleAgentSessionRecord,
|
||||||
|
quick_fill_requested: bool,
|
||||||
|
) -> String {
|
||||||
|
let quick_fill_rules = if quick_fill_requested {
|
||||||
|
format!(
|
||||||
|
"\n\n{}",
|
||||||
|
render_quick_fill_extra_rules(
|
||||||
|
"当前方洞挑战方向里的题材、反差规则、形状数量和难度",
|
||||||
|
"不要要求用户再提供洞口、形状、演出或难度信息",
|
||||||
|
"输出完整 nextConfig,直接补齐空缺或仍过于泛化的项",
|
||||||
|
"生成结果页",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
String::new()
|
||||||
|
};
|
||||||
|
format!(
|
||||||
|
"模板目标:收束成可试玩、可发布的方洞挑战玩法草稿。{quick_fill_rules}\n\n当前是第 {turn} 轮,当前进度 {progress}% 。\n\n是否要求自动配置:{quick_fill_requested_text}\n\n当前配置:\n{current_config}\n\n最近聊天记录:\n{chat_history}\n\n收束要求:\n1. themeText 描述本局的玩具、道具或场景题材,保持短句。\n2. twistRule 描述真实判定规则,优先体现方洞优先或类似反直觉逻辑。\n3. shapeCount 决定单局形状数量,移动端短局建议 8 到 16。\n4. difficulty 决定误导强度和节奏,建议 3 到 7。\n5. 用户给出明确方向时优先吸收并推进,不要机械问完四个问题。\n\n{contract}",
|
||||||
|
quick_fill_rules = quick_fill_rules,
|
||||||
|
turn = session.current_turn.saturating_add(1),
|
||||||
|
progress = session.progress_percent,
|
||||||
|
quick_fill_requested_text = if quick_fill_requested { "是" } else { "否" },
|
||||||
|
current_config = serialize_square_hole_session_config(session),
|
||||||
|
chat_history =
|
||||||
|
serde_json::to_string_pretty(&build_chat_history(session.messages.as_slice()))
|
||||||
|
.unwrap_or_else(|_| "[]".to_string()),
|
||||||
|
contract = SQUARE_HOLE_AGENT_OUTPUT_CONTRACT,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn serialize_square_hole_session_config(session: &SquareHoleAgentSessionRecord) -> String {
|
||||||
|
serde_json::to_string_pretty(&json!({
|
||||||
|
"themeText": session.config.theme_text,
|
||||||
|
"twistRule": session.config.twist_rule,
|
||||||
|
"shapeCount": session.config.shape_count,
|
||||||
|
"difficulty": session.config.difficulty,
|
||||||
|
}))
|
||||||
|
.unwrap_or_else(|_| "{}".to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_chat_history(messages: &[SquareHoleAgentMessageRecord]) -> Vec<JsonValue> {
|
||||||
|
messages
|
||||||
|
.iter()
|
||||||
|
.map(|message| {
|
||||||
|
json!({
|
||||||
|
"role": message.role,
|
||||||
|
"kind": message.kind,
|
||||||
|
"content": message.text,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::build_square_hole_agent_prompt;
|
||||||
|
|
||||||
|
fn message(role: &str, text: &str) -> spacetime_client::SquareHoleAgentMessageRecord {
|
||||||
|
spacetime_client::SquareHoleAgentMessageRecord {
|
||||||
|
id: format!("message-{role}"),
|
||||||
|
role: role.to_string(),
|
||||||
|
kind: "chat".to_string(),
|
||||||
|
text: text.to_string(),
|
||||||
|
created_at: "2026-05-04T10:00:00.000Z".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn session_record() -> spacetime_client::SquareHoleAgentSessionRecord {
|
||||||
|
spacetime_client::SquareHoleAgentSessionRecord {
|
||||||
|
session_id: "square-hole-session-test".to_string(),
|
||||||
|
current_turn: 1,
|
||||||
|
progress_percent: 25,
|
||||||
|
stage: "collecting_config".to_string(),
|
||||||
|
anchor_pack: spacetime_client::SquareHoleAnchorPackRecord {
|
||||||
|
theme: anchor("theme", "题材主题", "积木纸箱"),
|
||||||
|
twist_rule: anchor("twistRule", "反差规则", ""),
|
||||||
|
shape_count: anchor("shapeCount", "形状数量", "12"),
|
||||||
|
difficulty: anchor("difficulty", "难度", "4"),
|
||||||
|
},
|
||||||
|
config: spacetime_client::SquareHoleCreatorConfigRecord {
|
||||||
|
theme_text: "积木纸箱".to_string(),
|
||||||
|
twist_rule: "方洞万能".to_string(),
|
||||||
|
shape_count: 12,
|
||||||
|
difficulty: 4,
|
||||||
|
},
|
||||||
|
draft: None,
|
||||||
|
messages: vec![message("user", "做成办公室文具版")],
|
||||||
|
last_assistant_reply: Some("这次可以从办公室文具题材开始。".to_string()),
|
||||||
|
published_profile_id: None,
|
||||||
|
updated_at: "2026-05-04T10:00:00.000Z".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn anchor(key: &str, label: &str, value: &str) -> spacetime_client::SquareHoleAnchorItemRecord {
|
||||||
|
spacetime_client::SquareHoleAnchorItemRecord {
|
||||||
|
key: key.to_string(),
|
||||||
|
label: label.to_string(),
|
||||||
|
value: value.to_string(),
|
||||||
|
status: if value.is_empty() {
|
||||||
|
"missing"
|
||||||
|
} else {
|
||||||
|
"confirmed"
|
||||||
|
}
|
||||||
|
.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn quick_fill_prompt_requires_complete_config() {
|
||||||
|
let prompt = build_square_hole_agent_prompt(&session_record(), true);
|
||||||
|
|
||||||
|
assert!(prompt.contains("用户刚刚主动要求你自动补充剩余关键字"));
|
||||||
|
assert!(prompt.contains("不要再继续提问"));
|
||||||
|
assert!(prompt.contains("nextConfig"));
|
||||||
|
assert!(prompt.contains("progressPercent 直接输出为 100"));
|
||||||
|
}
|
||||||
|
}
|
||||||
1481
server-rs/crates/api-server/src/square_hole.rs
Normal file
1481
server-rs/crates/api-server/src/square_hole.rs
Normal file
File diff suppressed because it is too large
Load Diff
307
server-rs/crates/api-server/src/square_hole_agent_turn.rs
Normal file
307
server-rs/crates/api-server/src/square_hole_agent_turn.rs
Normal file
@@ -0,0 +1,307 @@
|
|||||||
|
use module_square_hole::{
|
||||||
|
SQUARE_HOLE_MAX_DIFFICULTY, SQUARE_HOLE_MAX_SHAPE_COUNT, SQUARE_HOLE_MIN_DIFFICULTY,
|
||||||
|
SQUARE_HOLE_MIN_SHAPE_COUNT,
|
||||||
|
};
|
||||||
|
use platform_llm::LlmClient;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_json::Value as JsonValue;
|
||||||
|
use spacetime_client::{SquareHoleAgentMessageFinalizeRecordInput, SquareHoleAgentSessionRecord};
|
||||||
|
|
||||||
|
use crate::creation_agent_llm_turn::{
|
||||||
|
CreationAgentLlmTurnErrorMessages, stream_creation_agent_json_turn,
|
||||||
|
};
|
||||||
|
use crate::prompt::square_hole::{
|
||||||
|
SQUARE_HOLE_AGENT_JSON_TURN_USER_PROMPT, SQUARE_HOLE_AGENT_SYSTEM_PROMPT,
|
||||||
|
build_square_hole_agent_prompt,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub(crate) struct SquareHoleAgentTurnRequest<'a> {
|
||||||
|
pub llm_client: Option<&'a LlmClient>,
|
||||||
|
pub session: &'a SquareHoleAgentSessionRecord,
|
||||||
|
pub quick_fill_requested: bool,
|
||||||
|
pub enable_web_search: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub(crate) struct SquareHoleAgentTurnResult {
|
||||||
|
pub assistant_reply_text: String,
|
||||||
|
pub stage: String,
|
||||||
|
pub progress_percent: u32,
|
||||||
|
pub config_json: String,
|
||||||
|
pub error_message: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub(crate) struct SquareHoleAgentTurnError {
|
||||||
|
message: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SquareHoleAgentTurnError {
|
||||||
|
fn new(message: impl Into<String>) -> Self {
|
||||||
|
Self {
|
||||||
|
message: message.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for SquareHoleAgentTurnError {
|
||||||
|
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
formatter.write_str(&self.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::error::Error for SquareHoleAgentTurnError {}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
struct SquareHoleAgentModelOutput {
|
||||||
|
reply_text: String,
|
||||||
|
progress_percent: u32,
|
||||||
|
next_config: SquareHoleAgentConfigOutput,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
struct SquareHoleAgentConfigOutput {
|
||||||
|
theme_text: String,
|
||||||
|
twist_rule: String,
|
||||||
|
shape_count: u32,
|
||||||
|
difficulty: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn run_square_hole_agent_turn<F>(
|
||||||
|
request: SquareHoleAgentTurnRequest<'_>,
|
||||||
|
on_reply_update: F,
|
||||||
|
) -> Result<SquareHoleAgentTurnResult, SquareHoleAgentTurnError>
|
||||||
|
where
|
||||||
|
F: FnMut(&str),
|
||||||
|
{
|
||||||
|
let prompt = build_square_hole_agent_prompt(request.session, request.quick_fill_requested);
|
||||||
|
let turn_output = stream_creation_agent_json_turn(
|
||||||
|
request.llm_client,
|
||||||
|
format!("{SQUARE_HOLE_AGENT_SYSTEM_PROMPT}\n\n{prompt}"),
|
||||||
|
SQUARE_HOLE_AGENT_JSON_TURN_USER_PROMPT,
|
||||||
|
request.enable_web_search,
|
||||||
|
CreationAgentLlmTurnErrorMessages {
|
||||||
|
model_unavailable: "当前模型不可用,请稍后重试。",
|
||||||
|
generation_failed: "方洞挑战聊天生成失败,请稍后重试。",
|
||||||
|
parse_failed: "方洞挑战聊天结果解析失败,请稍后重试。",
|
||||||
|
},
|
||||||
|
on_reply_update,
|
||||||
|
SquareHoleAgentTurnError::new,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
let output = parse_model_output(&turn_output.parsed, request.session)?;
|
||||||
|
let progress_percent = if request.quick_fill_requested {
|
||||||
|
100
|
||||||
|
} else {
|
||||||
|
output.progress_percent.min(100)
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(SquareHoleAgentTurnResult {
|
||||||
|
assistant_reply_text: output.reply_text,
|
||||||
|
stage: resolve_stage(progress_percent),
|
||||||
|
progress_percent,
|
||||||
|
config_json: serde_json::to_string(&output.next_config)
|
||||||
|
.map_err(|_| SquareHoleAgentTurnError::new("方洞挑战配置序列化失败。"))?,
|
||||||
|
error_message: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn build_finalize_record_input(
|
||||||
|
session_id: String,
|
||||||
|
owner_user_id: String,
|
||||||
|
assistant_message_id: String,
|
||||||
|
result: SquareHoleAgentTurnResult,
|
||||||
|
updated_at_micros: i64,
|
||||||
|
) -> SquareHoleAgentMessageFinalizeRecordInput {
|
||||||
|
SquareHoleAgentMessageFinalizeRecordInput {
|
||||||
|
session_id,
|
||||||
|
owner_user_id,
|
||||||
|
assistant_message_id: Some(assistant_message_id),
|
||||||
|
assistant_reply_text: Some(result.assistant_reply_text),
|
||||||
|
config_json: Some(result.config_json),
|
||||||
|
progress_percent: result.progress_percent,
|
||||||
|
stage: result.stage,
|
||||||
|
updated_at_micros,
|
||||||
|
error_message: result.error_message,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_model_output(
|
||||||
|
parsed: &JsonValue,
|
||||||
|
session: &SquareHoleAgentSessionRecord,
|
||||||
|
) -> Result<SquareHoleAgentModelOutput, SquareHoleAgentTurnError> {
|
||||||
|
let reply_text = parsed
|
||||||
|
.get("replyText")
|
||||||
|
.and_then(JsonValue::as_str)
|
||||||
|
.map(str::trim)
|
||||||
|
.filter(|value| !value.is_empty())
|
||||||
|
.ok_or_else(|| SquareHoleAgentTurnError::new("方洞挑战聊天结果缺少有效回复,请稍后重试。"))?
|
||||||
|
.to_string();
|
||||||
|
let progress_percent = parsed
|
||||||
|
.get("progressPercent")
|
||||||
|
.and_then(JsonValue::as_u64)
|
||||||
|
.map(|value| value.min(100) as u32)
|
||||||
|
.unwrap_or(session.progress_percent);
|
||||||
|
let next_config_value = parsed
|
||||||
|
.get("nextConfig")
|
||||||
|
.ok_or_else(|| SquareHoleAgentTurnError::new("方洞挑战聊天结果缺少 nextConfig。"))?;
|
||||||
|
let next_config = parse_model_config(next_config_value, session)?;
|
||||||
|
Ok(SquareHoleAgentModelOutput {
|
||||||
|
reply_text,
|
||||||
|
progress_percent,
|
||||||
|
next_config,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_model_config(
|
||||||
|
value: &JsonValue,
|
||||||
|
session: &SquareHoleAgentSessionRecord,
|
||||||
|
) -> Result<SquareHoleAgentConfigOutput, SquareHoleAgentTurnError> {
|
||||||
|
if !value.is_object() {
|
||||||
|
return Err(SquareHoleAgentTurnError::new(
|
||||||
|
"方洞挑战聊天结果中的 nextConfig 必须是对象。",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(SquareHoleAgentConfigOutput {
|
||||||
|
theme_text: read_text_field(value, "themeText")
|
||||||
|
.unwrap_or_else(|| session.config.theme_text.clone()),
|
||||||
|
twist_rule: read_text_field(value, "twistRule")
|
||||||
|
.unwrap_or_else(|| session.config.twist_rule.clone()),
|
||||||
|
shape_count: read_u32_field(value, "shapeCount")
|
||||||
|
.unwrap_or(session.config.shape_count)
|
||||||
|
.clamp(SQUARE_HOLE_MIN_SHAPE_COUNT, SQUARE_HOLE_MAX_SHAPE_COUNT),
|
||||||
|
difficulty: read_u32_field(value, "difficulty")
|
||||||
|
.unwrap_or(session.config.difficulty)
|
||||||
|
.clamp(SQUARE_HOLE_MIN_DIFFICULTY, SQUARE_HOLE_MAX_DIFFICULTY),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_text_field(value: &JsonValue, field_name: &str) -> Option<String> {
|
||||||
|
value
|
||||||
|
.get(field_name)
|
||||||
|
.and_then(JsonValue::as_str)
|
||||||
|
.map(str::trim)
|
||||||
|
.filter(|text| !text.is_empty())
|
||||||
|
.map(str::to_string)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_u32_field(value: &JsonValue, field_name: &str) -> Option<u32> {
|
||||||
|
value
|
||||||
|
.get(field_name)
|
||||||
|
.and_then(JsonValue::as_u64)
|
||||||
|
.and_then(|number| u32::try_from(number).ok())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn resolve_stage(progress_percent: u32) -> String {
|
||||||
|
if progress_percent >= 100 {
|
||||||
|
"ReadyToCompile"
|
||||||
|
} else {
|
||||||
|
"Collecting"
|
||||||
|
}
|
||||||
|
.to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use serde_json::json;
|
||||||
|
|
||||||
|
use super::{parse_model_output, resolve_stage};
|
||||||
|
|
||||||
|
fn session_record() -> spacetime_client::SquareHoleAgentSessionRecord {
|
||||||
|
spacetime_client::SquareHoleAgentSessionRecord {
|
||||||
|
session_id: "square-hole-session-test".to_string(),
|
||||||
|
current_turn: 1,
|
||||||
|
progress_percent: 25,
|
||||||
|
stage: "collecting_config".to_string(),
|
||||||
|
anchor_pack: spacetime_client::SquareHoleAnchorPackRecord {
|
||||||
|
theme: anchor("theme", "题材主题", "纸箱"),
|
||||||
|
twist_rule: anchor("twistRule", "反差规则", "方洞万能"),
|
||||||
|
shape_count: anchor("shapeCount", "形状数量", "12"),
|
||||||
|
difficulty: anchor("difficulty", "难度", "4"),
|
||||||
|
},
|
||||||
|
config: spacetime_client::SquareHoleCreatorConfigRecord {
|
||||||
|
theme_text: "纸箱".to_string(),
|
||||||
|
twist_rule: "方洞万能".to_string(),
|
||||||
|
shape_count: 12,
|
||||||
|
difficulty: 4,
|
||||||
|
},
|
||||||
|
draft: None,
|
||||||
|
messages: Vec::new(),
|
||||||
|
last_assistant_reply: None,
|
||||||
|
published_profile_id: None,
|
||||||
|
updated_at: "2026-05-04T10:00:00.000Z".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn anchor(key: &str, label: &str, value: &str) -> spacetime_client::SquareHoleAnchorItemRecord {
|
||||||
|
spacetime_client::SquareHoleAnchorItemRecord {
|
||||||
|
key: key.to_string(),
|
||||||
|
label: label.to_string(),
|
||||||
|
value: value.to_string(),
|
||||||
|
status: if value.is_empty() {
|
||||||
|
"missing"
|
||||||
|
} else {
|
||||||
|
"confirmed"
|
||||||
|
}
|
||||||
|
.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_model_output_accepts_camel_case_config_contract() {
|
||||||
|
let model_output = json!({
|
||||||
|
"replyText": "可以,把办公室文具都做成会被方洞吞进去的挑战。",
|
||||||
|
"progressPercent": 86,
|
||||||
|
"nextConfig": {
|
||||||
|
"themeText": "办公室文具",
|
||||||
|
"twistRule": "所有文具最终都优先进入方洞",
|
||||||
|
"shapeCount": 14,
|
||||||
|
"difficulty": 6
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let output =
|
||||||
|
parse_model_output(&model_output, &session_record()).expect("模型输出应能解析");
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
output.reply_text,
|
||||||
|
"可以,把办公室文具都做成会被方洞吞进去的挑战。"
|
||||||
|
);
|
||||||
|
assert_eq!(output.progress_percent, 86);
|
||||||
|
assert_eq!(output.next_config.theme_text, "办公室文具");
|
||||||
|
assert_eq!(output.next_config.twist_rule, "所有文具最终都优先进入方洞");
|
||||||
|
assert_eq!(output.next_config.shape_count, 14);
|
||||||
|
assert_eq!(output.next_config.difficulty, 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_model_output_clamps_numeric_config() {
|
||||||
|
let model_output = json!({
|
||||||
|
"replyText": "我先把数字压到可试玩范围里。",
|
||||||
|
"progressPercent": 120,
|
||||||
|
"nextConfig": {
|
||||||
|
"themeText": "霓虹积木",
|
||||||
|
"twistRule": "方洞优先",
|
||||||
|
"shapeCount": 99,
|
||||||
|
"difficulty": 0
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let output =
|
||||||
|
parse_model_output(&model_output, &session_record()).expect("模型输出应能解析");
|
||||||
|
|
||||||
|
assert_eq!(output.progress_percent, 100);
|
||||||
|
assert_eq!(output.next_config.shape_count, 24);
|
||||||
|
assert_eq!(output.next_config.difficulty, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn resolve_stage_switches_to_compile_only_at_complete_progress() {
|
||||||
|
assert_eq!(resolve_stage(99), "Collecting");
|
||||||
|
assert_eq!(resolve_stage(100), "ReadyToCompile");
|
||||||
|
}
|
||||||
|
}
|
||||||
14
server-rs/crates/module-square-hole/Cargo.toml
Normal file
14
server-rs/crates/module-square-hole/Cargo.toml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
[package]
|
||||||
|
name = "module-square-hole"
|
||||||
|
edition.workspace = true
|
||||||
|
version.workspace = true
|
||||||
|
license.workspace = true
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = []
|
||||||
|
spacetime-types = ["dep:spacetimedb"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
serde = { version = "1", features = ["derive"] }
|
||||||
|
shared-kernel = { path = "../shared-kernel" }
|
||||||
|
spacetimedb = { workspace = true, optional = true }
|
||||||
456
server-rs/crates/module-square-hole/src/application.rs
Normal file
456
server-rs/crates/module-square-hole/src/application.rs
Normal file
@@ -0,0 +1,456 @@
|
|||||||
|
use shared_kernel::{normalize_optional_string, normalize_required_string, normalize_string_list};
|
||||||
|
|
||||||
|
use crate::commands::{default_tags_for_theme, validate_publish_requirements};
|
||||||
|
use crate::{
|
||||||
|
SQUARE_HOLE_DEFAULT_DURATION_LIMIT_MS, SQUARE_HOLE_MAX_DIFFICULTY, SQUARE_HOLE_MIN_DIFFICULTY,
|
||||||
|
SquareHoleCreatorConfig, SquareHoleDropConfirmation, SquareHoleDropFeedback,
|
||||||
|
SquareHoleDropInput, SquareHoleDropRejectReason, SquareHoleError, SquareHoleHoleSnapshot,
|
||||||
|
SquareHolePublicationStatus, SquareHoleResultDraft, SquareHoleRunSnapshot, SquareHoleRunStatus,
|
||||||
|
SquareHoleShapeSnapshot, SquareHoleWorkProfile,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn compile_result_draft(
|
||||||
|
profile_id: String,
|
||||||
|
config: &SquareHoleCreatorConfig,
|
||||||
|
) -> SquareHoleResultDraft {
|
||||||
|
let game_name = format!("{}方洞挑战", config.theme_text);
|
||||||
|
let summary = format!(
|
||||||
|
"{}主题,{} 个形状,难度 {},真实规则:{}。",
|
||||||
|
config.theme_text, config.shape_count, config.difficulty, config.twist_rule
|
||||||
|
);
|
||||||
|
let mut draft = SquareHoleResultDraft {
|
||||||
|
profile_id,
|
||||||
|
game_name,
|
||||||
|
theme_text: config.theme_text.clone(),
|
||||||
|
twist_rule: config.twist_rule.clone(),
|
||||||
|
summary,
|
||||||
|
tags: default_tags_for_theme(&config.theme_text),
|
||||||
|
shape_count: config.shape_count,
|
||||||
|
difficulty: config.difficulty,
|
||||||
|
publish_ready: false,
|
||||||
|
blockers: Vec::new(),
|
||||||
|
};
|
||||||
|
draft.blockers = validate_publish_requirements(&draft);
|
||||||
|
draft.publish_ready = draft.blockers.is_empty();
|
||||||
|
draft
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_work_profile(
|
||||||
|
work_id: String,
|
||||||
|
profile_id: String,
|
||||||
|
owner_user_id: String,
|
||||||
|
source_session_id: Option<String>,
|
||||||
|
draft: &SquareHoleResultDraft,
|
||||||
|
updated_at_micros: i64,
|
||||||
|
) -> Result<SquareHoleWorkProfile, SquareHoleError> {
|
||||||
|
let work_id = normalize_required_string(work_id).ok_or(SquareHoleError::MissingText)?;
|
||||||
|
let profile_id =
|
||||||
|
normalize_required_string(profile_id).ok_or(SquareHoleError::MissingProfileId)?;
|
||||||
|
let owner_user_id =
|
||||||
|
normalize_required_string(owner_user_id).ok_or(SquareHoleError::MissingOwnerUserId)?;
|
||||||
|
|
||||||
|
Ok(SquareHoleWorkProfile {
|
||||||
|
work_id,
|
||||||
|
profile_id,
|
||||||
|
owner_user_id,
|
||||||
|
source_session_id: normalize_optional_string(source_session_id),
|
||||||
|
game_name: draft.game_name.clone(),
|
||||||
|
theme_text: draft.theme_text.clone(),
|
||||||
|
twist_rule: draft.twist_rule.clone(),
|
||||||
|
summary: draft.summary.clone(),
|
||||||
|
tags: normalize_string_list(draft.tags.clone()),
|
||||||
|
cover_image_src: None,
|
||||||
|
shape_count: draft.shape_count,
|
||||||
|
difficulty: draft.difficulty,
|
||||||
|
publication_status: SquareHolePublicationStatus::Draft,
|
||||||
|
play_count: 0,
|
||||||
|
updated_at_micros,
|
||||||
|
published_at_micros: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn publish_work_profile(
|
||||||
|
profile: &SquareHoleWorkProfile,
|
||||||
|
published_at_micros: i64,
|
||||||
|
) -> Result<SquareHoleWorkProfile, SquareHoleError> {
|
||||||
|
if profile.shape_count == 0 {
|
||||||
|
return Err(SquareHoleError::InvalidShapeCount);
|
||||||
|
}
|
||||||
|
if !(SQUARE_HOLE_MIN_DIFFICULTY..=SQUARE_HOLE_MAX_DIFFICULTY).contains(&profile.difficulty) {
|
||||||
|
return Err(SquareHoleError::InvalidDifficulty);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut next = profile.clone();
|
||||||
|
next.publication_status = SquareHolePublicationStatus::Published;
|
||||||
|
next.updated_at_micros = published_at_micros;
|
||||||
|
next.published_at_micros = Some(published_at_micros);
|
||||||
|
Ok(next)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn start_run_at(
|
||||||
|
run_id: String,
|
||||||
|
owner_user_id: String,
|
||||||
|
profile_id: String,
|
||||||
|
config: &SquareHoleCreatorConfig,
|
||||||
|
started_at_ms: u64,
|
||||||
|
) -> Result<SquareHoleRunSnapshot, SquareHoleError> {
|
||||||
|
let run_id = normalize_required_string(run_id).ok_or(SquareHoleError::MissingRunId)?;
|
||||||
|
let owner_user_id =
|
||||||
|
normalize_required_string(owner_user_id).ok_or(SquareHoleError::MissingOwnerUserId)?;
|
||||||
|
let profile_id =
|
||||||
|
normalize_required_string(profile_id).ok_or(SquareHoleError::MissingProfileId)?;
|
||||||
|
|
||||||
|
Ok(SquareHoleRunSnapshot {
|
||||||
|
run_id,
|
||||||
|
profile_id,
|
||||||
|
owner_user_id,
|
||||||
|
status: SquareHoleRunStatus::Running,
|
||||||
|
snapshot_version: 1,
|
||||||
|
started_at_ms,
|
||||||
|
duration_limit_ms: SQUARE_HOLE_DEFAULT_DURATION_LIMIT_MS,
|
||||||
|
remaining_ms: SQUARE_HOLE_DEFAULT_DURATION_LIMIT_MS,
|
||||||
|
total_shape_count: config.shape_count,
|
||||||
|
completed_shape_count: 0,
|
||||||
|
combo: 0,
|
||||||
|
best_combo: 0,
|
||||||
|
score: 0,
|
||||||
|
rule_label: config.twist_rule.clone(),
|
||||||
|
current_shape: Some(build_shape_at(0, config.shape_count)),
|
||||||
|
holes: default_holes(),
|
||||||
|
last_feedback: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn confirm_drop_at(
|
||||||
|
run: &SquareHoleRunSnapshot,
|
||||||
|
input: &SquareHoleDropInput,
|
||||||
|
) -> Result<SquareHoleDropConfirmation, SquareHoleError> {
|
||||||
|
let hole_id =
|
||||||
|
normalize_required_string(&input.hole_id).ok_or(SquareHoleError::MissingHoleId)?;
|
||||||
|
let mut next = resolve_run_timer_at(run, input.dropped_at_ms);
|
||||||
|
if next.status != SquareHoleRunStatus::Running {
|
||||||
|
return Ok(rejected(next, SquareHoleDropRejectReason::RunNotActive));
|
||||||
|
}
|
||||||
|
if input.client_snapshot_version != next.snapshot_version {
|
||||||
|
return Ok(rejected(
|
||||||
|
next,
|
||||||
|
SquareHoleDropRejectReason::SnapshotVersionMismatch,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
let Some(hole) = next.holes.iter().find(|item| item.hole_id == hole_id) else {
|
||||||
|
return Ok(rejected(next, SquareHoleDropRejectReason::HoleNotFound));
|
||||||
|
};
|
||||||
|
let Some(shape) = next.current_shape.clone() else {
|
||||||
|
return Ok(rejected(next, SquareHoleDropRejectReason::Incompatible));
|
||||||
|
};
|
||||||
|
|
||||||
|
if !is_shape_accepted_by_hole(&shape, hole) {
|
||||||
|
next.combo = 0;
|
||||||
|
next.snapshot_version = next.snapshot_version.saturating_add(1);
|
||||||
|
return Ok(rejected(next, SquareHoleDropRejectReason::Incompatible));
|
||||||
|
}
|
||||||
|
|
||||||
|
let message = format!("{}进入{}", shape.label, hole.label);
|
||||||
|
let feedback = SquareHoleDropFeedback {
|
||||||
|
accepted: true,
|
||||||
|
reject_reason: None,
|
||||||
|
message,
|
||||||
|
};
|
||||||
|
next.completed_shape_count = next.completed_shape_count.saturating_add(1);
|
||||||
|
next.combo = next.combo.saturating_add(1);
|
||||||
|
next.best_combo = next.best_combo.max(next.combo);
|
||||||
|
next.score = next.score.saturating_add(100 + next.combo * 10);
|
||||||
|
next.current_shape = if next.completed_shape_count >= next.total_shape_count {
|
||||||
|
next.status = SquareHoleRunStatus::Won;
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(build_shape_at(
|
||||||
|
next.completed_shape_count,
|
||||||
|
next.total_shape_count,
|
||||||
|
))
|
||||||
|
};
|
||||||
|
next.snapshot_version = next.snapshot_version.saturating_add(1);
|
||||||
|
next.last_feedback = Some(feedback.clone());
|
||||||
|
|
||||||
|
Ok(SquareHoleDropConfirmation {
|
||||||
|
feedback,
|
||||||
|
run: next,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn resolve_run_timer_at(run: &SquareHoleRunSnapshot, now_ms: u64) -> SquareHoleRunSnapshot {
|
||||||
|
let mut next = run.clone();
|
||||||
|
if next.status != SquareHoleRunStatus::Running {
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
let elapsed_ms = now_ms.saturating_sub(next.started_at_ms);
|
||||||
|
next.remaining_ms = next.duration_limit_ms.saturating_sub(elapsed_ms);
|
||||||
|
if next.remaining_ms == 0 {
|
||||||
|
let feedback = SquareHoleDropFeedback {
|
||||||
|
accepted: false,
|
||||||
|
reject_reason: Some(SquareHoleDropRejectReason::TimeUp),
|
||||||
|
message: "时间到".to_string(),
|
||||||
|
};
|
||||||
|
next.status = SquareHoleRunStatus::Failed;
|
||||||
|
next.combo = 0;
|
||||||
|
next.current_shape = None;
|
||||||
|
next.last_feedback = Some(feedback);
|
||||||
|
next.snapshot_version = next.snapshot_version.saturating_add(1);
|
||||||
|
}
|
||||||
|
next
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn stop_run_at(run: &SquareHoleRunSnapshot) -> SquareHoleRunSnapshot {
|
||||||
|
let mut next = run.clone();
|
||||||
|
if next.status == SquareHoleRunStatus::Running {
|
||||||
|
next.status = SquareHoleRunStatus::Stopped;
|
||||||
|
next.combo = 0;
|
||||||
|
next.snapshot_version = next.snapshot_version.saturating_add(1);
|
||||||
|
next.last_feedback = Some(SquareHoleDropFeedback {
|
||||||
|
accepted: false,
|
||||||
|
reject_reason: Some(SquareHoleDropRejectReason::RunNotActive),
|
||||||
|
message: "已退出本局".to_string(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
next
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build_shape_at(index: u32, total: u32) -> SquareHoleShapeSnapshot {
|
||||||
|
let kind = if index + 1 == total {
|
||||||
|
"square"
|
||||||
|
} else if index % 4 == 0 {
|
||||||
|
"circle"
|
||||||
|
} else if index % 4 == 1 {
|
||||||
|
"triangle"
|
||||||
|
} else if index % 4 == 2 {
|
||||||
|
"diamond"
|
||||||
|
} else {
|
||||||
|
"star"
|
||||||
|
};
|
||||||
|
|
||||||
|
SquareHoleShapeSnapshot {
|
||||||
|
shape_id: format!("square-hole-shape-{index:03}"),
|
||||||
|
shape_kind: kind.to_string(),
|
||||||
|
label: match kind {
|
||||||
|
"square" => "方块",
|
||||||
|
"circle" => "圆块",
|
||||||
|
"triangle" => "三角块",
|
||||||
|
"diamond" => "菱形块",
|
||||||
|
_ => "星形块",
|
||||||
|
}
|
||||||
|
.to_string(),
|
||||||
|
color: match kind {
|
||||||
|
"square" => "#facc15",
|
||||||
|
"circle" => "#22c55e",
|
||||||
|
"triangle" => "#38bdf8",
|
||||||
|
"diamond" => "#fb7185",
|
||||||
|
_ => "#c084fc",
|
||||||
|
}
|
||||||
|
.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn default_holes() -> Vec<SquareHoleHoleSnapshot> {
|
||||||
|
vec![
|
||||||
|
SquareHoleHoleSnapshot {
|
||||||
|
hole_id: "square-hole".to_string(),
|
||||||
|
hole_kind: "square".to_string(),
|
||||||
|
label: "方洞".to_string(),
|
||||||
|
x: 0.5,
|
||||||
|
y: 0.28,
|
||||||
|
},
|
||||||
|
SquareHoleHoleSnapshot {
|
||||||
|
hole_id: "circle-hole".to_string(),
|
||||||
|
hole_kind: "circle".to_string(),
|
||||||
|
label: "圆洞".to_string(),
|
||||||
|
x: 0.24,
|
||||||
|
y: 0.54,
|
||||||
|
},
|
||||||
|
SquareHoleHoleSnapshot {
|
||||||
|
hole_id: "triangle-hole".to_string(),
|
||||||
|
hole_kind: "triangle".to_string(),
|
||||||
|
label: "三角洞".to_string(),
|
||||||
|
x: 0.76,
|
||||||
|
y: 0.54,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_shape_accepted_by_hole(
|
||||||
|
shape: &SquareHoleShapeSnapshot,
|
||||||
|
hole: &SquareHoleHoleSnapshot,
|
||||||
|
) -> bool {
|
||||||
|
// 中文注释:首版核心反差固定为“方洞万能”,保留同形状洞口兼容便于后续扩展规则。
|
||||||
|
hole.hole_kind == "square" || hole.hole_kind == shape.shape_kind
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rejected(
|
||||||
|
mut run: SquareHoleRunSnapshot,
|
||||||
|
reject_reason: SquareHoleDropRejectReason,
|
||||||
|
) -> SquareHoleDropConfirmation {
|
||||||
|
let message = match reject_reason {
|
||||||
|
SquareHoleDropRejectReason::RunNotActive => "当前局已结束",
|
||||||
|
SquareHoleDropRejectReason::SnapshotVersionMismatch => "操作慢了一步",
|
||||||
|
SquareHoleDropRejectReason::HoleNotFound => "洞口不存在",
|
||||||
|
SquareHoleDropRejectReason::Incompatible => "这个洞不对",
|
||||||
|
SquareHoleDropRejectReason::TimeUp => "时间到",
|
||||||
|
}
|
||||||
|
.to_string();
|
||||||
|
let feedback = SquareHoleDropFeedback {
|
||||||
|
accepted: false,
|
||||||
|
reject_reason: Some(reject_reason),
|
||||||
|
message,
|
||||||
|
};
|
||||||
|
run.last_feedback = Some(feedback.clone());
|
||||||
|
SquareHoleDropConfirmation { feedback, run }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use crate::commands::build_creator_config;
|
||||||
|
|
||||||
|
fn test_config(shape_count: u32) -> SquareHoleCreatorConfig {
|
||||||
|
build_creator_config("玩具", "方洞万能", shape_count, 4).expect("config should be valid")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn draft_is_publishable_with_required_fields() {
|
||||||
|
let draft = compile_result_draft("profile-1".to_string(), &test_config(8));
|
||||||
|
|
||||||
|
assert!(draft.publish_ready);
|
||||||
|
assert!(draft.blockers.is_empty());
|
||||||
|
assert!(draft.tags.contains(&"方洞挑战".to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn run_starts_with_current_shape_and_default_holes() {
|
||||||
|
let run = start_run_at(
|
||||||
|
"run-1".to_string(),
|
||||||
|
"user-1".to_string(),
|
||||||
|
"profile-1".to_string(),
|
||||||
|
&test_config(8),
|
||||||
|
1_000,
|
||||||
|
)
|
||||||
|
.expect("run should start");
|
||||||
|
|
||||||
|
assert_eq!(run.status, SquareHoleRunStatus::Running);
|
||||||
|
assert!(run.current_shape.is_some());
|
||||||
|
assert_eq!(run.holes.len(), 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn square_hole_accepts_non_square_shape() {
|
||||||
|
let run = start_run_at(
|
||||||
|
"run-1".to_string(),
|
||||||
|
"user-1".to_string(),
|
||||||
|
"profile-1".to_string(),
|
||||||
|
&test_config(8),
|
||||||
|
1_000,
|
||||||
|
)
|
||||||
|
.expect("run should start");
|
||||||
|
let result = confirm_drop_at(
|
||||||
|
&run,
|
||||||
|
&SquareHoleDropInput {
|
||||||
|
run_id: run.run_id.clone(),
|
||||||
|
owner_user_id: run.owner_user_id.clone(),
|
||||||
|
hole_id: "square-hole".to_string(),
|
||||||
|
client_snapshot_version: run.snapshot_version,
|
||||||
|
client_event_id: "event-1".to_string(),
|
||||||
|
dropped_at_ms: 1_100,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.expect("drop should resolve");
|
||||||
|
|
||||||
|
assert!(result.feedback.accepted);
|
||||||
|
assert_eq!(result.run.completed_shape_count, 1);
|
||||||
|
assert_eq!(result.run.combo, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn wrong_non_square_hole_rejects_and_resets_combo() {
|
||||||
|
let mut run = start_run_at(
|
||||||
|
"run-1".to_string(),
|
||||||
|
"user-1".to_string(),
|
||||||
|
"profile-1".to_string(),
|
||||||
|
&test_config(8),
|
||||||
|
1_000,
|
||||||
|
)
|
||||||
|
.expect("run should start");
|
||||||
|
run.current_shape = Some(build_shape_at(1, 8));
|
||||||
|
run.combo = 2;
|
||||||
|
|
||||||
|
let result = confirm_drop_at(
|
||||||
|
&run,
|
||||||
|
&SquareHoleDropInput {
|
||||||
|
run_id: run.run_id.clone(),
|
||||||
|
owner_user_id: run.owner_user_id.clone(),
|
||||||
|
hole_id: "circle-hole".to_string(),
|
||||||
|
client_snapshot_version: run.snapshot_version,
|
||||||
|
client_event_id: "event-1".to_string(),
|
||||||
|
dropped_at_ms: 1_100,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.expect("drop should resolve");
|
||||||
|
|
||||||
|
assert!(!result.feedback.accepted);
|
||||||
|
assert_eq!(
|
||||||
|
result.feedback.reject_reason,
|
||||||
|
Some(SquareHoleDropRejectReason::Incompatible)
|
||||||
|
);
|
||||||
|
assert_eq!(result.run.combo, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn last_shape_win_finishes_run() {
|
||||||
|
let mut run = start_run_at(
|
||||||
|
"run-1".to_string(),
|
||||||
|
"user-1".to_string(),
|
||||||
|
"profile-1".to_string(),
|
||||||
|
&test_config(6),
|
||||||
|
1_000,
|
||||||
|
)
|
||||||
|
.expect("run should start");
|
||||||
|
run.completed_shape_count = 5;
|
||||||
|
run.current_shape = Some(build_shape_at(5, 6));
|
||||||
|
|
||||||
|
let result = confirm_drop_at(
|
||||||
|
&run,
|
||||||
|
&SquareHoleDropInput {
|
||||||
|
run_id: run.run_id.clone(),
|
||||||
|
owner_user_id: run.owner_user_id.clone(),
|
||||||
|
hole_id: "square-hole".to_string(),
|
||||||
|
client_snapshot_version: run.snapshot_version,
|
||||||
|
client_event_id: "event-1".to_string(),
|
||||||
|
dropped_at_ms: 1_100,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.expect("drop should resolve");
|
||||||
|
|
||||||
|
assert_eq!(result.run.status, SquareHoleRunStatus::Won);
|
||||||
|
assert!(result.run.current_shape.is_none());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn timer_expiration_fails_running_run() {
|
||||||
|
let run = start_run_at(
|
||||||
|
"run-1".to_string(),
|
||||||
|
"user-1".to_string(),
|
||||||
|
"profile-1".to_string(),
|
||||||
|
&test_config(8),
|
||||||
|
1_000,
|
||||||
|
)
|
||||||
|
.expect("run should start");
|
||||||
|
|
||||||
|
let expired = resolve_run_timer_at(&run, 1_000 + SQUARE_HOLE_DEFAULT_DURATION_LIMIT_MS);
|
||||||
|
|
||||||
|
assert_eq!(expired.status, SquareHoleRunStatus::Failed);
|
||||||
|
assert_eq!(
|
||||||
|
expired
|
||||||
|
.last_feedback
|
||||||
|
.and_then(|feedback| feedback.reject_reason),
|
||||||
|
Some(SquareHoleDropRejectReason::TimeUp)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
116
server-rs/crates/module-square-hole/src/commands.rs
Normal file
116
server-rs/crates/module-square-hole/src/commands.rs
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
use shared_kernel::{normalize_required_string, normalize_string_list};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
SQUARE_HOLE_MAX_DIFFICULTY, SQUARE_HOLE_MAX_SHAPE_COUNT, SQUARE_HOLE_MIN_DIFFICULTY,
|
||||||
|
SQUARE_HOLE_MIN_SHAPE_COUNT, SquareHoleCreatorConfig, SquareHoleError, SquareHoleResultDraft,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn validate_shape_count(value: u32) -> Result<u32, SquareHoleError> {
|
||||||
|
if (SQUARE_HOLE_MIN_SHAPE_COUNT..=SQUARE_HOLE_MAX_SHAPE_COUNT).contains(&value) {
|
||||||
|
Ok(value)
|
||||||
|
} else {
|
||||||
|
Err(SquareHoleError::InvalidShapeCount)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn validate_difficulty(value: u32) -> Result<u32, SquareHoleError> {
|
||||||
|
if (SQUARE_HOLE_MIN_DIFFICULTY..=SQUARE_HOLE_MAX_DIFFICULTY).contains(&value) {
|
||||||
|
Ok(value)
|
||||||
|
} else {
|
||||||
|
Err(SquareHoleError::InvalidDifficulty)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn normalize_theme_text(value: impl AsRef<str>) -> Result<String, SquareHoleError> {
|
||||||
|
normalize_required_string(value).ok_or(SquareHoleError::MissingText)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build_creator_config(
|
||||||
|
theme_text: &str,
|
||||||
|
twist_rule: &str,
|
||||||
|
shape_count: u32,
|
||||||
|
difficulty: u32,
|
||||||
|
) -> Result<SquareHoleCreatorConfig, SquareHoleError> {
|
||||||
|
Ok(SquareHoleCreatorConfig {
|
||||||
|
theme_text: normalize_theme_text(theme_text)?,
|
||||||
|
twist_rule: normalize_required_string(twist_rule).ok_or(SquareHoleError::MissingText)?,
|
||||||
|
shape_count: validate_shape_count(shape_count)?,
|
||||||
|
difficulty: validate_difficulty(difficulty)?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build_default_tags(theme_text: &str) -> Vec<String> {
|
||||||
|
normalize_string_list(vec![
|
||||||
|
"方洞挑战".to_string(),
|
||||||
|
theme_text.to_string(),
|
||||||
|
"反直觉".to_string(),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn default_tags_for_theme(theme_text: &str) -> Vec<String> {
|
||||||
|
let mut tags = vec![
|
||||||
|
"方洞挑战".to_string(),
|
||||||
|
"反直觉".to_string(),
|
||||||
|
theme_text.to_string(),
|
||||||
|
];
|
||||||
|
tags.sort();
|
||||||
|
tags.dedup();
|
||||||
|
tags
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn validate_publish_requirements(draft: &SquareHoleResultDraft) -> Vec<String> {
|
||||||
|
let mut blockers = Vec::new();
|
||||||
|
if normalize_required_string(&draft.game_name).is_none() {
|
||||||
|
blockers.push("游戏名称不能为空".to_string());
|
||||||
|
}
|
||||||
|
if normalize_required_string(&draft.summary).is_none() {
|
||||||
|
blockers.push("简介不能为空".to_string());
|
||||||
|
}
|
||||||
|
if normalize_required_string(&draft.theme_text).is_none() {
|
||||||
|
blockers.push("题材不能为空".to_string());
|
||||||
|
}
|
||||||
|
if normalize_required_string(&draft.twist_rule).is_none() {
|
||||||
|
blockers.push("反直觉规则不能为空".to_string());
|
||||||
|
}
|
||||||
|
if normalize_string_list(draft.tags.clone()).is_empty() {
|
||||||
|
blockers.push("至少需要 1 个标签".to_string());
|
||||||
|
}
|
||||||
|
if validate_shape_count(draft.shape_count).is_err() {
|
||||||
|
blockers.push(format!(
|
||||||
|
"形状数量必须在 {} 到 {} 之间",
|
||||||
|
SQUARE_HOLE_MIN_SHAPE_COUNT, SQUARE_HOLE_MAX_SHAPE_COUNT
|
||||||
|
));
|
||||||
|
}
|
||||||
|
if validate_difficulty(draft.difficulty).is_err() {
|
||||||
|
blockers.push("难度必须在 1 到 10 之间".to_string());
|
||||||
|
}
|
||||||
|
blockers
|
||||||
|
}
|
||||||
|
|
||||||
|
#[deprecated(note = "请使用 compile_result_draft(profile_id, &config)")]
|
||||||
|
pub fn build_result_draft(
|
||||||
|
profile_id: String,
|
||||||
|
theme_text: String,
|
||||||
|
twist_rule: String,
|
||||||
|
shape_count: u32,
|
||||||
|
difficulty: u32,
|
||||||
|
) -> SquareHoleResultDraft {
|
||||||
|
let game_name = format!("{theme_text}方洞挑战");
|
||||||
|
let summary = format!(
|
||||||
|
"{theme_text}主题,{} 个形状,难度 {},规则:{twist_rule}",
|
||||||
|
shape_count, difficulty
|
||||||
|
);
|
||||||
|
let blockers = Vec::new();
|
||||||
|
SquareHoleResultDraft {
|
||||||
|
profile_id,
|
||||||
|
game_name,
|
||||||
|
theme_text,
|
||||||
|
twist_rule,
|
||||||
|
summary,
|
||||||
|
tags: build_default_tags("方洞挑战"),
|
||||||
|
shape_count,
|
||||||
|
difficulty,
|
||||||
|
publish_ready: true,
|
||||||
|
blockers,
|
||||||
|
}
|
||||||
|
}
|
||||||
204
server-rs/crates/module-square-hole/src/domain.rs
Normal file
204
server-rs/crates/module-square-hole/src/domain.rs
Normal file
@@ -0,0 +1,204 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
#[cfg(feature = "spacetime-types")]
|
||||||
|
use spacetimedb::SpacetimeType;
|
||||||
|
|
||||||
|
pub const SQUARE_HOLE_SESSION_ID_PREFIX: &str = "square-hole-session-";
|
||||||
|
pub const SQUARE_HOLE_MESSAGE_ID_PREFIX: &str = "square-hole-message-";
|
||||||
|
pub const SQUARE_HOLE_PROFILE_ID_PREFIX: &str = "square-hole-profile-";
|
||||||
|
pub const SQUARE_HOLE_WORK_ID_PREFIX: &str = "square-hole-work-";
|
||||||
|
pub const SQUARE_HOLE_RUN_ID_PREFIX: &str = "square-hole-run-";
|
||||||
|
pub const SQUARE_HOLE_MIN_SHAPE_COUNT: u32 = 6;
|
||||||
|
pub const SQUARE_HOLE_MAX_SHAPE_COUNT: u32 = 24;
|
||||||
|
pub const SQUARE_HOLE_MIN_DIFFICULTY: u32 = 1;
|
||||||
|
pub const SQUARE_HOLE_MAX_DIFFICULTY: u32 = 10;
|
||||||
|
pub const SQUARE_HOLE_DEFAULT_DURATION_LIMIT_MS: u64 = 60_000;
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub enum SquareHoleCreationStage {
|
||||||
|
CollectingConfig,
|
||||||
|
DraftReady,
|
||||||
|
ReadyToPublish,
|
||||||
|
Published,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub enum SquareHolePublicationStatus {
|
||||||
|
Draft,
|
||||||
|
Published,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub enum SquareHoleRunStatus {
|
||||||
|
Running,
|
||||||
|
Won,
|
||||||
|
Failed,
|
||||||
|
Stopped,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub enum SquareHoleDropRejectReason {
|
||||||
|
RunNotActive,
|
||||||
|
SnapshotVersionMismatch,
|
||||||
|
HoleNotFound,
|
||||||
|
Incompatible,
|
||||||
|
TimeUp,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct SquareHoleCreatorConfig {
|
||||||
|
pub theme_text: String,
|
||||||
|
pub twist_rule: String,
|
||||||
|
pub shape_count: u32,
|
||||||
|
pub difficulty: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct SquareHoleResultDraft {
|
||||||
|
pub profile_id: String,
|
||||||
|
pub game_name: String,
|
||||||
|
pub theme_text: String,
|
||||||
|
pub twist_rule: String,
|
||||||
|
pub summary: String,
|
||||||
|
pub tags: Vec<String>,
|
||||||
|
pub shape_count: u32,
|
||||||
|
pub difficulty: u32,
|
||||||
|
pub publish_ready: bool,
|
||||||
|
pub blockers: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct SquareHoleWorkProfile {
|
||||||
|
pub work_id: String,
|
||||||
|
pub profile_id: String,
|
||||||
|
pub owner_user_id: String,
|
||||||
|
pub source_session_id: Option<String>,
|
||||||
|
pub game_name: String,
|
||||||
|
pub theme_text: String,
|
||||||
|
pub twist_rule: String,
|
||||||
|
pub summary: String,
|
||||||
|
pub tags: Vec<String>,
|
||||||
|
pub cover_image_src: Option<String>,
|
||||||
|
pub shape_count: u32,
|
||||||
|
pub difficulty: u32,
|
||||||
|
pub publication_status: SquareHolePublicationStatus,
|
||||||
|
pub play_count: u32,
|
||||||
|
pub updated_at_micros: i64,
|
||||||
|
pub published_at_micros: Option<i64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct SquareHoleShapeSnapshot {
|
||||||
|
pub shape_id: String,
|
||||||
|
pub shape_kind: String,
|
||||||
|
pub label: String,
|
||||||
|
pub color: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
||||||
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct SquareHoleHoleSnapshot {
|
||||||
|
pub hole_id: String,
|
||||||
|
pub hole_kind: String,
|
||||||
|
pub label: String,
|
||||||
|
pub x: f32,
|
||||||
|
pub y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct SquareHoleDropFeedback {
|
||||||
|
pub accepted: bool,
|
||||||
|
pub reject_reason: Option<SquareHoleDropRejectReason>,
|
||||||
|
pub message: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
||||||
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct SquareHoleRunSnapshot {
|
||||||
|
pub run_id: String,
|
||||||
|
pub profile_id: String,
|
||||||
|
pub owner_user_id: String,
|
||||||
|
pub status: SquareHoleRunStatus,
|
||||||
|
pub snapshot_version: u64,
|
||||||
|
pub started_at_ms: u64,
|
||||||
|
pub duration_limit_ms: u64,
|
||||||
|
pub remaining_ms: u64,
|
||||||
|
pub total_shape_count: u32,
|
||||||
|
pub completed_shape_count: u32,
|
||||||
|
pub combo: u32,
|
||||||
|
pub best_combo: u32,
|
||||||
|
pub score: u32,
|
||||||
|
pub rule_label: String,
|
||||||
|
pub current_shape: Option<SquareHoleShapeSnapshot>,
|
||||||
|
pub holes: Vec<SquareHoleHoleSnapshot>,
|
||||||
|
pub last_feedback: Option<SquareHoleDropFeedback>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct SquareHoleDropInput {
|
||||||
|
pub run_id: String,
|
||||||
|
pub owner_user_id: String,
|
||||||
|
pub hole_id: String,
|
||||||
|
pub client_snapshot_version: u64,
|
||||||
|
pub client_event_id: String,
|
||||||
|
pub dropped_at_ms: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
||||||
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct SquareHoleDropConfirmation {
|
||||||
|
pub feedback: SquareHoleDropFeedback,
|
||||||
|
pub run: SquareHoleRunSnapshot,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SquareHoleCreationStage {
|
||||||
|
pub fn as_str(self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
Self::CollectingConfig => "collecting_config",
|
||||||
|
Self::DraftReady => "draft_ready",
|
||||||
|
Self::ReadyToPublish => "ready_to_publish",
|
||||||
|
Self::Published => "published",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SquareHolePublicationStatus {
|
||||||
|
pub fn as_str(self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
Self::Draft => "draft",
|
||||||
|
Self::Published => "published",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SquareHoleRunStatus {
|
||||||
|
pub fn as_str(self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
Self::Running => "running",
|
||||||
|
Self::Won => "won",
|
||||||
|
Self::Failed => "failed",
|
||||||
|
Self::Stopped => "stopped",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SquareHoleDropRejectReason {
|
||||||
|
pub fn as_str(self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
Self::RunNotActive => "run_not_active",
|
||||||
|
Self::SnapshotVersionMismatch => "snapshot_version_mismatch",
|
||||||
|
Self::HoleNotFound => "hole_not_found",
|
||||||
|
Self::Incompatible => "incompatible",
|
||||||
|
Self::TimeUp => "time_up",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
37
server-rs/crates/module-square-hole/src/errors.rs
Normal file
37
server-rs/crates/module-square-hole/src/errors.rs
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
use std::fmt::{self, Display};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub enum SquareHoleError {
|
||||||
|
MissingText,
|
||||||
|
MissingOwnerUserId,
|
||||||
|
InvalidShapeCount,
|
||||||
|
InvalidDifficulty,
|
||||||
|
MissingProfileId,
|
||||||
|
MissingRunId,
|
||||||
|
MissingHoleId,
|
||||||
|
RunNotActive,
|
||||||
|
SnapshotVersionMismatch,
|
||||||
|
HoleNotFound,
|
||||||
|
Incompatible,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for SquareHoleError {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
let message = match self {
|
||||||
|
Self::MissingText => "文本不能为空",
|
||||||
|
Self::MissingOwnerUserId => "owner_user_id 缺失",
|
||||||
|
Self::InvalidShapeCount => "形状数量必须在 6 到 24 之间",
|
||||||
|
Self::InvalidDifficulty => "难度必须在 1 到 10 之间",
|
||||||
|
Self::MissingProfileId => "缺少 profileId",
|
||||||
|
Self::MissingRunId => "缺少 runId",
|
||||||
|
Self::MissingHoleId => "缺少 holeId",
|
||||||
|
Self::RunNotActive => "当前运行态未激活",
|
||||||
|
Self::SnapshotVersionMismatch => "快照版本不一致",
|
||||||
|
Self::HoleNotFound => "洞口不存在",
|
||||||
|
Self::Incompatible => "当前形状不能投入这个洞口",
|
||||||
|
};
|
||||||
|
write!(f, "{message}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::error::Error for SquareHoleError {}
|
||||||
25
server-rs/crates/module-square-hole/src/events.rs
Normal file
25
server-rs/crates/module-square-hole/src/events.rs
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
//! 方洞挑战领域事件。
|
||||||
|
//!
|
||||||
|
//! 事件只表达已经发生的领域事实,是否持久化、投影或通知前端由
|
||||||
|
//! SpacetimeDB adapter 与 BFF 编排层决定。
|
||||||
|
|
||||||
|
/// 方洞挑战领域事件。
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub enum SquareHoleDomainEvent {
|
||||||
|
DraftCompiled {
|
||||||
|
profile_id: String,
|
||||||
|
owner_user_id: String,
|
||||||
|
occurred_at_micros: i64,
|
||||||
|
},
|
||||||
|
WorkPublished {
|
||||||
|
profile_id: String,
|
||||||
|
owner_user_id: String,
|
||||||
|
occurred_at_micros: i64,
|
||||||
|
},
|
||||||
|
RunSettled {
|
||||||
|
run_id: String,
|
||||||
|
owner_user_id: String,
|
||||||
|
status: String,
|
||||||
|
occurred_at_micros: i64,
|
||||||
|
},
|
||||||
|
}
|
||||||
11
server-rs/crates/module-square-hole/src/lib.rs
Normal file
11
server-rs/crates/module-square-hole/src/lib.rs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
mod application;
|
||||||
|
mod commands;
|
||||||
|
mod domain;
|
||||||
|
mod errors;
|
||||||
|
mod events;
|
||||||
|
|
||||||
|
pub use application::*;
|
||||||
|
pub use commands::*;
|
||||||
|
pub use domain::*;
|
||||||
|
pub use errors::*;
|
||||||
|
pub use events::*;
|
||||||
@@ -16,4 +16,7 @@ pub mod puzzle_runtime;
|
|||||||
pub mod puzzle_works;
|
pub mod puzzle_works;
|
||||||
pub mod runtime;
|
pub mod runtime;
|
||||||
pub mod runtime_story;
|
pub mod runtime_story;
|
||||||
|
pub mod square_hole_agent;
|
||||||
|
pub mod square_hole_runtime;
|
||||||
|
pub mod square_hole_works;
|
||||||
pub mod story;
|
pub mod story;
|
||||||
|
|||||||
122
server-rs/crates/shared-contracts/src/square_hole_agent.rs
Normal file
122
server-rs/crates/shared-contracts/src/square_hole_agent.rs
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CreateSquareHoleSessionRequest {
|
||||||
|
#[serde(default)]
|
||||||
|
pub seed_text: Option<String>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub theme_text: Option<String>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub twist_rule: Option<String>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub shape_count: Option<u32>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub difficulty: Option<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct SendSquareHoleMessageRequest {
|
||||||
|
pub client_message_id: String,
|
||||||
|
pub text: String,
|
||||||
|
#[serde(default)]
|
||||||
|
pub quick_fill_requested: Option<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct ExecuteSquareHoleActionRequest {
|
||||||
|
pub action: String,
|
||||||
|
#[serde(default)]
|
||||||
|
pub game_name: Option<String>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub summary: Option<String>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub tags: Option<Vec<String>>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub cover_image_src: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct SquareHoleAnchorItemResponse {
|
||||||
|
pub key: String,
|
||||||
|
pub label: String,
|
||||||
|
pub value: String,
|
||||||
|
pub status: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct SquareHoleAnchorPackResponse {
|
||||||
|
pub theme: SquareHoleAnchorItemResponse,
|
||||||
|
pub twist_rule: SquareHoleAnchorItemResponse,
|
||||||
|
pub shape_count: SquareHoleAnchorItemResponse,
|
||||||
|
pub difficulty: SquareHoleAnchorItemResponse,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct SquareHoleCreatorConfigResponse {
|
||||||
|
pub theme_text: String,
|
||||||
|
pub twist_rule: String,
|
||||||
|
pub shape_count: u32,
|
||||||
|
pub difficulty: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct SquareHoleResultDraftResponse {
|
||||||
|
pub profile_id: String,
|
||||||
|
pub game_name: String,
|
||||||
|
pub theme_text: String,
|
||||||
|
pub twist_rule: String,
|
||||||
|
pub summary: String,
|
||||||
|
pub tags: Vec<String>,
|
||||||
|
pub shape_count: u32,
|
||||||
|
pub difficulty: u32,
|
||||||
|
pub publish_ready: bool,
|
||||||
|
pub blockers: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct SquareHoleAgentMessageResponse {
|
||||||
|
pub id: String,
|
||||||
|
pub role: String,
|
||||||
|
pub kind: String,
|
||||||
|
pub text: String,
|
||||||
|
pub created_at: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct SquareHoleSessionSnapshotResponse {
|
||||||
|
pub session_id: String,
|
||||||
|
pub current_turn: u32,
|
||||||
|
pub progress_percent: u32,
|
||||||
|
pub stage: String,
|
||||||
|
pub anchor_pack: SquareHoleAnchorPackResponse,
|
||||||
|
pub config: SquareHoleCreatorConfigResponse,
|
||||||
|
#[serde(default)]
|
||||||
|
pub draft: Option<SquareHoleResultDraftResponse>,
|
||||||
|
pub messages: Vec<SquareHoleAgentMessageResponse>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub last_assistant_reply: Option<String>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub published_profile_id: Option<String>,
|
||||||
|
pub updated_at: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct SquareHoleSessionResponse {
|
||||||
|
pub session: SquareHoleSessionSnapshotResponse,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct SquareHoleActionResponse {
|
||||||
|
pub session: SquareHoleSessionSnapshotResponse,
|
||||||
|
}
|
||||||
89
server-rs/crates/shared-contracts/src/square_hole_runtime.rs
Normal file
89
server-rs/crates/shared-contracts/src/square_hole_runtime.rs
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct StartSquareHoleRunRequest {
|
||||||
|
pub profile_id: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct DropSquareHoleShapeRequest {
|
||||||
|
#[serde(default)]
|
||||||
|
pub run_id: Option<String>,
|
||||||
|
pub hole_id: String,
|
||||||
|
pub client_snapshot_version: u64,
|
||||||
|
pub client_event_id: String,
|
||||||
|
pub dropped_at_ms: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct StopSquareHoleRunRequest {
|
||||||
|
pub client_action_id: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct SquareHoleShapeSnapshotResponse {
|
||||||
|
pub shape_id: String,
|
||||||
|
pub shape_kind: String,
|
||||||
|
pub label: String,
|
||||||
|
pub color: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct SquareHoleHoleSnapshotResponse {
|
||||||
|
pub hole_id: String,
|
||||||
|
pub hole_kind: String,
|
||||||
|
pub label: String,
|
||||||
|
pub x: f32,
|
||||||
|
pub y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct SquareHoleDropFeedbackResponse {
|
||||||
|
pub accepted: bool,
|
||||||
|
#[serde(default)]
|
||||||
|
pub reject_reason: Option<String>,
|
||||||
|
pub message: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct SquareHoleRunSnapshotResponse {
|
||||||
|
pub run_id: String,
|
||||||
|
pub profile_id: String,
|
||||||
|
pub owner_user_id: String,
|
||||||
|
pub status: String,
|
||||||
|
pub snapshot_version: u64,
|
||||||
|
pub started_at_ms: u64,
|
||||||
|
pub duration_limit_ms: u64,
|
||||||
|
pub remaining_ms: u64,
|
||||||
|
pub total_shape_count: u32,
|
||||||
|
pub completed_shape_count: u32,
|
||||||
|
pub combo: u32,
|
||||||
|
pub best_combo: u32,
|
||||||
|
pub score: u32,
|
||||||
|
pub rule_label: String,
|
||||||
|
#[serde(default)]
|
||||||
|
pub current_shape: Option<SquareHoleShapeSnapshotResponse>,
|
||||||
|
pub holes: Vec<SquareHoleHoleSnapshotResponse>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub last_feedback: Option<SquareHoleDropFeedbackResponse>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct SquareHoleRunResponse {
|
||||||
|
pub run: SquareHoleRunSnapshotResponse,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct SquareHoleDropResponse {
|
||||||
|
pub feedback: SquareHoleDropFeedbackResponse,
|
||||||
|
pub run: SquareHoleRunSnapshotResponse,
|
||||||
|
}
|
||||||
66
server-rs/crates/shared-contracts/src/square_hole_works.rs
Normal file
66
server-rs/crates/shared-contracts/src/square_hole_works.rs
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct PutSquareHoleWorkRequest {
|
||||||
|
pub game_name: String,
|
||||||
|
#[serde(default)]
|
||||||
|
pub theme_text: Option<String>,
|
||||||
|
pub twist_rule: String,
|
||||||
|
pub summary: String,
|
||||||
|
pub tags: Vec<String>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub cover_image_src: Option<String>,
|
||||||
|
pub shape_count: u32,
|
||||||
|
pub difficulty: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct SquareHoleWorkSummaryResponse {
|
||||||
|
pub work_id: String,
|
||||||
|
pub profile_id: String,
|
||||||
|
pub owner_user_id: String,
|
||||||
|
#[serde(default)]
|
||||||
|
pub source_session_id: Option<String>,
|
||||||
|
pub game_name: String,
|
||||||
|
pub theme_text: String,
|
||||||
|
pub twist_rule: String,
|
||||||
|
pub summary: String,
|
||||||
|
pub tags: Vec<String>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub cover_image_src: Option<String>,
|
||||||
|
pub shape_count: u32,
|
||||||
|
pub difficulty: u32,
|
||||||
|
pub publication_status: String,
|
||||||
|
pub play_count: u32,
|
||||||
|
pub updated_at: String,
|
||||||
|
#[serde(default)]
|
||||||
|
pub published_at: Option<String>,
|
||||||
|
pub publish_ready: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct SquareHoleWorkProfileResponse {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub summary: SquareHoleWorkSummaryResponse,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct SquareHoleWorksResponse {
|
||||||
|
pub items: Vec<SquareHoleWorkSummaryResponse>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct SquareHoleWorkDetailResponse {
|
||||||
|
pub item: SquareHoleWorkProfileResponse,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct SquareHoleWorkMutationResponse {
|
||||||
|
pub item: SquareHoleWorkProfileResponse,
|
||||||
|
}
|
||||||
@@ -17,6 +17,7 @@ module-puzzle = { path = "../module-puzzle" }
|
|||||||
module-runtime = { path = "../module-runtime" }
|
module-runtime = { path = "../module-runtime" }
|
||||||
module-runtime-story = { path = "../module-runtime-story" }
|
module-runtime-story = { path = "../module-runtime-story" }
|
||||||
module-runtime-item = { path = "../module-runtime-item" }
|
module-runtime-item = { path = "../module-runtime-item" }
|
||||||
|
module-square-hole = { path = "../module-square-hole" }
|
||||||
module-story = { path = "../module-story" }
|
module-story = { path = "../module-story" }
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
|
|||||||
@@ -51,6 +51,15 @@ pub use mapper::{
|
|||||||
PuzzleSelectCoverImageRecordInput, PuzzleWorkLikeReportRecordInput,
|
PuzzleSelectCoverImageRecordInput, PuzzleWorkLikeReportRecordInput,
|
||||||
PuzzleWorkPointIncentiveClaimRecordInput, PuzzleWorkProfileRecord, PuzzleWorkRemixRecordInput,
|
PuzzleWorkPointIncentiveClaimRecordInput, PuzzleWorkProfileRecord, PuzzleWorkRemixRecordInput,
|
||||||
PuzzleWorkUpsertRecordInput, ResolveCombatActionRecord, ResolveNpcBattleInteractionInput,
|
PuzzleWorkUpsertRecordInput, ResolveCombatActionRecord, ResolveNpcBattleInteractionInput,
|
||||||
|
SquareHoleAgentMessageFinalizeRecordInput, SquareHoleAgentMessageRecord,
|
||||||
|
SquareHoleAgentMessageSubmitRecordInput, SquareHoleAgentSessionCreateRecordInput,
|
||||||
|
SquareHoleAgentSessionRecord, SquareHoleAnchorItemRecord, SquareHoleAnchorPackRecord,
|
||||||
|
SquareHoleCompileDraftRecordInput, SquareHoleCreatorConfigRecord,
|
||||||
|
SquareHoleDropConfirmationRecord, SquareHoleDropFeedbackRecord, SquareHoleHoleSnapshotRecord,
|
||||||
|
SquareHoleResultDraftRecord, SquareHoleRunDropRecordInput, SquareHoleRunRecord,
|
||||||
|
SquareHoleRunRestartRecordInput, SquareHoleRunStartRecordInput, SquareHoleRunStopRecordInput,
|
||||||
|
SquareHoleRunTimeUpRecordInput, SquareHoleShapeSnapshotRecord, SquareHoleWorkProfileRecord,
|
||||||
|
SquareHoleWorkUpdateRecordInput,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod ai;
|
pub mod ai;
|
||||||
@@ -64,6 +73,7 @@ pub mod match3d;
|
|||||||
pub mod npc;
|
pub mod npc;
|
||||||
pub mod puzzle;
|
pub mod puzzle;
|
||||||
pub mod runtime;
|
pub mod runtime;
|
||||||
|
pub mod square_hole;
|
||||||
pub mod story;
|
pub mod story;
|
||||||
pub mod story_runtime;
|
pub mod story_runtime;
|
||||||
|
|
||||||
|
|||||||
@@ -1575,6 +1575,110 @@ pub(crate) fn map_match3d_click_item_procedure_result(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn map_square_hole_agent_session_procedure_result(
|
||||||
|
result: SquareHoleAgentSessionProcedureResult,
|
||||||
|
) -> Result<SquareHoleAgentSessionRecord, SpacetimeClientError> {
|
||||||
|
if !result.ok {
|
||||||
|
return Err(SpacetimeClientError::procedure_failed(result.error_message));
|
||||||
|
}
|
||||||
|
|
||||||
|
let session_json = result
|
||||||
|
.session_json
|
||||||
|
.ok_or_else(|| SpacetimeClientError::missing_snapshot("square hole agent session 快照"))?;
|
||||||
|
let session =
|
||||||
|
serde_json::from_str::<SquareHoleAgentSessionJsonRecord>(&session_json).map_err(
|
||||||
|
|error| {
|
||||||
|
SpacetimeClientError::Runtime(format!(
|
||||||
|
"square hole session_json 非法: {error}"
|
||||||
|
))
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(map_square_hole_agent_session_snapshot(session))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn map_square_hole_work_procedure_result(
|
||||||
|
result: SquareHoleWorkProcedureResult,
|
||||||
|
) -> Result<SquareHoleWorkProfileRecord, SpacetimeClientError> {
|
||||||
|
if !result.ok {
|
||||||
|
return Err(SpacetimeClientError::procedure_failed(result.error_message));
|
||||||
|
}
|
||||||
|
|
||||||
|
let work_json = result
|
||||||
|
.work_json
|
||||||
|
.ok_or_else(|| SpacetimeClientError::missing_snapshot("square hole work 快照"))?;
|
||||||
|
let work = serde_json::from_str::<SquareHoleWorkJsonRecord>(&work_json).map_err(|error| {
|
||||||
|
SpacetimeClientError::Runtime(format!("square hole work_json 非法: {error}"))
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(map_square_hole_work_snapshot(work))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn map_square_hole_works_procedure_result(
|
||||||
|
result: SquareHoleWorksProcedureResult,
|
||||||
|
) -> Result<Vec<SquareHoleWorkProfileRecord>, SpacetimeClientError> {
|
||||||
|
if !result.ok {
|
||||||
|
return Err(SpacetimeClientError::procedure_failed(result.error_message));
|
||||||
|
}
|
||||||
|
|
||||||
|
let items_json = result
|
||||||
|
.items_json
|
||||||
|
.ok_or_else(|| SpacetimeClientError::missing_snapshot("square hole works 快照"))?;
|
||||||
|
let items = serde_json::from_str::<Vec<SquareHoleWorkJsonRecord>>(&items_json).map_err(
|
||||||
|
|error| {
|
||||||
|
SpacetimeClientError::Runtime(format!("square hole works items_json 非法: {error}"))
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(items.into_iter().map(map_square_hole_work_snapshot).collect())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn map_square_hole_run_procedure_result(
|
||||||
|
result: SquareHoleRunProcedureResult,
|
||||||
|
) -> Result<SquareHoleRunRecord, SpacetimeClientError> {
|
||||||
|
if !result.ok {
|
||||||
|
return Err(SpacetimeClientError::procedure_failed(result.error_message));
|
||||||
|
}
|
||||||
|
|
||||||
|
let run_json = result
|
||||||
|
.run_json
|
||||||
|
.ok_or_else(|| SpacetimeClientError::missing_snapshot("square hole run 快照"))?;
|
||||||
|
map_square_hole_run_json(run_json)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn map_square_hole_drop_shape_procedure_result(
|
||||||
|
result: SquareHoleDropShapeProcedureResult,
|
||||||
|
) -> Result<SquareHoleDropConfirmationRecord, SpacetimeClientError> {
|
||||||
|
if !result.ok {
|
||||||
|
return Err(SpacetimeClientError::procedure_failed(result.error_message));
|
||||||
|
}
|
||||||
|
|
||||||
|
let run_json = result
|
||||||
|
.run_json
|
||||||
|
.ok_or_else(|| SpacetimeClientError::missing_snapshot("square hole drop run 快照"))?;
|
||||||
|
let feedback_json = result.feedback_json.ok_or_else(|| {
|
||||||
|
SpacetimeClientError::missing_snapshot("square hole drop feedback 快照")
|
||||||
|
})?;
|
||||||
|
let run = map_square_hole_run_json(run_json)?;
|
||||||
|
let feedback =
|
||||||
|
serde_json::from_str::<SquareHoleDropFeedbackJsonRecord>(&feedback_json).map_err(
|
||||||
|
|error| {
|
||||||
|
SpacetimeClientError::Runtime(format!(
|
||||||
|
"square hole feedback_json 非法: {error}"
|
||||||
|
))
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(SquareHoleDropConfirmationRecord {
|
||||||
|
status: result.status,
|
||||||
|
accepted: feedback.accepted,
|
||||||
|
reject_reason: feedback.reject_reason.clone(),
|
||||||
|
failure_reason: result.failure_reason,
|
||||||
|
feedback: map_square_hole_feedback_snapshot(feedback),
|
||||||
|
run,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn map_story_session_procedure_result(
|
pub(crate) fn map_story_session_procedure_result(
|
||||||
result: StorySessionProcedureResult,
|
result: StorySessionProcedureResult,
|
||||||
) -> Result<StorySessionResultRecord, SpacetimeClientError> {
|
) -> Result<StorySessionResultRecord, SpacetimeClientError> {
|
||||||
@@ -2815,6 +2919,198 @@ fn build_match3d_anchor_item(key: &str, label: &str, value: &str) -> Match3DAnch
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn map_square_hole_agent_session_snapshot(
|
||||||
|
snapshot: SquareHoleAgentSessionJsonRecord,
|
||||||
|
) -> SquareHoleAgentSessionRecord {
|
||||||
|
let config = map_square_hole_creator_config(snapshot.config);
|
||||||
|
SquareHoleAgentSessionRecord {
|
||||||
|
session_id: snapshot.session_id,
|
||||||
|
current_turn: snapshot.current_turn,
|
||||||
|
progress_percent: snapshot.progress_percent,
|
||||||
|
stage: normalize_square_hole_stage(&snapshot.stage).to_string(),
|
||||||
|
anchor_pack: build_square_hole_anchor_pack(&config),
|
||||||
|
config,
|
||||||
|
draft: snapshot.draft.map(map_square_hole_result_draft),
|
||||||
|
messages: snapshot
|
||||||
|
.messages
|
||||||
|
.into_iter()
|
||||||
|
.map(map_square_hole_agent_message_snapshot)
|
||||||
|
.collect(),
|
||||||
|
last_assistant_reply: empty_string_to_none(snapshot.last_assistant_reply),
|
||||||
|
published_profile_id: snapshot.published_profile_id,
|
||||||
|
updated_at: format_timestamp_micros(snapshot.updated_at_micros),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn map_square_hole_creator_config(
|
||||||
|
snapshot: SquareHoleCreatorConfigJsonRecord,
|
||||||
|
) -> SquareHoleCreatorConfigRecord {
|
||||||
|
SquareHoleCreatorConfigRecord {
|
||||||
|
theme_text: snapshot.theme_text,
|
||||||
|
twist_rule: snapshot.twist_rule,
|
||||||
|
shape_count: snapshot.shape_count,
|
||||||
|
difficulty: snapshot.difficulty,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn map_square_hole_result_draft(
|
||||||
|
snapshot: SquareHoleDraftJsonRecord,
|
||||||
|
) -> SquareHoleResultDraftRecord {
|
||||||
|
SquareHoleResultDraftRecord {
|
||||||
|
profile_id: snapshot.profile_id,
|
||||||
|
game_name: snapshot.game_name,
|
||||||
|
theme_text: snapshot.theme_text,
|
||||||
|
twist_rule: snapshot.twist_rule,
|
||||||
|
summary: snapshot.summary_text,
|
||||||
|
tags: snapshot.tags,
|
||||||
|
shape_count: snapshot.shape_count,
|
||||||
|
difficulty: snapshot.difficulty,
|
||||||
|
publish_ready: false,
|
||||||
|
blockers: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn map_square_hole_agent_message_snapshot(
|
||||||
|
snapshot: SquareHoleAgentMessageJsonRecord,
|
||||||
|
) -> SquareHoleAgentMessageRecord {
|
||||||
|
SquareHoleAgentMessageRecord {
|
||||||
|
id: snapshot.message_id,
|
||||||
|
role: snapshot.role,
|
||||||
|
kind: normalize_square_hole_message_kind(&snapshot.kind).to_string(),
|
||||||
|
text: snapshot.text,
|
||||||
|
created_at: format_timestamp_micros(snapshot.created_at_micros),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn map_square_hole_work_snapshot(
|
||||||
|
snapshot: SquareHoleWorkJsonRecord,
|
||||||
|
) -> SquareHoleWorkProfileRecord {
|
||||||
|
SquareHoleWorkProfileRecord {
|
||||||
|
work_id: snapshot.work_id,
|
||||||
|
profile_id: snapshot.profile_id,
|
||||||
|
owner_user_id: snapshot.owner_user_id,
|
||||||
|
source_session_id: empty_string_to_none(snapshot.source_session_id),
|
||||||
|
author_display_name: snapshot.author_display_name,
|
||||||
|
game_name: snapshot.game_name,
|
||||||
|
theme_text: snapshot.theme_text,
|
||||||
|
twist_rule: snapshot.twist_rule,
|
||||||
|
summary: snapshot.summary_text,
|
||||||
|
tags: snapshot.tags,
|
||||||
|
cover_image_src: empty_string_to_none(snapshot.cover_image_src),
|
||||||
|
shape_count: snapshot.shape_count,
|
||||||
|
difficulty: snapshot.difficulty,
|
||||||
|
publication_status: normalize_square_hole_publication_status(&snapshot.publication_status)
|
||||||
|
.to_string(),
|
||||||
|
play_count: snapshot.play_count,
|
||||||
|
updated_at: format_timestamp_micros(snapshot.updated_at_micros),
|
||||||
|
published_at: snapshot.published_at_micros.map(format_timestamp_micros),
|
||||||
|
publish_ready: snapshot.publish_ready,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn map_square_hole_run_json(run_json: String) -> Result<SquareHoleRunRecord, SpacetimeClientError> {
|
||||||
|
let run = serde_json::from_str::<SquareHoleRunJsonRecord>(&run_json).map_err(|error| {
|
||||||
|
SpacetimeClientError::Runtime(format!("square hole run_json 非法: {error}"))
|
||||||
|
})?;
|
||||||
|
Ok(map_square_hole_run_snapshot(run))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn map_square_hole_run_snapshot(snapshot: SquareHoleRunJsonRecord) -> SquareHoleRunRecord {
|
||||||
|
SquareHoleRunRecord {
|
||||||
|
run_id: snapshot.run_id,
|
||||||
|
profile_id: snapshot.profile_id,
|
||||||
|
owner_user_id: snapshot.owner_user_id,
|
||||||
|
status: normalize_square_hole_run_status(&snapshot.status).to_string(),
|
||||||
|
snapshot_version: snapshot.snapshot_version,
|
||||||
|
started_at_ms: i64_to_u64_ms(snapshot.started_at_ms),
|
||||||
|
duration_limit_ms: i64_to_u64_ms(snapshot.duration_limit_ms),
|
||||||
|
server_now_ms: Some(i64_to_u64_ms(snapshot.server_now_ms)),
|
||||||
|
remaining_ms: i64_to_u64_ms(snapshot.remaining_ms),
|
||||||
|
total_shape_count: snapshot.total_shape_count,
|
||||||
|
completed_shape_count: snapshot.completed_shape_count,
|
||||||
|
combo: snapshot.combo,
|
||||||
|
best_combo: snapshot.best_combo,
|
||||||
|
score: snapshot.score,
|
||||||
|
rule_label: snapshot.rule_label,
|
||||||
|
current_shape: snapshot.current_shape.map(map_square_hole_shape_snapshot),
|
||||||
|
holes: snapshot
|
||||||
|
.holes
|
||||||
|
.into_iter()
|
||||||
|
.map(map_square_hole_hole_snapshot)
|
||||||
|
.collect(),
|
||||||
|
last_feedback: snapshot
|
||||||
|
.last_feedback
|
||||||
|
.map(map_square_hole_feedback_snapshot),
|
||||||
|
last_confirmed_action_id: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn map_square_hole_shape_snapshot(
|
||||||
|
snapshot: SquareHoleShapeJsonRecord,
|
||||||
|
) -> SquareHoleShapeSnapshotRecord {
|
||||||
|
SquareHoleShapeSnapshotRecord {
|
||||||
|
shape_id: snapshot.shape_id,
|
||||||
|
shape_kind: snapshot.shape_kind,
|
||||||
|
label: snapshot.label,
|
||||||
|
color: snapshot.color,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn map_square_hole_hole_snapshot(
|
||||||
|
snapshot: SquareHoleHoleJsonRecord,
|
||||||
|
) -> SquareHoleHoleSnapshotRecord {
|
||||||
|
SquareHoleHoleSnapshotRecord {
|
||||||
|
hole_id: snapshot.hole_id,
|
||||||
|
hole_kind: snapshot.hole_kind,
|
||||||
|
label: snapshot.label,
|
||||||
|
x: snapshot.x,
|
||||||
|
y: snapshot.y,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn map_square_hole_feedback_snapshot(
|
||||||
|
snapshot: SquareHoleDropFeedbackJsonRecord,
|
||||||
|
) -> SquareHoleDropFeedbackRecord {
|
||||||
|
SquareHoleDropFeedbackRecord {
|
||||||
|
accepted: snapshot.accepted,
|
||||||
|
reject_reason: snapshot
|
||||||
|
.reject_reason
|
||||||
|
.map(|value| normalize_square_hole_reject_reason(&value).to_string()),
|
||||||
|
message: snapshot.message,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_square_hole_anchor_pack(
|
||||||
|
config: &SquareHoleCreatorConfigRecord,
|
||||||
|
) -> SquareHoleAnchorPackRecord {
|
||||||
|
let shape_count = config.shape_count.to_string();
|
||||||
|
let difficulty = config.difficulty.to_string();
|
||||||
|
SquareHoleAnchorPackRecord {
|
||||||
|
theme: build_square_hole_anchor_item("theme", "题材主题", config.theme_text.as_str()),
|
||||||
|
twist_rule: build_square_hole_anchor_item("twistRule", "反差规则", config.twist_rule.as_str()),
|
||||||
|
shape_count: build_square_hole_anchor_item("shapeCount", "形状数量", shape_count.as_str()),
|
||||||
|
difficulty: build_square_hole_anchor_item("difficulty", "难度", difficulty.as_str()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_square_hole_anchor_item(
|
||||||
|
key: &str,
|
||||||
|
label: &str,
|
||||||
|
value: &str,
|
||||||
|
) -> SquareHoleAnchorItemRecord {
|
||||||
|
SquareHoleAnchorItemRecord {
|
||||||
|
key: key.to_string(),
|
||||||
|
label: label.to_string(),
|
||||||
|
value: value.to_string(),
|
||||||
|
status: if value.trim().is_empty() {
|
||||||
|
"missing"
|
||||||
|
} else {
|
||||||
|
"confirmed"
|
||||||
|
}
|
||||||
|
.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn normalize_match3d_stage(value: &str) -> &str {
|
fn normalize_match3d_stage(value: &str) -> &str {
|
||||||
match value {
|
match value {
|
||||||
"Collecting" | "collecting" | "collecting_config" => "collecting_config",
|
"Collecting" | "collecting" | "collecting_config" => "collecting_config",
|
||||||
@@ -2840,6 +3136,54 @@ fn normalize_match3d_message_kind(value: &str) -> &str {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn normalize_square_hole_stage(value: &str) -> &str {
|
||||||
|
match value {
|
||||||
|
"Collecting" | "CollectingConfig" | "collecting" | "collecting_config" => {
|
||||||
|
"collecting_config"
|
||||||
|
}
|
||||||
|
"ReadyToCompile" | "ready_to_compile" => "ready_to_compile",
|
||||||
|
"DraftCompiled" | "DraftReady" | "draft_compiled" | "draft_ready" => "draft_ready",
|
||||||
|
"Published" | "published" => "published",
|
||||||
|
_ => value,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn normalize_square_hole_publication_status(value: &str) -> &str {
|
||||||
|
match value {
|
||||||
|
"Draft" | "draft" => "draft",
|
||||||
|
"Published" | "published" => "published",
|
||||||
|
_ => value,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn normalize_square_hole_run_status(value: &str) -> &str {
|
||||||
|
match value {
|
||||||
|
"Running" | "running" => "running",
|
||||||
|
"Won" | "won" => "won",
|
||||||
|
"Failed" | "failed" => "failed",
|
||||||
|
"Stopped" | "stopped" => "stopped",
|
||||||
|
_ => value,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn normalize_square_hole_message_kind(value: &str) -> &str {
|
||||||
|
match value {
|
||||||
|
"text" => "chat",
|
||||||
|
_ => value,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn normalize_square_hole_reject_reason(value: &str) -> &str {
|
||||||
|
match value {
|
||||||
|
"RunNotActive" | "run_not_active" => "run_not_active",
|
||||||
|
"SnapshotVersionMismatch" | "snapshot_version_mismatch" => "snapshot_version_mismatch",
|
||||||
|
"HoleNotFound" | "hole_not_found" => "hole_not_found",
|
||||||
|
"Incompatible" | "incompatible" => "incompatible",
|
||||||
|
"TimeUp" | "time_up" => "time_up",
|
||||||
|
_ => value,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn empty_string_to_none(value: String) -> Option<String> {
|
fn empty_string_to_none(value: String) -> Option<String> {
|
||||||
let trimmed = value.trim();
|
let trimmed = value.trim();
|
||||||
if trimmed.is_empty() {
|
if trimmed.is_empty() {
|
||||||
@@ -5592,6 +5936,378 @@ struct Match3DRunJsonRecord {
|
|||||||
failure_reason: Option<String>,
|
failure_reason: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub struct SquareHoleAgentSessionCreateRecordInput {
|
||||||
|
pub session_id: String,
|
||||||
|
pub owner_user_id: String,
|
||||||
|
pub seed_text: String,
|
||||||
|
pub welcome_message_id: String,
|
||||||
|
pub welcome_message_text: String,
|
||||||
|
pub config_json: Option<String>,
|
||||||
|
pub created_at_micros: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub struct SquareHoleAgentMessageSubmitRecordInput {
|
||||||
|
pub session_id: String,
|
||||||
|
pub owner_user_id: String,
|
||||||
|
pub user_message_id: String,
|
||||||
|
pub user_message_text: String,
|
||||||
|
pub submitted_at_micros: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub struct SquareHoleAgentMessageFinalizeRecordInput {
|
||||||
|
pub session_id: String,
|
||||||
|
pub owner_user_id: String,
|
||||||
|
pub assistant_message_id: Option<String>,
|
||||||
|
pub assistant_reply_text: Option<String>,
|
||||||
|
pub config_json: Option<String>,
|
||||||
|
pub progress_percent: u32,
|
||||||
|
pub stage: String,
|
||||||
|
pub updated_at_micros: i64,
|
||||||
|
pub error_message: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub struct SquareHoleCompileDraftRecordInput {
|
||||||
|
pub session_id: String,
|
||||||
|
pub owner_user_id: String,
|
||||||
|
pub profile_id: String,
|
||||||
|
pub author_display_name: String,
|
||||||
|
pub game_name: Option<String>,
|
||||||
|
pub summary_text: Option<String>,
|
||||||
|
pub tags_json: Option<String>,
|
||||||
|
pub cover_image_src: Option<String>,
|
||||||
|
pub compiled_at_micros: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub struct SquareHoleWorkUpdateRecordInput {
|
||||||
|
pub profile_id: String,
|
||||||
|
pub owner_user_id: String,
|
||||||
|
pub game_name: String,
|
||||||
|
pub theme_text: String,
|
||||||
|
pub twist_rule: String,
|
||||||
|
pub summary_text: String,
|
||||||
|
pub tags_json: String,
|
||||||
|
pub cover_image_src: String,
|
||||||
|
pub shape_count: u32,
|
||||||
|
pub difficulty: u32,
|
||||||
|
pub updated_at_micros: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub struct SquareHoleRunStartRecordInput {
|
||||||
|
pub run_id: String,
|
||||||
|
pub owner_user_id: String,
|
||||||
|
pub profile_id: String,
|
||||||
|
pub started_at_ms: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub struct SquareHoleRunDropRecordInput {
|
||||||
|
pub run_id: String,
|
||||||
|
pub owner_user_id: String,
|
||||||
|
pub hole_id: String,
|
||||||
|
pub client_snapshot_version: u64,
|
||||||
|
pub client_event_id: String,
|
||||||
|
pub dropped_at_ms: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub struct SquareHoleRunStopRecordInput {
|
||||||
|
pub run_id: String,
|
||||||
|
pub owner_user_id: String,
|
||||||
|
pub stopped_at_ms: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub struct SquareHoleRunRestartRecordInput {
|
||||||
|
pub source_run_id: String,
|
||||||
|
pub next_run_id: String,
|
||||||
|
pub owner_user_id: String,
|
||||||
|
pub restarted_at_ms: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub struct SquareHoleRunTimeUpRecordInput {
|
||||||
|
pub run_id: String,
|
||||||
|
pub owner_user_id: String,
|
||||||
|
pub finished_at_ms: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub struct SquareHoleAnchorItemRecord {
|
||||||
|
pub key: String,
|
||||||
|
pub label: String,
|
||||||
|
pub value: String,
|
||||||
|
pub status: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub struct SquareHoleAnchorPackRecord {
|
||||||
|
pub theme: SquareHoleAnchorItemRecord,
|
||||||
|
pub twist_rule: SquareHoleAnchorItemRecord,
|
||||||
|
pub shape_count: SquareHoleAnchorItemRecord,
|
||||||
|
pub difficulty: SquareHoleAnchorItemRecord,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub struct SquareHoleCreatorConfigRecord {
|
||||||
|
pub theme_text: String,
|
||||||
|
pub twist_rule: String,
|
||||||
|
pub shape_count: u32,
|
||||||
|
pub difficulty: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub struct SquareHoleResultDraftRecord {
|
||||||
|
pub profile_id: String,
|
||||||
|
pub game_name: String,
|
||||||
|
pub theme_text: String,
|
||||||
|
pub twist_rule: String,
|
||||||
|
pub summary: String,
|
||||||
|
pub tags: Vec<String>,
|
||||||
|
pub shape_count: u32,
|
||||||
|
pub difficulty: u32,
|
||||||
|
pub publish_ready: bool,
|
||||||
|
pub blockers: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub struct SquareHoleAgentMessageRecord {
|
||||||
|
pub id: String,
|
||||||
|
pub role: String,
|
||||||
|
pub kind: String,
|
||||||
|
pub text: String,
|
||||||
|
pub created_at: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub struct SquareHoleAgentSessionRecord {
|
||||||
|
pub session_id: String,
|
||||||
|
pub current_turn: u32,
|
||||||
|
pub progress_percent: u32,
|
||||||
|
pub stage: String,
|
||||||
|
pub anchor_pack: SquareHoleAnchorPackRecord,
|
||||||
|
pub config: SquareHoleCreatorConfigRecord,
|
||||||
|
pub draft: Option<SquareHoleResultDraftRecord>,
|
||||||
|
pub messages: Vec<SquareHoleAgentMessageRecord>,
|
||||||
|
pub last_assistant_reply: Option<String>,
|
||||||
|
pub published_profile_id: Option<String>,
|
||||||
|
pub updated_at: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub struct SquareHoleWorkProfileRecord {
|
||||||
|
pub work_id: String,
|
||||||
|
pub profile_id: String,
|
||||||
|
pub owner_user_id: String,
|
||||||
|
pub source_session_id: Option<String>,
|
||||||
|
pub author_display_name: String,
|
||||||
|
pub game_name: String,
|
||||||
|
pub theme_text: String,
|
||||||
|
pub twist_rule: String,
|
||||||
|
pub summary: String,
|
||||||
|
pub tags: Vec<String>,
|
||||||
|
pub cover_image_src: Option<String>,
|
||||||
|
pub shape_count: u32,
|
||||||
|
pub difficulty: u32,
|
||||||
|
pub publication_status: String,
|
||||||
|
pub play_count: u32,
|
||||||
|
pub updated_at: String,
|
||||||
|
pub published_at: Option<String>,
|
||||||
|
pub publish_ready: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub struct SquareHoleShapeSnapshotRecord {
|
||||||
|
pub shape_id: String,
|
||||||
|
pub shape_kind: String,
|
||||||
|
pub label: String,
|
||||||
|
pub color: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub struct SquareHoleHoleSnapshotRecord {
|
||||||
|
pub hole_id: String,
|
||||||
|
pub hole_kind: String,
|
||||||
|
pub label: String,
|
||||||
|
pub x: f32,
|
||||||
|
pub y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub struct SquareHoleDropFeedbackRecord {
|
||||||
|
pub accepted: bool,
|
||||||
|
pub reject_reason: Option<String>,
|
||||||
|
pub message: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub struct SquareHoleRunRecord {
|
||||||
|
pub run_id: String,
|
||||||
|
pub profile_id: String,
|
||||||
|
pub owner_user_id: String,
|
||||||
|
pub status: String,
|
||||||
|
pub snapshot_version: u64,
|
||||||
|
pub started_at_ms: u64,
|
||||||
|
pub duration_limit_ms: u64,
|
||||||
|
pub server_now_ms: Option<u64>,
|
||||||
|
pub remaining_ms: u64,
|
||||||
|
pub total_shape_count: u32,
|
||||||
|
pub completed_shape_count: u32,
|
||||||
|
pub combo: u32,
|
||||||
|
pub best_combo: u32,
|
||||||
|
pub score: u32,
|
||||||
|
pub rule_label: String,
|
||||||
|
pub current_shape: Option<SquareHoleShapeSnapshotRecord>,
|
||||||
|
pub holes: Vec<SquareHoleHoleSnapshotRecord>,
|
||||||
|
pub last_feedback: Option<SquareHoleDropFeedbackRecord>,
|
||||||
|
pub last_confirmed_action_id: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub struct SquareHoleDropConfirmationRecord {
|
||||||
|
pub status: String,
|
||||||
|
pub accepted: bool,
|
||||||
|
pub reject_reason: Option<String>,
|
||||||
|
pub failure_reason: Option<String>,
|
||||||
|
pub feedback: SquareHoleDropFeedbackRecord,
|
||||||
|
pub run: SquareHoleRunRecord,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
struct SquareHoleCreatorConfigJsonRecord {
|
||||||
|
theme_text: String,
|
||||||
|
twist_rule: String,
|
||||||
|
shape_count: u32,
|
||||||
|
difficulty: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
struct SquareHoleAgentMessageJsonRecord {
|
||||||
|
message_id: String,
|
||||||
|
#[allow(dead_code)]
|
||||||
|
session_id: String,
|
||||||
|
role: String,
|
||||||
|
kind: String,
|
||||||
|
text: String,
|
||||||
|
created_at_micros: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
struct SquareHoleDraftJsonRecord {
|
||||||
|
profile_id: String,
|
||||||
|
game_name: String,
|
||||||
|
theme_text: String,
|
||||||
|
twist_rule: String,
|
||||||
|
summary_text: String,
|
||||||
|
tags: Vec<String>,
|
||||||
|
shape_count: u32,
|
||||||
|
difficulty: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
struct SquareHoleAgentSessionJsonRecord {
|
||||||
|
session_id: String,
|
||||||
|
#[allow(dead_code)]
|
||||||
|
owner_user_id: String,
|
||||||
|
#[allow(dead_code)]
|
||||||
|
seed_text: String,
|
||||||
|
current_turn: u32,
|
||||||
|
progress_percent: u32,
|
||||||
|
stage: String,
|
||||||
|
config: SquareHoleCreatorConfigJsonRecord,
|
||||||
|
draft: Option<SquareHoleDraftJsonRecord>,
|
||||||
|
messages: Vec<SquareHoleAgentMessageJsonRecord>,
|
||||||
|
last_assistant_reply: String,
|
||||||
|
published_profile_id: Option<String>,
|
||||||
|
#[allow(dead_code)]
|
||||||
|
created_at_micros: i64,
|
||||||
|
updated_at_micros: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
struct SquareHoleWorkJsonRecord {
|
||||||
|
work_id: String,
|
||||||
|
profile_id: String,
|
||||||
|
owner_user_id: String,
|
||||||
|
source_session_id: String,
|
||||||
|
author_display_name: String,
|
||||||
|
game_name: String,
|
||||||
|
theme_text: String,
|
||||||
|
twist_rule: String,
|
||||||
|
summary_text: String,
|
||||||
|
tags: Vec<String>,
|
||||||
|
cover_image_src: String,
|
||||||
|
shape_count: u32,
|
||||||
|
difficulty: u32,
|
||||||
|
#[allow(dead_code)]
|
||||||
|
config: SquareHoleCreatorConfigJsonRecord,
|
||||||
|
publication_status: String,
|
||||||
|
publish_ready: bool,
|
||||||
|
play_count: u32,
|
||||||
|
updated_at_micros: i64,
|
||||||
|
published_at_micros: Option<i64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
struct SquareHoleShapeJsonRecord {
|
||||||
|
shape_id: String,
|
||||||
|
shape_kind: String,
|
||||||
|
label: String,
|
||||||
|
color: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, serde::Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
struct SquareHoleHoleJsonRecord {
|
||||||
|
hole_id: String,
|
||||||
|
hole_kind: String,
|
||||||
|
label: String,
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
struct SquareHoleDropFeedbackJsonRecord {
|
||||||
|
accepted: bool,
|
||||||
|
reject_reason: Option<String>,
|
||||||
|
message: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, serde::Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
struct SquareHoleRunJsonRecord {
|
||||||
|
run_id: String,
|
||||||
|
profile_id: String,
|
||||||
|
owner_user_id: String,
|
||||||
|
status: String,
|
||||||
|
snapshot_version: u64,
|
||||||
|
started_at_ms: i64,
|
||||||
|
duration_limit_ms: i64,
|
||||||
|
server_now_ms: i64,
|
||||||
|
remaining_ms: i64,
|
||||||
|
total_shape_count: u32,
|
||||||
|
completed_shape_count: u32,
|
||||||
|
combo: u32,
|
||||||
|
best_combo: u32,
|
||||||
|
score: u32,
|
||||||
|
rule_label: String,
|
||||||
|
current_shape: Option<SquareHoleShapeJsonRecord>,
|
||||||
|
holes: Vec<SquareHoleHoleJsonRecord>,
|
||||||
|
last_feedback: Option<SquareHoleDropFeedbackJsonRecord>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub struct PuzzleAnchorItemRecord {
|
pub struct PuzzleAnchorItemRecord {
|
||||||
pub key: String,
|
pub key: String,
|
||||||
|
|||||||
@@ -47,9 +47,11 @@ pub trait accept_quest {
|
|||||||
&self,
|
&self,
|
||||||
input: QuestRecordInput,
|
input: QuestRecordInput,
|
||||||
|
|
||||||
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
|
callback: impl FnOnce(
|
||||||
+ Send
|
&super::ReducerEventContext,
|
||||||
+ 'static,
|
Result<Result<(), String>, __sdk::InternalError>,
|
||||||
|
) + Send
|
||||||
|
+ 'static,
|
||||||
) -> __sdk::Result<()>;
|
) -> __sdk::Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,9 +60,11 @@ impl accept_quest for super::RemoteReducers {
|
|||||||
&self,
|
&self,
|
||||||
input: QuestRecordInput,
|
input: QuestRecordInput,
|
||||||
|
|
||||||
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
|
callback: impl FnOnce(
|
||||||
+ Send
|
&super::ReducerEventContext,
|
||||||
+ 'static,
|
Result<Result<(), String>, __sdk::InternalError>,
|
||||||
|
) + Send
|
||||||
|
+ 'static,
|
||||||
) -> __sdk::Result<()> {
|
) -> __sdk::Result<()> {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_reducer_with_callback(AcceptQuestArgs { input }, callback)
|
.invoke_reducer_with_callback(AcceptQuestArgs { input }, callback)
|
||||||
|
|||||||
@@ -47,9 +47,11 @@ pub trait acknowledge_quest_completion {
|
|||||||
&self,
|
&self,
|
||||||
input: QuestCompletionAckInput,
|
input: QuestCompletionAckInput,
|
||||||
|
|
||||||
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
|
callback: impl FnOnce(
|
||||||
+ Send
|
&super::ReducerEventContext,
|
||||||
+ 'static,
|
Result<Result<(), String>, __sdk::InternalError>,
|
||||||
|
) + Send
|
||||||
|
+ 'static,
|
||||||
) -> __sdk::Result<()>;
|
) -> __sdk::Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,9 +60,11 @@ impl acknowledge_quest_completion for super::RemoteReducers {
|
|||||||
&self,
|
&self,
|
||||||
input: QuestCompletionAckInput,
|
input: QuestCompletionAckInput,
|
||||||
|
|
||||||
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
|
callback: impl FnOnce(
|
||||||
+ Send
|
&super::ReducerEventContext,
|
||||||
+ 'static,
|
Result<Result<(), String>, __sdk::InternalError>,
|
||||||
|
) + Send
|
||||||
|
+ 'static,
|
||||||
) -> __sdk::Result<()> {
|
) -> __sdk::Result<()> {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_reducer_with_callback(AcknowledgeQuestCompletionArgs { input }, callback)
|
.invoke_reducer_with_callback(AcknowledgeQuestCompletionArgs { input }, callback)
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait admin_disable_profile_redeem_code {
|
|||||||
input: RuntimeProfileRedeemCodeAdminDisableInput,
|
input: RuntimeProfileRedeemCodeAdminDisableInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<RuntimeProfileRedeemCodeAdminProcedureResult, __sdk::InternalError>,
|
Result<RuntimeProfileRedeemCodeAdminProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl admin_disable_profile_redeem_code for super::RemoteProcedures {
|
|||||||
input: RuntimeProfileRedeemCodeAdminDisableInput,
|
input: RuntimeProfileRedeemCodeAdminDisableInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<RuntimeProfileRedeemCodeAdminProcedureResult, __sdk::InternalError>,
|
Result<RuntimeProfileRedeemCodeAdminProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, RuntimeProfileRedeemCodeAdminProcedureResult>(
|
.invoke_procedure_with_callback::<_, RuntimeProfileRedeemCodeAdminProcedureResult>(
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait admin_disable_profile_task_config {
|
|||||||
input: RuntimeProfileTaskConfigAdminDisableInput,
|
input: RuntimeProfileTaskConfigAdminDisableInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<RuntimeProfileTaskConfigAdminProcedureResult, __sdk::InternalError>,
|
Result<RuntimeProfileTaskConfigAdminProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl admin_disable_profile_task_config for super::RemoteProcedures {
|
|||||||
input: RuntimeProfileTaskConfigAdminDisableInput,
|
input: RuntimeProfileTaskConfigAdminDisableInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<RuntimeProfileTaskConfigAdminProcedureResult, __sdk::InternalError>,
|
Result<RuntimeProfileTaskConfigAdminProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, RuntimeProfileTaskConfigAdminProcedureResult>(
|
.invoke_procedure_with_callback::<_, RuntimeProfileTaskConfigAdminProcedureResult>(
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait admin_list_profile_invite_codes {
|
|||||||
input: RuntimeProfileInviteCodeAdminListInput,
|
input: RuntimeProfileInviteCodeAdminListInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<RuntimeProfileInviteCodeAdminListProcedureResult, __sdk::InternalError>,
|
Result<RuntimeProfileInviteCodeAdminListProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl admin_list_profile_invite_codes for super::RemoteProcedures {
|
|||||||
input: RuntimeProfileInviteCodeAdminListInput,
|
input: RuntimeProfileInviteCodeAdminListInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<RuntimeProfileInviteCodeAdminListProcedureResult, __sdk::InternalError>,
|
Result<RuntimeProfileInviteCodeAdminListProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, RuntimeProfileInviteCodeAdminListProcedureResult>(
|
.invoke_procedure_with_callback::<_, RuntimeProfileInviteCodeAdminListProcedureResult>(
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait admin_list_profile_redeem_codes {
|
|||||||
input: RuntimeProfileRedeemCodeAdminListInput,
|
input: RuntimeProfileRedeemCodeAdminListInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<RuntimeProfileRedeemCodeAdminListProcedureResult, __sdk::InternalError>,
|
Result<RuntimeProfileRedeemCodeAdminListProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl admin_list_profile_redeem_codes for super::RemoteProcedures {
|
|||||||
input: RuntimeProfileRedeemCodeAdminListInput,
|
input: RuntimeProfileRedeemCodeAdminListInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<RuntimeProfileRedeemCodeAdminListProcedureResult, __sdk::InternalError>,
|
Result<RuntimeProfileRedeemCodeAdminListProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, RuntimeProfileRedeemCodeAdminListProcedureResult>(
|
.invoke_procedure_with_callback::<_, RuntimeProfileRedeemCodeAdminListProcedureResult>(
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait admin_list_profile_task_configs {
|
|||||||
input: RuntimeProfileTaskConfigAdminListInput,
|
input: RuntimeProfileTaskConfigAdminListInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<RuntimeProfileTaskConfigAdminListProcedureResult, __sdk::InternalError>,
|
Result<RuntimeProfileTaskConfigAdminListProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl admin_list_profile_task_configs for super::RemoteProcedures {
|
|||||||
input: RuntimeProfileTaskConfigAdminListInput,
|
input: RuntimeProfileTaskConfigAdminListInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<RuntimeProfileTaskConfigAdminListProcedureResult, __sdk::InternalError>,
|
Result<RuntimeProfileTaskConfigAdminListProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, RuntimeProfileTaskConfigAdminListProcedureResult>(
|
.invoke_procedure_with_callback::<_, RuntimeProfileTaskConfigAdminListProcedureResult>(
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait admin_upsert_profile_invite_code {
|
|||||||
input: RuntimeProfileInviteCodeAdminUpsertInput,
|
input: RuntimeProfileInviteCodeAdminUpsertInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<RuntimeProfileInviteCodeAdminProcedureResult, __sdk::InternalError>,
|
Result<RuntimeProfileInviteCodeAdminProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl admin_upsert_profile_invite_code for super::RemoteProcedures {
|
|||||||
input: RuntimeProfileInviteCodeAdminUpsertInput,
|
input: RuntimeProfileInviteCodeAdminUpsertInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<RuntimeProfileInviteCodeAdminProcedureResult, __sdk::InternalError>,
|
Result<RuntimeProfileInviteCodeAdminProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, RuntimeProfileInviteCodeAdminProcedureResult>(
|
.invoke_procedure_with_callback::<_, RuntimeProfileInviteCodeAdminProcedureResult>(
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait admin_upsert_profile_redeem_code {
|
|||||||
input: RuntimeProfileRedeemCodeAdminUpsertInput,
|
input: RuntimeProfileRedeemCodeAdminUpsertInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<RuntimeProfileRedeemCodeAdminProcedureResult, __sdk::InternalError>,
|
Result<RuntimeProfileRedeemCodeAdminProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl admin_upsert_profile_redeem_code for super::RemoteProcedures {
|
|||||||
input: RuntimeProfileRedeemCodeAdminUpsertInput,
|
input: RuntimeProfileRedeemCodeAdminUpsertInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<RuntimeProfileRedeemCodeAdminProcedureResult, __sdk::InternalError>,
|
Result<RuntimeProfileRedeemCodeAdminProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, RuntimeProfileRedeemCodeAdminProcedureResult>(
|
.invoke_procedure_with_callback::<_, RuntimeProfileRedeemCodeAdminProcedureResult>(
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait admin_upsert_profile_task_config {
|
|||||||
input: RuntimeProfileTaskConfigAdminUpsertInput,
|
input: RuntimeProfileTaskConfigAdminUpsertInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<RuntimeProfileTaskConfigAdminProcedureResult, __sdk::InternalError>,
|
Result<RuntimeProfileTaskConfigAdminProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl admin_upsert_profile_task_config for super::RemoteProcedures {
|
|||||||
input: RuntimeProfileTaskConfigAdminUpsertInput,
|
input: RuntimeProfileTaskConfigAdminUpsertInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<RuntimeProfileTaskConfigAdminProcedureResult, __sdk::InternalError>,
|
Result<RuntimeProfileTaskConfigAdminProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, RuntimeProfileTaskConfigAdminProcedureResult>(
|
.invoke_procedure_with_callback::<_, RuntimeProfileTaskConfigAdminProcedureResult>(
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait advance_puzzle_next_level {
|
|||||||
input: PuzzleRunNextLevelInput,
|
input: PuzzleRunNextLevelInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<PuzzleRunProcedureResult, __sdk::InternalError>,
|
Result<PuzzleRunProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl advance_puzzle_next_level for super::RemoteProcedures {
|
|||||||
input: PuzzleRunNextLevelInput,
|
input: PuzzleRunNextLevelInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<PuzzleRunProcedureResult, __sdk::InternalError>,
|
Result<PuzzleRunProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, PuzzleRunProcedureResult>(
|
.invoke_procedure_with_callback::<_, PuzzleRunProcedureResult>(
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait append_ai_text_chunk_and_return {
|
|||||||
input: AiTextChunkAppendInput,
|
input: AiTextChunkAppendInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<AiTaskProcedureResult, __sdk::InternalError>,
|
Result<AiTaskProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl append_ai_text_chunk_and_return for super::RemoteProcedures {
|
|||||||
input: AiTextChunkAppendInput,
|
input: AiTextChunkAppendInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<AiTaskProcedureResult, __sdk::InternalError>,
|
Result<AiTaskProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, AiTaskProcedureResult>(
|
.invoke_procedure_with_callback::<_, AiTaskProcedureResult>(
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ pub trait apply_chapter_progression_ledger_entry_and_return {
|
|||||||
input: ChapterProgressionLedgerInput,
|
input: ChapterProgressionLedgerInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<ChapterProgressionProcedureResult, __sdk::InternalError>,
|
Result<ChapterProgressionProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,10 +47,10 @@ impl apply_chapter_progression_ledger_entry_and_return for super::RemoteProcedur
|
|||||||
input: ChapterProgressionLedgerInput,
|
input: ChapterProgressionLedgerInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<ChapterProgressionProcedureResult, __sdk::InternalError>,
|
Result<ChapterProgressionProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, ChapterProgressionProcedureResult>(
|
.invoke_procedure_with_callback::<_, ChapterProgressionProcedureResult>(
|
||||||
|
|||||||
@@ -50,9 +50,11 @@ pub trait apply_chapter_progression_ledger_entry {
|
|||||||
&self,
|
&self,
|
||||||
input: ChapterProgressionLedgerInput,
|
input: ChapterProgressionLedgerInput,
|
||||||
|
|
||||||
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
|
callback: impl FnOnce(
|
||||||
+ Send
|
&super::ReducerEventContext,
|
||||||
+ 'static,
|
Result<Result<(), String>, __sdk::InternalError>,
|
||||||
|
) + Send
|
||||||
|
+ 'static,
|
||||||
) -> __sdk::Result<()>;
|
) -> __sdk::Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,9 +63,11 @@ impl apply_chapter_progression_ledger_entry for super::RemoteReducers {
|
|||||||
&self,
|
&self,
|
||||||
input: ChapterProgressionLedgerInput,
|
input: ChapterProgressionLedgerInput,
|
||||||
|
|
||||||
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
|
callback: impl FnOnce(
|
||||||
+ Send
|
&super::ReducerEventContext,
|
||||||
+ 'static,
|
Result<Result<(), String>, __sdk::InternalError>,
|
||||||
|
) + Send
|
||||||
|
+ 'static,
|
||||||
) -> __sdk::Result<()> {
|
) -> __sdk::Result<()> {
|
||||||
self.imp.invoke_reducer_with_callback(
|
self.imp.invoke_reducer_with_callback(
|
||||||
ApplyChapterProgressionLedgerEntryArgs { input },
|
ApplyChapterProgressionLedgerEntryArgs { input },
|
||||||
|
|||||||
@@ -47,9 +47,11 @@ pub trait apply_inventory_mutation {
|
|||||||
&self,
|
&self,
|
||||||
input: InventoryMutationInput,
|
input: InventoryMutationInput,
|
||||||
|
|
||||||
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
|
callback: impl FnOnce(
|
||||||
+ Send
|
&super::ReducerEventContext,
|
||||||
+ 'static,
|
Result<Result<(), String>, __sdk::InternalError>,
|
||||||
|
) + Send
|
||||||
|
+ 'static,
|
||||||
) -> __sdk::Result<()>;
|
) -> __sdk::Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,9 +60,11 @@ impl apply_inventory_mutation for super::RemoteReducers {
|
|||||||
&self,
|
&self,
|
||||||
input: InventoryMutationInput,
|
input: InventoryMutationInput,
|
||||||
|
|
||||||
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
|
callback: impl FnOnce(
|
||||||
+ Send
|
&super::ReducerEventContext,
|
||||||
+ 'static,
|
Result<Result<(), String>, __sdk::InternalError>,
|
||||||
|
) + Send
|
||||||
|
+ 'static,
|
||||||
) -> __sdk::Result<()> {
|
) -> __sdk::Result<()> {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_reducer_with_callback(ApplyInventoryMutationArgs { input }, callback)
|
.invoke_reducer_with_callback(ApplyInventoryMutationArgs { input }, callback)
|
||||||
|
|||||||
@@ -47,9 +47,11 @@ pub trait apply_quest_signal {
|
|||||||
&self,
|
&self,
|
||||||
input: QuestSignalApplyInput,
|
input: QuestSignalApplyInput,
|
||||||
|
|
||||||
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
|
callback: impl FnOnce(
|
||||||
+ Send
|
&super::ReducerEventContext,
|
||||||
+ 'static,
|
Result<Result<(), String>, __sdk::InternalError>,
|
||||||
|
) + Send
|
||||||
|
+ 'static,
|
||||||
) -> __sdk::Result<()>;
|
) -> __sdk::Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,9 +60,11 @@ impl apply_quest_signal for super::RemoteReducers {
|
|||||||
&self,
|
&self,
|
||||||
input: QuestSignalApplyInput,
|
input: QuestSignalApplyInput,
|
||||||
|
|
||||||
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
|
callback: impl FnOnce(
|
||||||
+ Send
|
&super::ReducerEventContext,
|
||||||
+ 'static,
|
Result<Result<(), String>, __sdk::InternalError>,
|
||||||
|
) + Send
|
||||||
|
+ 'static,
|
||||||
) -> __sdk::Result<()> {
|
) -> __sdk::Result<()> {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_reducer_with_callback(ApplyQuestSignalArgs { input }, callback)
|
.invoke_reducer_with_callback(ApplyQuestSignalArgs { input }, callback)
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait attach_ai_result_reference_and_return {
|
|||||||
input: AiResultReferenceInput,
|
input: AiResultReferenceInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<AiTaskProcedureResult, __sdk::InternalError>,
|
Result<AiTaskProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl attach_ai_result_reference_and_return for super::RemoteProcedures {
|
|||||||
input: AiResultReferenceInput,
|
input: AiResultReferenceInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<AiTaskProcedureResult, __sdk::InternalError>,
|
Result<AiTaskProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, AiTaskProcedureResult>(
|
.invoke_procedure_with_callback::<_, AiTaskProcedureResult>(
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ pub trait authorize_database_migration_operator {
|
|||||||
input: DatabaseMigrationAuthorizeOperatorInput,
|
input: DatabaseMigrationAuthorizeOperatorInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<DatabaseMigrationOperatorProcedureResult, __sdk::InternalError>,
|
Result<DatabaseMigrationOperatorProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,10 +47,10 @@ impl authorize_database_migration_operator for super::RemoteProcedures {
|
|||||||
input: DatabaseMigrationAuthorizeOperatorInput,
|
input: DatabaseMigrationAuthorizeOperatorInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<DatabaseMigrationOperatorProcedureResult, __sdk::InternalError>,
|
Result<DatabaseMigrationOperatorProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, DatabaseMigrationOperatorProcedureResult>(
|
.invoke_procedure_with_callback::<_, DatabaseMigrationOperatorProcedureResult>(
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait begin_story_session_and_return {
|
|||||||
input: StorySessionInput,
|
input: StorySessionInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<StorySessionProcedureResult, __sdk::InternalError>,
|
Result<StorySessionProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl begin_story_session_and_return for super::RemoteProcedures {
|
|||||||
input: StorySessionInput,
|
input: StorySessionInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<StorySessionProcedureResult, __sdk::InternalError>,
|
Result<StorySessionProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, StorySessionProcedureResult>(
|
.invoke_procedure_with_callback::<_, StorySessionProcedureResult>(
|
||||||
|
|||||||
@@ -47,9 +47,11 @@ pub trait begin_story_session {
|
|||||||
&self,
|
&self,
|
||||||
input: StorySessionInput,
|
input: StorySessionInput,
|
||||||
|
|
||||||
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
|
callback: impl FnOnce(
|
||||||
+ Send
|
&super::ReducerEventContext,
|
||||||
+ 'static,
|
Result<Result<(), String>, __sdk::InternalError>,
|
||||||
|
) + Send
|
||||||
|
+ 'static,
|
||||||
) -> __sdk::Result<()>;
|
) -> __sdk::Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,9 +60,11 @@ impl begin_story_session for super::RemoteReducers {
|
|||||||
&self,
|
&self,
|
||||||
input: StorySessionInput,
|
input: StorySessionInput,
|
||||||
|
|
||||||
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
|
callback: impl FnOnce(
|
||||||
+ Send
|
&super::ReducerEventContext,
|
||||||
+ 'static,
|
Result<Result<(), String>, __sdk::InternalError>,
|
||||||
|
) + Send
|
||||||
|
+ 'static,
|
||||||
) -> __sdk::Result<()> {
|
) -> __sdk::Result<()> {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_reducer_with_callback(BeginStorySessionArgs { input }, callback)
|
.invoke_reducer_with_callback(BeginStorySessionArgs { input }, callback)
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait bind_asset_object_to_entity_and_return {
|
|||||||
input: AssetEntityBindingInput,
|
input: AssetEntityBindingInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<AssetEntityBindingProcedureResult, __sdk::InternalError>,
|
Result<AssetEntityBindingProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl bind_asset_object_to_entity_and_return for super::RemoteProcedures {
|
|||||||
input: AssetEntityBindingInput,
|
input: AssetEntityBindingInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<AssetEntityBindingProcedureResult, __sdk::InternalError>,
|
Result<AssetEntityBindingProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, AssetEntityBindingProcedureResult>(
|
.invoke_procedure_with_callback::<_, AssetEntityBindingProcedureResult>(
|
||||||
|
|||||||
@@ -47,9 +47,11 @@ pub trait bind_asset_object_to_entity {
|
|||||||
&self,
|
&self,
|
||||||
input: AssetEntityBindingInput,
|
input: AssetEntityBindingInput,
|
||||||
|
|
||||||
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
|
callback: impl FnOnce(
|
||||||
+ Send
|
&super::ReducerEventContext,
|
||||||
+ 'static,
|
Result<Result<(), String>, __sdk::InternalError>,
|
||||||
|
) + Send
|
||||||
|
+ 'static,
|
||||||
) -> __sdk::Result<()>;
|
) -> __sdk::Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,9 +60,11 @@ impl bind_asset_object_to_entity for super::RemoteReducers {
|
|||||||
&self,
|
&self,
|
||||||
input: AssetEntityBindingInput,
|
input: AssetEntityBindingInput,
|
||||||
|
|
||||||
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
|
callback: impl FnOnce(
|
||||||
+ Send
|
&super::ReducerEventContext,
|
||||||
+ 'static,
|
Result<Result<(), String>, __sdk::InternalError>,
|
||||||
|
) + Send
|
||||||
|
+ 'static,
|
||||||
) -> __sdk::Result<()> {
|
) -> __sdk::Result<()> {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_reducer_with_callback(BindAssetObjectToEntityArgs { input }, callback)
|
.invoke_reducer_with_callback(BindAssetObjectToEntityArgs { input }, callback)
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait cancel_ai_task_and_return {
|
|||||||
input: AiTaskCancelInput,
|
input: AiTaskCancelInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<AiTaskProcedureResult, __sdk::InternalError>,
|
Result<AiTaskProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl cancel_ai_task_and_return for super::RemoteProcedures {
|
|||||||
input: AiTaskCancelInput,
|
input: AiTaskCancelInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<AiTaskProcedureResult, __sdk::InternalError>,
|
Result<AiTaskProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, AiTaskProcedureResult>(
|
.invoke_procedure_with_callback::<_, AiTaskProcedureResult>(
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait claim_profile_task_reward_and_return {
|
|||||||
input: RuntimeProfileTaskClaimInput,
|
input: RuntimeProfileTaskClaimInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<RuntimeProfileTaskClaimProcedureResult, __sdk::InternalError>,
|
Result<RuntimeProfileTaskClaimProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl claim_profile_task_reward_and_return for super::RemoteProcedures {
|
|||||||
input: RuntimeProfileTaskClaimInput,
|
input: RuntimeProfileTaskClaimInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<RuntimeProfileTaskClaimProcedureResult, __sdk::InternalError>,
|
Result<RuntimeProfileTaskClaimProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, RuntimeProfileTaskClaimProcedureResult>(
|
.invoke_procedure_with_callback::<_, RuntimeProfileTaskClaimProcedureResult>(
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait claim_puzzle_work_point_incentive {
|
|||||||
input: PuzzleWorkPointIncentiveClaimInput,
|
input: PuzzleWorkPointIncentiveClaimInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<PuzzleWorkProcedureResult, __sdk::InternalError>,
|
Result<PuzzleWorkProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl claim_puzzle_work_point_incentive for super::RemoteProcedures {
|
|||||||
input: PuzzleWorkPointIncentiveClaimInput,
|
input: PuzzleWorkPointIncentiveClaimInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<PuzzleWorkProcedureResult, __sdk::InternalError>,
|
Result<PuzzleWorkProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, PuzzleWorkProcedureResult>(
|
.invoke_procedure_with_callback::<_, PuzzleWorkProcedureResult>(
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ pub trait clear_database_migration_import_chunks {
|
|||||||
input: DatabaseMigrationImportChunksClearInput,
|
input: DatabaseMigrationImportChunksClearInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<DatabaseMigrationProcedureResult, __sdk::InternalError>,
|
Result<DatabaseMigrationProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,10 +47,10 @@ impl clear_database_migration_import_chunks for super::RemoteProcedures {
|
|||||||
input: DatabaseMigrationImportChunksClearInput,
|
input: DatabaseMigrationImportChunksClearInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<DatabaseMigrationProcedureResult, __sdk::InternalError>,
|
Result<DatabaseMigrationProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, DatabaseMigrationProcedureResult>(
|
.invoke_procedure_with_callback::<_, DatabaseMigrationProcedureResult>(
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait clear_platform_browse_history_and_return {
|
|||||||
input: RuntimeBrowseHistoryClearInput,
|
input: RuntimeBrowseHistoryClearInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<RuntimeBrowseHistoryProcedureResult, __sdk::InternalError>,
|
Result<RuntimeBrowseHistoryProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl clear_platform_browse_history_and_return for super::RemoteProcedures {
|
|||||||
input: RuntimeBrowseHistoryClearInput,
|
input: RuntimeBrowseHistoryClearInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<RuntimeBrowseHistoryProcedureResult, __sdk::InternalError>,
|
Result<RuntimeBrowseHistoryProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, RuntimeBrowseHistoryProcedureResult>(
|
.invoke_procedure_with_callback::<_, RuntimeBrowseHistoryProcedureResult>(
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait click_match_3_d_item {
|
|||||||
input: Match3DRunClickInput,
|
input: Match3DRunClickInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<Match3DClickItemProcedureResult, __sdk::InternalError>,
|
Result<Match3DClickItemProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl click_match_3_d_item for super::RemoteProcedures {
|
|||||||
input: Match3DRunClickInput,
|
input: Match3DRunClickInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<Match3DClickItemProcedureResult, __sdk::InternalError>,
|
Result<Match3DClickItemProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, Match3DClickItemProcedureResult>(
|
.invoke_procedure_with_callback::<_, Match3DClickItemProcedureResult>(
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait compile_big_fish_draft {
|
|||||||
input: BigFishDraftCompileInput,
|
input: BigFishDraftCompileInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<BigFishSessionProcedureResult, __sdk::InternalError>,
|
Result<BigFishSessionProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl compile_big_fish_draft for super::RemoteProcedures {
|
|||||||
input: BigFishDraftCompileInput,
|
input: BigFishDraftCompileInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<BigFishSessionProcedureResult, __sdk::InternalError>,
|
Result<BigFishSessionProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, BigFishSessionProcedureResult>(
|
.invoke_procedure_with_callback::<_, BigFishSessionProcedureResult>(
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ pub trait compile_custom_world_published_profile {
|
|||||||
input: CustomWorldPublishedProfileCompileInput,
|
input: CustomWorldPublishedProfileCompileInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<CustomWorldPublishedProfileCompileResult, __sdk::InternalError>,
|
Result<CustomWorldPublishedProfileCompileResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,10 +47,10 @@ impl compile_custom_world_published_profile for super::RemoteProcedures {
|
|||||||
input: CustomWorldPublishedProfileCompileInput,
|
input: CustomWorldPublishedProfileCompileInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<CustomWorldPublishedProfileCompileResult, __sdk::InternalError>,
|
Result<CustomWorldPublishedProfileCompileResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, CustomWorldPublishedProfileCompileResult>(
|
.invoke_procedure_with_callback::<_, CustomWorldPublishedProfileCompileResult>(
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait compile_match_3_d_draft {
|
|||||||
input: Match3DDraftCompileInput,
|
input: Match3DDraftCompileInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<Match3DAgentSessionProcedureResult, __sdk::InternalError>,
|
Result<Match3DAgentSessionProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl compile_match_3_d_draft for super::RemoteProcedures {
|
|||||||
input: Match3DDraftCompileInput,
|
input: Match3DDraftCompileInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<Match3DAgentSessionProcedureResult, __sdk::InternalError>,
|
Result<Match3DAgentSessionProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, Match3DAgentSessionProcedureResult>(
|
.invoke_procedure_with_callback::<_, Match3DAgentSessionProcedureResult>(
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait compile_puzzle_agent_draft {
|
|||||||
input: PuzzleDraftCompileInput,
|
input: PuzzleDraftCompileInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<PuzzleAgentSessionProcedureResult, __sdk::InternalError>,
|
Result<PuzzleAgentSessionProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl compile_puzzle_agent_draft for super::RemoteProcedures {
|
|||||||
input: PuzzleDraftCompileInput,
|
input: PuzzleDraftCompileInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<PuzzleAgentSessionProcedureResult, __sdk::InternalError>,
|
Result<PuzzleAgentSessionProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, PuzzleAgentSessionProcedureResult>(
|
.invoke_procedure_with_callback::<_, PuzzleAgentSessionProcedureResult>(
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||||
|
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||||
|
|
||||||
|
#![allow(unused, clippy::all)]
|
||||||
|
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||||
|
|
||||||
|
use super::square_hole_agent_session_procedure_result_type::SquareHoleAgentSessionProcedureResult;
|
||||||
|
use super::square_hole_draft_compile_input_type::SquareHoleDraftCompileInput;
|
||||||
|
|
||||||
|
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||||
|
#[sats(crate = __lib)]
|
||||||
|
struct CompileSquareHoleDraftArgs {
|
||||||
|
pub input: SquareHoleDraftCompileInput,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl __sdk::InModule for CompileSquareHoleDraftArgs {
|
||||||
|
type Module = super::RemoteModule;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
/// Extension trait for access to the procedure `compile_square_hole_draft`.
|
||||||
|
///
|
||||||
|
/// Implemented for [`super::RemoteProcedures`].
|
||||||
|
pub trait compile_square_hole_draft {
|
||||||
|
fn compile_square_hole_draft(&self, input: SquareHoleDraftCompileInput) {
|
||||||
|
self.compile_square_hole_draft_then(input, |_, _| {});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compile_square_hole_draft_then(
|
||||||
|
&self,
|
||||||
|
input: SquareHoleDraftCompileInput,
|
||||||
|
|
||||||
|
__callback: impl FnOnce(
|
||||||
|
&super::ProcedureEventContext,
|
||||||
|
Result<SquareHoleAgentSessionProcedureResult, __sdk::InternalError>,
|
||||||
|
) + Send
|
||||||
|
+ 'static,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl compile_square_hole_draft for super::RemoteProcedures {
|
||||||
|
fn compile_square_hole_draft_then(
|
||||||
|
&self,
|
||||||
|
input: SquareHoleDraftCompileInput,
|
||||||
|
|
||||||
|
__callback: impl FnOnce(
|
||||||
|
&super::ProcedureEventContext,
|
||||||
|
Result<SquareHoleAgentSessionProcedureResult, __sdk::InternalError>,
|
||||||
|
) + Send
|
||||||
|
+ 'static,
|
||||||
|
) {
|
||||||
|
self.imp
|
||||||
|
.invoke_procedure_with_callback::<_, SquareHoleAgentSessionProcedureResult>(
|
||||||
|
"compile_square_hole_draft",
|
||||||
|
CompileSquareHoleDraftArgs { input },
|
||||||
|
__callback,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -31,10 +31,10 @@ pub trait complete_ai_stage_and_return {
|
|||||||
input: AiStageCompletionInput,
|
input: AiStageCompletionInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<AiTaskProcedureResult, __sdk::InternalError>,
|
Result<AiTaskProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl complete_ai_stage_and_return for super::RemoteProcedures {
|
|||||||
input: AiStageCompletionInput,
|
input: AiStageCompletionInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<AiTaskProcedureResult, __sdk::InternalError>,
|
Result<AiTaskProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, AiTaskProcedureResult>(
|
.invoke_procedure_with_callback::<_, AiTaskProcedureResult>(
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait complete_ai_task_and_return {
|
|||||||
input: AiTaskFinishInput,
|
input: AiTaskFinishInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<AiTaskProcedureResult, __sdk::InternalError>,
|
Result<AiTaskProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl complete_ai_task_and_return for super::RemoteProcedures {
|
|||||||
input: AiTaskFinishInput,
|
input: AiTaskFinishInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<AiTaskProcedureResult, __sdk::InternalError>,
|
Result<AiTaskProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, AiTaskProcedureResult>(
|
.invoke_procedure_with_callback::<_, AiTaskProcedureResult>(
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait confirm_asset_object_and_return {
|
|||||||
input: AssetObjectUpsertInput,
|
input: AssetObjectUpsertInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<AssetObjectProcedureResult, __sdk::InternalError>,
|
Result<AssetObjectProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl confirm_asset_object_and_return for super::RemoteProcedures {
|
|||||||
input: AssetObjectUpsertInput,
|
input: AssetObjectUpsertInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<AssetObjectProcedureResult, __sdk::InternalError>,
|
Result<AssetObjectProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, AssetObjectProcedureResult>(
|
.invoke_procedure_with_callback::<_, AssetObjectProcedureResult>(
|
||||||
|
|||||||
@@ -47,9 +47,11 @@ pub trait confirm_asset_object {
|
|||||||
&self,
|
&self,
|
||||||
input: AssetObjectUpsertInput,
|
input: AssetObjectUpsertInput,
|
||||||
|
|
||||||
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
|
callback: impl FnOnce(
|
||||||
+ Send
|
&super::ReducerEventContext,
|
||||||
+ 'static,
|
Result<Result<(), String>, __sdk::InternalError>,
|
||||||
|
) + Send
|
||||||
|
+ 'static,
|
||||||
) -> __sdk::Result<()>;
|
) -> __sdk::Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,9 +60,11 @@ impl confirm_asset_object for super::RemoteReducers {
|
|||||||
&self,
|
&self,
|
||||||
input: AssetObjectUpsertInput,
|
input: AssetObjectUpsertInput,
|
||||||
|
|
||||||
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
|
callback: impl FnOnce(
|
||||||
+ Send
|
&super::ReducerEventContext,
|
||||||
+ 'static,
|
Result<Result<(), String>, __sdk::InternalError>,
|
||||||
|
) + Send
|
||||||
|
+ 'static,
|
||||||
) -> __sdk::Result<()> {
|
) -> __sdk::Result<()> {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_reducer_with_callback(ConfirmAssetObjectArgs { input }, callback)
|
.invoke_reducer_with_callback(ConfirmAssetObjectArgs { input }, callback)
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait consume_profile_wallet_points_and_return {
|
|||||||
input: RuntimeProfileWalletAdjustmentInput,
|
input: RuntimeProfileWalletAdjustmentInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<RuntimeProfileWalletAdjustmentProcedureResult, __sdk::InternalError>,
|
Result<RuntimeProfileWalletAdjustmentProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl consume_profile_wallet_points_and_return for super::RemoteProcedures {
|
|||||||
input: RuntimeProfileWalletAdjustmentInput,
|
input: RuntimeProfileWalletAdjustmentInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<RuntimeProfileWalletAdjustmentProcedureResult, __sdk::InternalError>,
|
Result<RuntimeProfileWalletAdjustmentProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, RuntimeProfileWalletAdjustmentProcedureResult>(
|
.invoke_procedure_with_callback::<_, RuntimeProfileWalletAdjustmentProcedureResult>(
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait continue_story_and_return {
|
|||||||
input: StoryContinueInput,
|
input: StoryContinueInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<StorySessionProcedureResult, __sdk::InternalError>,
|
Result<StorySessionProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl continue_story_and_return for super::RemoteProcedures {
|
|||||||
input: StoryContinueInput,
|
input: StoryContinueInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<StorySessionProcedureResult, __sdk::InternalError>,
|
Result<StorySessionProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, StorySessionProcedureResult>(
|
.invoke_procedure_with_callback::<_, StorySessionProcedureResult>(
|
||||||
|
|||||||
@@ -47,9 +47,11 @@ pub trait continue_story {
|
|||||||
&self,
|
&self,
|
||||||
input: StoryContinueInput,
|
input: StoryContinueInput,
|
||||||
|
|
||||||
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
|
callback: impl FnOnce(
|
||||||
+ Send
|
&super::ReducerEventContext,
|
||||||
+ 'static,
|
Result<Result<(), String>, __sdk::InternalError>,
|
||||||
|
) + Send
|
||||||
|
+ 'static,
|
||||||
) -> __sdk::Result<()>;
|
) -> __sdk::Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,9 +60,11 @@ impl continue_story for super::RemoteReducers {
|
|||||||
&self,
|
&self,
|
||||||
input: StoryContinueInput,
|
input: StoryContinueInput,
|
||||||
|
|
||||||
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
|
callback: impl FnOnce(
|
||||||
+ Send
|
&super::ReducerEventContext,
|
||||||
+ 'static,
|
Result<Result<(), String>, __sdk::InternalError>,
|
||||||
|
) + Send
|
||||||
|
+ 'static,
|
||||||
) -> __sdk::Result<()> {
|
) -> __sdk::Result<()> {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_reducer_with_callback(ContinueStoryArgs { input }, callback)
|
.invoke_reducer_with_callback(ContinueStoryArgs { input }, callback)
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait create_ai_task_and_return {
|
|||||||
input: AiTaskCreateInput,
|
input: AiTaskCreateInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<AiTaskProcedureResult, __sdk::InternalError>,
|
Result<AiTaskProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl create_ai_task_and_return for super::RemoteProcedures {
|
|||||||
input: AiTaskCreateInput,
|
input: AiTaskCreateInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<AiTaskProcedureResult, __sdk::InternalError>,
|
Result<AiTaskProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, AiTaskProcedureResult>(
|
.invoke_procedure_with_callback::<_, AiTaskProcedureResult>(
|
||||||
|
|||||||
@@ -47,9 +47,11 @@ pub trait create_ai_task {
|
|||||||
&self,
|
&self,
|
||||||
input: AiTaskCreateInput,
|
input: AiTaskCreateInput,
|
||||||
|
|
||||||
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
|
callback: impl FnOnce(
|
||||||
+ Send
|
&super::ReducerEventContext,
|
||||||
+ 'static,
|
Result<Result<(), String>, __sdk::InternalError>,
|
||||||
|
) + Send
|
||||||
|
+ 'static,
|
||||||
) -> __sdk::Result<()>;
|
) -> __sdk::Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,9 +60,11 @@ impl create_ai_task for super::RemoteReducers {
|
|||||||
&self,
|
&self,
|
||||||
input: AiTaskCreateInput,
|
input: AiTaskCreateInput,
|
||||||
|
|
||||||
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
|
callback: impl FnOnce(
|
||||||
+ Send
|
&super::ReducerEventContext,
|
||||||
+ 'static,
|
Result<Result<(), String>, __sdk::InternalError>,
|
||||||
|
) + Send
|
||||||
|
+ 'static,
|
||||||
) -> __sdk::Result<()> {
|
) -> __sdk::Result<()> {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_reducer_with_callback(CreateAiTaskArgs { input }, callback)
|
.invoke_reducer_with_callback(CreateAiTaskArgs { input }, callback)
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait create_battle_state_and_return {
|
|||||||
input: BattleStateInput,
|
input: BattleStateInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<BattleStateProcedureResult, __sdk::InternalError>,
|
Result<BattleStateProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl create_battle_state_and_return for super::RemoteProcedures {
|
|||||||
input: BattleStateInput,
|
input: BattleStateInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<BattleStateProcedureResult, __sdk::InternalError>,
|
Result<BattleStateProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, BattleStateProcedureResult>(
|
.invoke_procedure_with_callback::<_, BattleStateProcedureResult>(
|
||||||
|
|||||||
@@ -47,9 +47,11 @@ pub trait create_battle_state {
|
|||||||
&self,
|
&self,
|
||||||
input: BattleStateInput,
|
input: BattleStateInput,
|
||||||
|
|
||||||
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
|
callback: impl FnOnce(
|
||||||
+ Send
|
&super::ReducerEventContext,
|
||||||
+ 'static,
|
Result<Result<(), String>, __sdk::InternalError>,
|
||||||
|
) + Send
|
||||||
|
+ 'static,
|
||||||
) -> __sdk::Result<()>;
|
) -> __sdk::Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,9 +60,11 @@ impl create_battle_state for super::RemoteReducers {
|
|||||||
&self,
|
&self,
|
||||||
input: BattleStateInput,
|
input: BattleStateInput,
|
||||||
|
|
||||||
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
|
callback: impl FnOnce(
|
||||||
+ Send
|
&super::ReducerEventContext,
|
||||||
+ 'static,
|
Result<Result<(), String>, __sdk::InternalError>,
|
||||||
|
) + Send
|
||||||
|
+ 'static,
|
||||||
) -> __sdk::Result<()> {
|
) -> __sdk::Result<()> {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_reducer_with_callback(CreateBattleStateArgs { input }, callback)
|
.invoke_reducer_with_callback(CreateBattleStateArgs { input }, callback)
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait create_big_fish_session {
|
|||||||
input: BigFishSessionCreateInput,
|
input: BigFishSessionCreateInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<BigFishSessionProcedureResult, __sdk::InternalError>,
|
Result<BigFishSessionProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl create_big_fish_session for super::RemoteProcedures {
|
|||||||
input: BigFishSessionCreateInput,
|
input: BigFishSessionCreateInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<BigFishSessionProcedureResult, __sdk::InternalError>,
|
Result<BigFishSessionProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, BigFishSessionProcedureResult>(
|
.invoke_procedure_with_callback::<_, BigFishSessionProcedureResult>(
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait create_custom_world_agent_session {
|
|||||||
input: CustomWorldAgentSessionCreateInput,
|
input: CustomWorldAgentSessionCreateInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<CustomWorldAgentSessionProcedureResult, __sdk::InternalError>,
|
Result<CustomWorldAgentSessionProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl create_custom_world_agent_session for super::RemoteProcedures {
|
|||||||
input: CustomWorldAgentSessionCreateInput,
|
input: CustomWorldAgentSessionCreateInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<CustomWorldAgentSessionProcedureResult, __sdk::InternalError>,
|
Result<CustomWorldAgentSessionProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, CustomWorldAgentSessionProcedureResult>(
|
.invoke_procedure_with_callback::<_, CustomWorldAgentSessionProcedureResult>(
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait create_match_3_d_agent_session {
|
|||||||
input: Match3DAgentSessionCreateInput,
|
input: Match3DAgentSessionCreateInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<Match3DAgentSessionProcedureResult, __sdk::InternalError>,
|
Result<Match3DAgentSessionProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl create_match_3_d_agent_session for super::RemoteProcedures {
|
|||||||
input: Match3DAgentSessionCreateInput,
|
input: Match3DAgentSessionCreateInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<Match3DAgentSessionProcedureResult, __sdk::InternalError>,
|
Result<Match3DAgentSessionProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, Match3DAgentSessionProcedureResult>(
|
.invoke_procedure_with_callback::<_, Match3DAgentSessionProcedureResult>(
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ pub trait create_profile_recharge_order_and_return {
|
|||||||
input: RuntimeProfileRechargeOrderCreateInput,
|
input: RuntimeProfileRechargeOrderCreateInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<RuntimeProfileRechargeCenterProcedureResult, __sdk::InternalError>,
|
Result<RuntimeProfileRechargeCenterProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,10 +47,10 @@ impl create_profile_recharge_order_and_return for super::RemoteProcedures {
|
|||||||
input: RuntimeProfileRechargeOrderCreateInput,
|
input: RuntimeProfileRechargeOrderCreateInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<RuntimeProfileRechargeCenterProcedureResult, __sdk::InternalError>,
|
Result<RuntimeProfileRechargeCenterProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, RuntimeProfileRechargeCenterProcedureResult>(
|
.invoke_procedure_with_callback::<_, RuntimeProfileRechargeCenterProcedureResult>(
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait create_puzzle_agent_session {
|
|||||||
input: PuzzleAgentSessionCreateInput,
|
input: PuzzleAgentSessionCreateInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<PuzzleAgentSessionProcedureResult, __sdk::InternalError>,
|
Result<PuzzleAgentSessionProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl create_puzzle_agent_session for super::RemoteProcedures {
|
|||||||
input: PuzzleAgentSessionCreateInput,
|
input: PuzzleAgentSessionCreateInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<PuzzleAgentSessionProcedureResult, __sdk::InternalError>,
|
Result<PuzzleAgentSessionProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, PuzzleAgentSessionProcedureResult>(
|
.invoke_procedure_with_callback::<_, PuzzleAgentSessionProcedureResult>(
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||||
|
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||||
|
|
||||||
|
#![allow(unused, clippy::all)]
|
||||||
|
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||||
|
|
||||||
|
use super::square_hole_agent_session_create_input_type::SquareHoleAgentSessionCreateInput;
|
||||||
|
use super::square_hole_agent_session_procedure_result_type::SquareHoleAgentSessionProcedureResult;
|
||||||
|
|
||||||
|
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||||
|
#[sats(crate = __lib)]
|
||||||
|
struct CreateSquareHoleAgentSessionArgs {
|
||||||
|
pub input: SquareHoleAgentSessionCreateInput,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl __sdk::InModule for CreateSquareHoleAgentSessionArgs {
|
||||||
|
type Module = super::RemoteModule;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
/// Extension trait for access to the procedure `create_square_hole_agent_session`.
|
||||||
|
///
|
||||||
|
/// Implemented for [`super::RemoteProcedures`].
|
||||||
|
pub trait create_square_hole_agent_session {
|
||||||
|
fn create_square_hole_agent_session(&self, input: SquareHoleAgentSessionCreateInput) {
|
||||||
|
self.create_square_hole_agent_session_then(input, |_, _| {});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_square_hole_agent_session_then(
|
||||||
|
&self,
|
||||||
|
input: SquareHoleAgentSessionCreateInput,
|
||||||
|
|
||||||
|
__callback: impl FnOnce(
|
||||||
|
&super::ProcedureEventContext,
|
||||||
|
Result<SquareHoleAgentSessionProcedureResult, __sdk::InternalError>,
|
||||||
|
) + Send
|
||||||
|
+ 'static,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl create_square_hole_agent_session for super::RemoteProcedures {
|
||||||
|
fn create_square_hole_agent_session_then(
|
||||||
|
&self,
|
||||||
|
input: SquareHoleAgentSessionCreateInput,
|
||||||
|
|
||||||
|
__callback: impl FnOnce(
|
||||||
|
&super::ProcedureEventContext,
|
||||||
|
Result<SquareHoleAgentSessionProcedureResult, __sdk::InternalError>,
|
||||||
|
) + Send
|
||||||
|
+ 'static,
|
||||||
|
) {
|
||||||
|
self.imp
|
||||||
|
.invoke_procedure_with_callback::<_, SquareHoleAgentSessionProcedureResult>(
|
||||||
|
"create_square_hole_agent_session",
|
||||||
|
CreateSquareHoleAgentSessionArgs { input },
|
||||||
|
__callback,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -31,10 +31,10 @@ pub trait delete_big_fish_work {
|
|||||||
input: BigFishWorkDeleteInput,
|
input: BigFishWorkDeleteInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<BigFishWorksProcedureResult, __sdk::InternalError>,
|
Result<BigFishWorksProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl delete_big_fish_work for super::RemoteProcedures {
|
|||||||
input: BigFishWorkDeleteInput,
|
input: BigFishWorkDeleteInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<BigFishWorksProcedureResult, __sdk::InternalError>,
|
Result<BigFishWorksProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, BigFishWorksProcedureResult>(
|
.invoke_procedure_with_callback::<_, BigFishWorksProcedureResult>(
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait delete_custom_world_agent_session {
|
|||||||
input: CustomWorldAgentSessionGetInput,
|
input: CustomWorldAgentSessionGetInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<CustomWorldWorksListResult, __sdk::InternalError>,
|
Result<CustomWorldWorksListResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl delete_custom_world_agent_session for super::RemoteProcedures {
|
|||||||
input: CustomWorldAgentSessionGetInput,
|
input: CustomWorldAgentSessionGetInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<CustomWorldWorksListResult, __sdk::InternalError>,
|
Result<CustomWorldWorksListResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, CustomWorldWorksListResult>(
|
.invoke_procedure_with_callback::<_, CustomWorldWorksListResult>(
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait delete_custom_world_profile_and_return {
|
|||||||
input: CustomWorldProfileDeleteInput,
|
input: CustomWorldProfileDeleteInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<CustomWorldProfileListResult, __sdk::InternalError>,
|
Result<CustomWorldProfileListResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl delete_custom_world_profile_and_return for super::RemoteProcedures {
|
|||||||
input: CustomWorldProfileDeleteInput,
|
input: CustomWorldProfileDeleteInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<CustomWorldProfileListResult, __sdk::InternalError>,
|
Result<CustomWorldProfileListResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, CustomWorldProfileListResult>(
|
.invoke_procedure_with_callback::<_, CustomWorldProfileListResult>(
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait delete_match_3_d_work {
|
|||||||
input: Match3DWorkDeleteInput,
|
input: Match3DWorkDeleteInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<Match3DWorksProcedureResult, __sdk::InternalError>,
|
Result<Match3DWorksProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl delete_match_3_d_work for super::RemoteProcedures {
|
|||||||
input: Match3DWorkDeleteInput,
|
input: Match3DWorkDeleteInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<Match3DWorksProcedureResult, __sdk::InternalError>,
|
Result<Match3DWorksProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, Match3DWorksProcedureResult>(
|
.invoke_procedure_with_callback::<_, Match3DWorksProcedureResult>(
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait delete_puzzle_work {
|
|||||||
input: PuzzleWorkDeleteInput,
|
input: PuzzleWorkDeleteInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<PuzzleWorksProcedureResult, __sdk::InternalError>,
|
Result<PuzzleWorksProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl delete_puzzle_work for super::RemoteProcedures {
|
|||||||
input: PuzzleWorkDeleteInput,
|
input: PuzzleWorkDeleteInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<PuzzleWorksProcedureResult, __sdk::InternalError>,
|
Result<PuzzleWorksProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, PuzzleWorksProcedureResult>(
|
.invoke_procedure_with_callback::<_, PuzzleWorksProcedureResult>(
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait delete_runtime_snapshot_and_return {
|
|||||||
input: RuntimeSnapshotDeleteInput,
|
input: RuntimeSnapshotDeleteInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<RuntimeSnapshotProcedureResult, __sdk::InternalError>,
|
Result<RuntimeSnapshotProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl delete_runtime_snapshot_and_return for super::RemoteProcedures {
|
|||||||
input: RuntimeSnapshotDeleteInput,
|
input: RuntimeSnapshotDeleteInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<RuntimeSnapshotProcedureResult, __sdk::InternalError>,
|
Result<RuntimeSnapshotProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, RuntimeSnapshotProcedureResult>(
|
.invoke_procedure_with_callback::<_, RuntimeSnapshotProcedureResult>(
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||||
|
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||||
|
|
||||||
|
#![allow(unused, clippy::all)]
|
||||||
|
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||||
|
|
||||||
|
use super::square_hole_work_delete_input_type::SquareHoleWorkDeleteInput;
|
||||||
|
use super::square_hole_works_procedure_result_type::SquareHoleWorksProcedureResult;
|
||||||
|
|
||||||
|
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||||
|
#[sats(crate = __lib)]
|
||||||
|
struct DeleteSquareHoleWorkArgs {
|
||||||
|
pub input: SquareHoleWorkDeleteInput,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl __sdk::InModule for DeleteSquareHoleWorkArgs {
|
||||||
|
type Module = super::RemoteModule;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
/// Extension trait for access to the procedure `delete_square_hole_work`.
|
||||||
|
///
|
||||||
|
/// Implemented for [`super::RemoteProcedures`].
|
||||||
|
pub trait delete_square_hole_work {
|
||||||
|
fn delete_square_hole_work(&self, input: SquareHoleWorkDeleteInput) {
|
||||||
|
self.delete_square_hole_work_then(input, |_, _| {});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn delete_square_hole_work_then(
|
||||||
|
&self,
|
||||||
|
input: SquareHoleWorkDeleteInput,
|
||||||
|
|
||||||
|
__callback: impl FnOnce(
|
||||||
|
&super::ProcedureEventContext,
|
||||||
|
Result<SquareHoleWorksProcedureResult, __sdk::InternalError>,
|
||||||
|
) + Send
|
||||||
|
+ 'static,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl delete_square_hole_work for super::RemoteProcedures {
|
||||||
|
fn delete_square_hole_work_then(
|
||||||
|
&self,
|
||||||
|
input: SquareHoleWorkDeleteInput,
|
||||||
|
|
||||||
|
__callback: impl FnOnce(
|
||||||
|
&super::ProcedureEventContext,
|
||||||
|
Result<SquareHoleWorksProcedureResult, __sdk::InternalError>,
|
||||||
|
) + Send
|
||||||
|
+ 'static,
|
||||||
|
) {
|
||||||
|
self.imp
|
||||||
|
.invoke_procedure_with_callback::<_, SquareHoleWorksProcedureResult>(
|
||||||
|
"delete_square_hole_work",
|
||||||
|
DeleteSquareHoleWorkArgs { input },
|
||||||
|
__callback,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -31,10 +31,10 @@ pub trait drag_puzzle_piece_or_group {
|
|||||||
input: PuzzleRunDragInput,
|
input: PuzzleRunDragInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<PuzzleRunProcedureResult, __sdk::InternalError>,
|
Result<PuzzleRunProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl drag_puzzle_piece_or_group for super::RemoteProcedures {
|
|||||||
input: PuzzleRunDragInput,
|
input: PuzzleRunDragInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<PuzzleRunProcedureResult, __sdk::InternalError>,
|
Result<PuzzleRunProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, PuzzleRunProcedureResult>(
|
.invoke_procedure_with_callback::<_, PuzzleRunProcedureResult>(
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||||
|
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||||
|
|
||||||
|
#![allow(unused, clippy::all)]
|
||||||
|
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||||
|
|
||||||
|
use super::square_hole_drop_shape_procedure_result_type::SquareHoleDropShapeProcedureResult;
|
||||||
|
use super::square_hole_run_drop_input_type::SquareHoleRunDropInput;
|
||||||
|
|
||||||
|
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||||
|
#[sats(crate = __lib)]
|
||||||
|
struct DropSquareHoleShapeArgs {
|
||||||
|
pub input: SquareHoleRunDropInput,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl __sdk::InModule for DropSquareHoleShapeArgs {
|
||||||
|
type Module = super::RemoteModule;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
/// Extension trait for access to the procedure `drop_square_hole_shape`.
|
||||||
|
///
|
||||||
|
/// Implemented for [`super::RemoteProcedures`].
|
||||||
|
pub trait drop_square_hole_shape {
|
||||||
|
fn drop_square_hole_shape(&self, input: SquareHoleRunDropInput) {
|
||||||
|
self.drop_square_hole_shape_then(input, |_, _| {});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn drop_square_hole_shape_then(
|
||||||
|
&self,
|
||||||
|
input: SquareHoleRunDropInput,
|
||||||
|
|
||||||
|
__callback: impl FnOnce(
|
||||||
|
&super::ProcedureEventContext,
|
||||||
|
Result<SquareHoleDropShapeProcedureResult, __sdk::InternalError>,
|
||||||
|
) + Send
|
||||||
|
+ 'static,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl drop_square_hole_shape for super::RemoteProcedures {
|
||||||
|
fn drop_square_hole_shape_then(
|
||||||
|
&self,
|
||||||
|
input: SquareHoleRunDropInput,
|
||||||
|
|
||||||
|
__callback: impl FnOnce(
|
||||||
|
&super::ProcedureEventContext,
|
||||||
|
Result<SquareHoleDropShapeProcedureResult, __sdk::InternalError>,
|
||||||
|
) + Send
|
||||||
|
+ 'static,
|
||||||
|
) {
|
||||||
|
self.imp
|
||||||
|
.invoke_procedure_with_callback::<_, SquareHoleDropShapeProcedureResult>(
|
||||||
|
"drop_square_hole_shape",
|
||||||
|
DropSquareHoleShapeArgs { input },
|
||||||
|
__callback,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -50,9 +50,11 @@ pub trait ensure_analytics_date_dimension_for_date {
|
|||||||
&self,
|
&self,
|
||||||
input: AnalyticsDateDimensionEnsureInput,
|
input: AnalyticsDateDimensionEnsureInput,
|
||||||
|
|
||||||
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
|
callback: impl FnOnce(
|
||||||
+ Send
|
&super::ReducerEventContext,
|
||||||
+ 'static,
|
Result<Result<(), String>, __sdk::InternalError>,
|
||||||
|
) + Send
|
||||||
|
+ 'static,
|
||||||
) -> __sdk::Result<()>;
|
) -> __sdk::Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,9 +63,11 @@ impl ensure_analytics_date_dimension_for_date for super::RemoteReducers {
|
|||||||
&self,
|
&self,
|
||||||
input: AnalyticsDateDimensionEnsureInput,
|
input: AnalyticsDateDimensionEnsureInput,
|
||||||
|
|
||||||
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
|
callback: impl FnOnce(
|
||||||
+ Send
|
&super::ReducerEventContext,
|
||||||
+ 'static,
|
Result<Result<(), String>, __sdk::InternalError>,
|
||||||
|
) + Send
|
||||||
|
+ 'static,
|
||||||
) -> __sdk::Result<()> {
|
) -> __sdk::Result<()> {
|
||||||
self.imp.invoke_reducer_with_callback(
|
self.imp.invoke_reducer_with_callback(
|
||||||
EnsureAnalyticsDateDimensionForDateArgs { input },
|
EnsureAnalyticsDateDimensionForDateArgs { input },
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait execute_custom_world_agent_action {
|
|||||||
input: CustomWorldAgentActionExecuteInput,
|
input: CustomWorldAgentActionExecuteInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<CustomWorldAgentActionExecuteResult, __sdk::InternalError>,
|
Result<CustomWorldAgentActionExecuteResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl execute_custom_world_agent_action for super::RemoteProcedures {
|
|||||||
input: CustomWorldAgentActionExecuteInput,
|
input: CustomWorldAgentActionExecuteInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<CustomWorldAgentActionExecuteResult, __sdk::InternalError>,
|
Result<CustomWorldAgentActionExecuteResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, CustomWorldAgentActionExecuteResult>(
|
.invoke_procedure_with_callback::<_, CustomWorldAgentActionExecuteResult>(
|
||||||
|
|||||||
@@ -27,10 +27,10 @@ pub trait export_auth_store_snapshot_from_tables {
|
|||||||
&self,
|
&self,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<AuthStoreSnapshotProcedureResult, __sdk::InternalError>,
|
Result<AuthStoreSnapshotProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,10 +39,10 @@ impl export_auth_store_snapshot_from_tables for super::RemoteProcedures {
|
|||||||
&self,
|
&self,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<AuthStoreSnapshotProcedureResult, __sdk::InternalError>,
|
Result<AuthStoreSnapshotProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, AuthStoreSnapshotProcedureResult>(
|
.invoke_procedure_with_callback::<_, AuthStoreSnapshotProcedureResult>(
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait export_database_migration_to_file {
|
|||||||
input: DatabaseMigrationExportInput,
|
input: DatabaseMigrationExportInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<DatabaseMigrationProcedureResult, __sdk::InternalError>,
|
Result<DatabaseMigrationProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl export_database_migration_to_file for super::RemoteProcedures {
|
|||||||
input: DatabaseMigrationExportInput,
|
input: DatabaseMigrationExportInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<DatabaseMigrationProcedureResult, __sdk::InternalError>,
|
Result<DatabaseMigrationProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, DatabaseMigrationProcedureResult>(
|
.invoke_procedure_with_callback::<_, DatabaseMigrationProcedureResult>(
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ pub trait fail_ai_task_and_return {
|
|||||||
input: AiTaskFailureInput,
|
input: AiTaskFailureInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<AiTaskProcedureResult, __sdk::InternalError>,
|
Result<AiTaskProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ impl fail_ai_task_and_return for super::RemoteProcedures {
|
|||||||
input: AiTaskFailureInput,
|
input: AiTaskFailureInput,
|
||||||
|
|
||||||
__callback: impl FnOnce(
|
__callback: impl FnOnce(
|
||||||
&super::ProcedureEventContext,
|
&super::ProcedureEventContext,
|
||||||
Result<AiTaskProcedureResult, __sdk::InternalError>,
|
Result<AiTaskProcedureResult, __sdk::InternalError>,
|
||||||
) + Send
|
) + Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) {
|
) {
|
||||||
self.imp
|
self.imp
|
||||||
.invoke_procedure_with_callback::<_, AiTaskProcedureResult>(
|
.invoke_procedure_with_callback::<_, AiTaskProcedureResult>(
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user