问题8 登录系统: - node:sqlite 账号存储(scrypt 哈希 + HMAC 签名 token),preset admin 改为 e2hang/evan1115 - /api/auth/register|login|me,me 返回 room 供重联 - 网关拦截 create/join 需登录(401),列表保持开放 踢人逻辑修正(问题2 延伸): - kickMove 真正释放座位(folded=false, name=null)而非锁死 - war/mill 去掉永久封禁语义 管理员越权:管理员 token 可删任意房间、踢任意房间内的人 单房间约束(用户新需求): - 同一用户同时只能在一个房间,create/join 他房返回 409 - 踢人后若房间仅剩踢人者则自动解散并释放其记录(修复 2 人局踢光对手后被困 409) - 陈旧房间记录兜底清理 UI 清理:移除"改名"按钮与"你的名字"输入框;删除房间按钮仅房主/管理员可见 docs: 新增 12-auth-kick-single-room.md 汇总本会话全部需求/根因/修复/边界测试 Co-Authored-By: Claude (CodeBuddy) <noreply@codebuddy.ai>
51 lines
3.8 KiB
Markdown
51 lines
3.8 KiB
Markdown
# 问题 3:结束后未重置房间;德州补码/退出;其他游戏无限轮回
|
||
|
||
## 现状
|
||
- **Holdem**:`showdown` 之后 `next: 'waiting'`,回到等待房主 `startHand`。但:
|
||
- 任何人筹码 ≤ 0 时,没有“补码 / 退出房间”的入口,UI 只显示一个“出局”徽章(`HoldemBoard.tsx:147`)。
|
||
- 没有“重置房间”(把所有人筹码恢复到 `startingStack`、清空战绩)的按钮。
|
||
- **其他游戏(War / Mill / DragTest)**:`endIf` 一旦满足就 `gameover`,客户端停在“游戏结束”界面,
|
||
没有“再来一局 / 无限轮回”的自动重开。
|
||
|
||
## 需求拆解
|
||
1. **Holdem**:有人筹码 ≤ 0 → 给他选择“补码(rebuy)”或“退出房间(leave)”。
|
||
2. **Holdem**:房主可“重置房间”(rebuy 所有人 / 重置到初始 setup)。
|
||
3. **通用(所有游戏)**:结束(gameover)后做一个“无限轮回”——自动或一键开下一局,而不是卡在结束页。
|
||
|
||
## 拟采用方案
|
||
|
||
### 3.1 Holdem —— 补码 / 退出 / 重置(engine + ui)
|
||
- engine 新增 moves:
|
||
- `rebuyMove({G, ctx, playerID}, amount?)`:把 `G.players[me].stack` 加回 `startingStack`
|
||
(或指定补码额,默认补足到 `startingStack`);若之前 `seated && stack===0` 且已 `inHand=false`,
|
||
补码后恢复 `inHand=true` 以便下一手参与。`amount` 需 ≤ 上限(如 `startingStack`)且为 5 的倍数(呼应问题 9 的分段)。
|
||
- `leaveRoomMove({G, ctx, playerID})`:把该座位 `seated=false`(本地视图退出),不删房间。
|
||
(真正的“离开房间”仍走 lobby `leave`,这里是牌桌内的“退出本手/本房”语义。)
|
||
- `resetRoomMove({G, ctx, playerID})`:**仅房主**:把所有 `seated` 玩家的 `stack` 重置为 `startingStack`、
|
||
`inHand/folded/allIn` 归位、清空 `pot/board/hands`、回到 `waiting`、可保留 `handNumber` 或清零。
|
||
- ui(`HoldemBoard`):
|
||
- 当 `myPlayer.stack <= 0` 且 `seated` → 显示“补码”/“退出房间”两个按钮。
|
||
- 房主在 `waiting` 阶段增加“重置房间”按钮(调 `resetRoom`)。
|
||
- `waiting` 阶段已有“开始游戏”按钮(`HoldemBoard.tsx:287`),补码/重置与之并列。
|
||
|
||
### 3.2 通用 —— 无限轮回(engine)
|
||
目标:游戏 `gameover` 后不要卡死,而是能“再来一局”。
|
||
- **方案 A(推荐,最小侵入)**:各游戏加一个通用 `playAgain`/`rematch` move(房主触发),
|
||
内部重新 `setup()` 并回到初始 phase。Holdem 的 `resetRoom` 已覆盖;War/Mill/DragTest 各加一个薄 `rematch`。
|
||
- **方案 B(自动轮回)**:`endIf` 命中后延迟 N 秒由房主/系统自动调用 `rematch`。
|
||
考虑到联机下需要权威端触发且避免“无人时自动开”,建议用**方案 A** + 在 UI 上把“再来一局”做成醒目的主按钮,
|
||
并允许房主开启“自动轮回”开关(可选)。
|
||
- 对 War/Mill:结算后 `waiting`/`rematch` phase 显示胜者 + “再来一局”按钮;不自动重开,避免误开。
|
||
|
||
> “无限轮回”理解为**可无限次重开同一房间**,而非同一对局逻辑无限循环。实现上就是“结束 → 一键重开”。
|
||
|
||
## 与问题 2 的耦合
|
||
- 补码/重置/重开都是 **game move**,需经 boardgame.io(server 权威)。
|
||
- 房主判定的“房主专属权”(重置、rematch)依赖问题 2 中固化的 `hostId`(metadata `createdBy`)。
|
||
engine `host()` 应改为读 `G.hostId`(setup 时由房主座位写入),避免破产后 host 漂移导致重置按钮消失。
|
||
|
||
## 验证
|
||
- Holdem:某人筹码 0 → 出现补码/退出;补码后 stack 回满、可继续;房主重置 → 全员回到初始。
|
||
- War/Mill:gameover → 显示“再来一局” → 点后回到初始可玩状态,房间不丢。
|
||
- 联机:补码/重置/rematch 在所有人客户端同步。
|