Conversation
木马(木牛流马 mark:700)弱候选与已知牌来源物化冲突修复: - A(时序): 新增 resolveHiddenMarkCandidatesFromFullHandReveal,在 resolveKnownMoveCards 之前对整手完整揭示做局部反向收敛——不在揭示 ID 里的候选明牌解到 mark,被挤出的匿名占位挤回来源手牌,消除 createExternal 与"明牌未找到可立即置换的手牌占位"告警。 - B(占位守恒): bindConfirmedMarkCardToMarkSpace 的 player-mark 占位回收 改为挤回 sourceSeat 手牌而非丢 outside(容器投影仍回 outside)。 - 复现守卫: tests/tracker/trojanFullHandReveal.test.ts。 技能打磨: - SiQi: 移除牌底端点诊断脚手架与 afterMove 二次对账(连带删 Room.moveCards 死钩子),收敛为单条 debug 日志,功能推断不变。 - QiaoZhi: 删除纯诊断的 getAnonymousHandEntityIDs / anonymousHandEntityIDsBefore 与 getUnknownPlayerCards,结算日志精简;差集反推逻辑不变。 全量 284 条 tracker 测试通过;typecheck/lint/build 清洁。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
📝 WalkthroughWalkthroughChanges技能移动事件装饰
隐藏标记与已知牌收敛
事件归一化与视图脏状态
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant MoveEventHandlers
participant QiaoZhi
participant SiQi
participant Room
MoveEventHandlers->>QiaoZhi: 分发 3544 移动事件
QiaoZhi->>Room: 记录展示牌并结算差集
MoveEventHandlers->>SiQi: 分发 3543 移动事件
SiQi->>Room: 读取来源区红牌并注入 sourceCards
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (4)
src/tracker/MoveEventNormalizer.ts (1)
351-351: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value注释建议改为陈述式说明。
// subZone 在观看公共区时会被设置成 hand, 我觉得不太合理,改成了 undefined为第一人称口语,建议改为客观说明变更原因(例如:观看公共区时不应默认推导为hand,故公共区来源置为undefined)。🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/tracker/MoveEventNormalizer.ts` at line 351, 将 MoveEventNormalizer.ts 中说明 subZone 的注释改为客观陈述,明确表达观看公共区时不应默认推导为 hand,因此公共区来源设置为 undefined;移除第一人称和口语化表述。src/tracker/skill/QiaoZhi.ts (2)
33-39: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value建议将诊断性跳过日志降为 debug。
recordDisplayedCards/recordHiddenGain/settleHiddenGain对所有正常跳过分支均使用trackerLogger.info,而同 PR 的SiQi.ts使用debug。3544 事件为高频入口,info会显著增加日志噪声,建议诊断类日志统一用debug。🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/tracker/skill/QiaoZhi.ts` around lines 33 - 39, 将 QiaoZhi.ts 中 recordDisplayedCards、recordHiddenGain 和 settleHiddenGain 的正常跳过分支日志从 trackerLogger.info 降为 trackerLogger.debug,保持现有日志内容及返回逻辑不变,统一与 SiQi.ts 的诊断日志级别。
15-21: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win提取共享 helper,消除
getRaw/getCount/hasPositiveID重复。 两个新技能文件复制了与src/tracker/runtime/moveEventHandlers.ts相同的事件读取工具,建议抽到共享模块(如src/tracker/skill/moveEventUtils.ts)统一导入,降低后续维护分叉风险。
src/tracker/skill/QiaoZhi.ts#L15-L21:移除本地getRaw/getCount,改为从共享模块导入。src/tracker/skill/SiQi.ts#L9-L19:移除本地getRaw/getCount/hasPositiveID,改为从共享模块导入。🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/tracker/skill/QiaoZhi.ts` around lines 15 - 21, 将 src/tracker/runtime/moveEventHandlers.ts 中与事件读取相关的 getRaw、getCount、hasPositiveID 提取到共享模块 src/tracker/skill/moveEventUtils.ts,并统一导出。更新 src/tracker/skill/QiaoZhi.ts 第15-21行移除本地 getRaw/getCount,改为导入共享实现;更新 src/tracker/skill/SiQi.ts 第9-19行移除本地 getRaw/getCount/hasPositiveID,改为导入共享实现,确保现有调用行为不变。src/tracker/roomMovement/hiddenMarks.ts (1)
984-992: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value占位回收筛选可与
bindConfirmedMarkCardToMarkSpace保持一致(防御性)。此处挑选被挤出的匿名占位仅判
isAnonymousCard(ph) && ph !== card,而bindConfirmedMarkCardToMarkSpace额外校验subZone === 'mark'且spellID === record.spellID。当前record.placeholderCards通常同 spellID,风险有限;但补齐同样的筛选可避免后续账本混入其它子区/spellID 占位时误回收。♻️ 建议筛选
- const placeholder = Array.from(record.placeholderCards ?? []).find( - (ph) => isAnonymousCard(ph) && ph !== card - ) + const placeholder = Array.from(record.placeholderCards ?? []).find( + (ph) => + isAnonymousCard(ph) && + ph !== card && + ph.location === 'player' && + ph.subZone === 'mark' && + Number(ph.spellID) === Number(record.spellID) + )🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/tracker/roomMovement/hiddenMarks.ts` around lines 984 - 992, 更新 hidden mark 占位回收逻辑中 `record.placeholderCards.find` 的筛选条件,除 `isAnonymousCard(ph)` 且 `ph !== card` 外,补充校验 `ph.subZone` 为 `mark` 且 `ph.spellID` 等于 `record.spellID`,使其与 `bindConfirmedMarkCardToMarkSpace` 的筛选保持一致。
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@src/tracker/MoveEventNormalizer.ts`:
- Line 351: 将 MoveEventNormalizer.ts 中说明 subZone 的注释改为客观陈述,明确表达观看公共区时不应默认推导为
hand,因此公共区来源设置为 undefined;移除第一人称和口语化表述。
In `@src/tracker/roomMovement/hiddenMarks.ts`:
- Around line 984-992: 更新 hidden mark 占位回收逻辑中 `record.placeholderCards.find`
的筛选条件,除 `isAnonymousCard(ph)` 且 `ph !== card` 外,补充校验 `ph.subZone` 为 `mark` 且
`ph.spellID` 等于 `record.spellID`,使其与 `bindConfirmedMarkCardToMarkSpace` 的筛选保持一致。
In `@src/tracker/skill/QiaoZhi.ts`:
- Around line 33-39: 将 QiaoZhi.ts 中 recordDisplayedCards、recordHiddenGain 和
settleHiddenGain 的正常跳过分支日志从 trackerLogger.info 降为
trackerLogger.debug,保持现有日志内容及返回逻辑不变,统一与 SiQi.ts 的诊断日志级别。
- Around line 15-21: 将 src/tracker/runtime/moveEventHandlers.ts 中与事件读取相关的
getRaw、getCount、hasPositiveID 提取到共享模块
src/tracker/skill/moveEventUtils.ts,并统一导出。更新 src/tracker/skill/QiaoZhi.ts
第15-21行移除本地 getRaw/getCount,改为导入共享实现;更新 src/tracker/skill/SiQi.ts 第9-19行移除本地
getRaw/getCount/hasPositiveID,改为导入共享实现,确保现有调用行为不变。
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 13712cbf-854b-4a31-9e85-b7a66271b764
📒 Files selected for processing (17)
src/handler/PubGsCMoveCard.jssrc/handler/spellEffects.jssrc/tracker/MoveEventNormalizer.tssrc/tracker/Room.tssrc/tracker/roomMovement.tssrc/tracker/roomMovement/hiddenMarks.tssrc/tracker/roomMovement/sources.tssrc/tracker/runtime/moveEventHandlers.tssrc/tracker/skill/QiaoZhi.tssrc/tracker/skill/SiQi.tstests/tracker/knownDiscardConfirm.test.tstests/tracker/moveEventNormalizer.test.tstests/tracker/qiaoZhi.test.tstests/tracker/siQi.test.tstests/tracker/spellEffects.test.tstests/tracker/trojanFullHandReveal.test.tstests/tracker/viewDirtyRender.test.ts
💤 Files with no reviewable changes (1)
- src/handler/spellEffects.js
- 抽出 getRaw/getCount/hasPositiveID 到 moveEventUtils - 整手揭示回收占位对齐 mark/spellID 筛选 - 巧织正常跳过日志降为 debug;公共区 subZone 注释客观化
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/tracker/skill/moveEventUtils.ts`:
- Around line 7-9: Update getCount to normalize event.cardCount or
event.options?.cardCount as a finite, non-negative integer before returning it.
Reject or safely default invalid values such as NaN, infinity, and fractions,
while preserving zero for missing or invalid counts and the existing
non-negative behavior for valid integers.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 321b7f91-d8e3-4213-a9c7-e1d48e136779
📒 Files selected for processing (6)
src/tracker/MoveEventNormalizer.tssrc/tracker/roomMovement/hiddenMarks.tssrc/tracker/runtime/moveEventHandlers.tssrc/tracker/skill/QiaoZhi.tssrc/tracker/skill/SiQi.tssrc/tracker/skill/moveEventUtils.ts
🚧 Files skipped from review as they are similar to previous changes (4)
- src/tracker/MoveEventNormalizer.ts
- src/tracker/skill/SiQi.ts
- src/tracker/skill/QiaoZhi.ts
- src/tracker/roomMovement/hiddenMarks.ts
概述
新增思泣(3543)/巧织(3544)技能对暗牌来源的推断适配,并修复适配期间暴露的木马(木牛流马 mark:700)弱候选与已知牌来源物化冲突。
改动
技能适配(527bbea)
sourceCards+combinationID。spellID:null,避免后续进木马时残留「标记(巧织)」描述)。createExternal缺口补建后统一confirmKnown;手牌 known 路径禁止消费 mark 占位等。木马弱候选收敛修复(a0d5986)
场景:3 号位 141(明)+2 暗,暗置 1 张进木马形成弱候选;整手
[29,50,113]完整进处理区、141 不在其中 → 141 必在木马。此前会createExternal([50])并把真实手牌占位丢弃。resolveHiddenMarkCandidatesFromFullHandReveal,在resolveKnownMoveCards之前对整手完整揭示做局部反向收敛——不在揭示 ID 里的候选明牌解到 mark,被挤出的匿名占位挤回来源手牌。bindConfirmedMarkCardToMarkSpace的 player-mark 占位回收改为挤回sourceSeat手牌,而非丢outside(容器投影占位仍回 outside)。诊断瘦身
afterMove二次对账(连带删Room.moveCards死钩子)。getAnonymousHandEntityIDs/getUnknownPlayerCards与冗余状态字段。测试
tests/tracker/trojanFullHandReveal.test.ts(木马整手揭示复现守卫)、tests/tracker/knownDiscardConfirm.test.ts。typecheck:tracker/lint/build均清洁。遗留
本轮为针对「整手完整揭示」触发的补丁;木马/mark 双重表示的结构性根因与更优方案(中心化守恒原语 / 收敛器增强)已记录在本地
plans/mark-space-and-trojan-convergence.md(gitignore,不入库),待后续单独立项。🤖 Generated with Claude Code
Summary by CodeRabbit