Files
ft/CodexOutput/upserver/ContinuousFishing/单账号连续普通钓鱼最小方案-待评审.md

132 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 单账号连续普通钓鱼最小方案(待完整评审)
2026-09-28,主会话。上一包101真实闭环与药水引导修正已限定关闭,120/120受审文件一致,无阻塞修复。本方案是下一包的建议方向;已询问用户业务优先级,尚未收到新选择,按“先跑起来、最小改动、单账号、重启式重登”整理。不把前包关闭当成本方案实施或新消费授权。
## 1. 目标、选择与边界
用户在一次Editor登录中,手动完成普通抛竿→拉杆→奖励落库→收下回主页,然后可以再次普通抛竿;退出后仍通过新进程恢复验证。第一轮实景验收只计划101最多两次手动尝试,中间不重启,随后统一恢复、对账与交付复核。一次完整方案评审后连续实施,内部检查点更新日志,不按方法或单个测试反复送审。
| 路径 | 代价与结果 | 选择 |
|---|---|---|
| 保留会话许可,增加同一会话的逐竿完成与隔离 | 复用已验证存储/登录/票据;集中修改钓鱼调用链,仍需一次会话准备 | 推荐,本方案 |
| 每竿仍重启、只优化操作说明 | 无生产修改,但无法解决连续调试成本 | 保留现状时可用,不作为本包交付 |
| 直接启用默认kv并解除所有门 | 牵涉4B3B/C全业务归属、生命周期与正式启用,超出当前证据 | 本包不采用 |
固定API `http://s101.local:18080/`,Unity CLI Loop,不打包。仅 `UNITY_EDITOR && !SERVICE_HOST` 的运行链扩展,许可解析仍可在现有Editor宿主回归。非Editor/PF分支保持原业务行为。不改经济公式、随机选鱼、UI资产、服务器、存档格式、Schema、旧档导入或账号映射;不开发热换号、广告重试、特殊鱼/活动奖励、额外领取。正式 `SaveBackend=kv` 拒绝和无许可时默认PF都保持;本包不能声称解决了普通正式登录切换。
## 2. 已核实的源码事实
| 位置 | 当前事实 | 本包必须解决的原因 |
|---|---|---|
| `UserService.KVGameplayLoop.cs`:BeginFishing/CancelFishing | fishingAction终身保留;取消通过Actor传给奖励层 | 不能仅将静态字段置空;A竿迟到取消可能命中复用Actor上的B竿 |
| `UserService.KVFishingReward.cs` | rewardPlan/rewardAction保留;多个入口取全局当前动作 | 每竿必须有独立计划、票据、分段与完成身份 |
| `FishingUpdateSys.CastLine` | 在调用BeginFishing的下游入口前,已写连击、startTimer等内存 | 动作准入必须前移到这些修改之前 |
| `FishingBehaviorB` | await/yield/tween后常读取可变kvFishingAction;长期复用场景对象 | 方法开始时捕获的A不能在恢复时变成B |
| `FishingUpdateSys` | RewardCanAdvance全局判断;ShowUI异步加载;FishEndCore销毁FishingPanel | 旧控制器和旧ShowUI完成不能控制新动作 |
| `FishingRewardPanel` | 已有confirmed→presented;收下无逐动作完成回报 | 不能用任意OnDisable当“成功收下”;重复点击不能重复重置选鱼 |
| `FishingAct` | ResetFishingStatus同步重新选鱼;RestartShowHomeUI异步返回主页 | 发布回主页事件不等于主页已就绪;不能据此立即重新放行 |
| `FishingBehaviorB.InitFishAsync/LoadFish` | 场景对象复用,路径比较不能区分连续两条同种鱼;延迟默认鱼/资源加载存在 | 准备阶段同样需要局部请求身份,避免旧资源覆盖下一条同种鱼 |
UIManager的ShowUI在返回前等待一帧;面板Start可先绑定奖励。DestroyUI移除字典后仍有下一帧通知。因此本包用本动作的面板请求完成、实际面板销毁和回主页完成事实收口,不修改通用UIManager,不用固定等待秒数当隔离依据。
## 3. 会话许可与操作预算
复用现有permit、备份/hash、AllowedKeys、固定账号/地址及进程Claim。增加显式v4操作 `fishing-reward-session`,必填正整数 `MaxFishingActions`;v1/v2/v3的准入与一次性语义保持,旧版本不得携带该扩展字段悄悄变成多竿。v4首包限定101;允许键必须来自本轮最新101备份,不导入、不创建空键。
MaxFishingActions是本次运行批准的最多尝试次数,不是成功次数或自动重试次数。仅在首次成功创建本次抛竿动作时占一个名额,在扣费前就占用;重复输入不占新名额。失败/拦截/取消不返还名额,且停止本会话后续钓鱼。到上限时阻止新的动作及其初始化内存修改,但允许已经完成的数据正常退出保存;不发起后台额外动作。
第一轮候选值为2。这是待确认的运行范围,并非已有授权。未来仅改变同一合同内的次数须有对应测试范围授权,不修改v3、删除claim或使旧进程重复认领。新增固定Editor准备入口,复用原验证/备份流程,不做新的许可管理器或调试面板。
## 4. 逐动作合同
### 4.1 准入与上下文
在 `FishingUpdateSys.CastLine` 第一个业务内存修改之前申请动作。绑定当前控制器、FishingBehavior实例及原Session Handle,并把返回的同一动作显式交给CastLineBehavior;不能由下游再创建另一个动作。旧控制器只绑定一次;已绑定的旧控制器再次调用属于重复/迟到输入,不能创建新动作。
下一竿须同时满足:v4仍有效、Ready且同一Owner、前竿完全收口、无当前故障/Unknown、名额未耗尽。首次运行也遵守这些条件。每竿重新运行现有普通鱼/引导/活动/配置/倍率/MapKey检查,重新捕获计划和前值;不复用上一竿的准入结果。`PrepareFishingReward`的奖励计划归属于动作,不能凭全局旧计划通过。
此外,v4在扣费前排除实际会触发额外收下分支的条件:当前倍率SupplyDrop>0或已有supplyDropCtrl,以及 `lastMapId非首地图 && !IsOpenAppraise && fish.Quality>=5` 的评价解锁分支。收下前复核这些条件;变更则停止,不调用额外分支、不回滚已确认奖励。现有KV下CheckResource不启动空投加载的行为保持。该限制用于本次普通回主页闭环,不修改这些玩法的规则或存档。
### 4.2 捕获与迟到回调
业务调用使用显式FishingAction/FishingRewardAction引用。所有异步方法在启动时捕获本动作到局部变量,每次await/yield恢复、tween回调、事件订阅回调进入后,均在第一次业务内存变更前核对该引用、Owner及实例寿命。不能恢复后再读取字段/全局当前动作作为A的身份;同一Actor、鱼ID、资源路径均不等于同一次动作。
| 链段 | 处理范围 |
|---|---|
| 抛竿/消费 | CastLine、CastLineBehavior、CastBait、BaitMove、WaitForFishBite、ConsumeBaitOnKVAsync、ContinueFishing及其tween/coroutine |
| 受力/收线 | PiercingFish、伤害保护/连击延迟、普通Update、FishEnd、取消生命周期与ShowKVRewardPanelAsync |
| 奖励 | BeginRewardDrawing/Ending/Segment、BindRewardPanel、确认/呈现、展示延迟及资源完成回调、收下 |
| 准备/返回 | FishingAct的本次Reset/回主页,FishingBehavior的InitFishAsync/LoadFish/ShowDefaultFish及本次特效、鱼线延迟 |
保留现有固定句柄和票据API,不增加跨业务Registry或全局Ambient Context。对复用FishingBehavior上早于抛竿的资源准备,使用仅限该组件的准备批次引用:InitFishAsync开始新准备即更换引用;本批次LoadFish/ShowDefaultFish捕获并传递同一引用,不在延迟恢复时创建新批次。旧批次迟到的资源只释放本次取得的引用,不写当前字段、不发布会改变当前鱼状态的事件。抛竿时绑定当时准备批次;运行中不得替换成新批次。一般静态资源预载和逐鱼请求分开判断,不因动作尚未创建而错误取消合法初始化。
现有特效加载若会在await后写复用字段,捕获调用时的准备批次/动作;迟到结果只释放自己的资源。不改无异步共享状态的纯计算。实现检查点需列出上述三份钓鱼文件中普通路径所有await/yield/tween的处理或不可达依据;不能只改现有KVFishingCurrent调用点而漏掉未加守卫的旧路径。
取消和异常处理同样带显式旧动作:A完成后A的Cancel、OnKill、异常、ticket完成、面板销毁不得Cancel/Fault/推进B。当前动作真实失败继续走现有Fault终止;会话级存储故障不可被当作普通迟到回调吞掉。旧资源清理只清理A拥有的资源,不按UI类型销毁B,不把全局缓存字段清空。
### 4.3 保存与收下完成
继续使用原扣费写批次和strike/ending/reward三段原始票据,先确认扣费再继续战斗,先确认最终鱼档/主档及实际任务写入再呈现。每竿票据列表、Segments、BeforeFishCount独立;A的Superseded/Confirmed不能充当B的确认,不补发、不重放Unknown。
v4状态为:可开始→进行中→奖励确认/呈现→收下收口中→已完成。成功收下需当前绑定面板、Confirmed且Presented;第一次点击原子标记收口中,重复点击直接返回,原OnClosePanel/InHomePanel业务主体只执行一次。普通OnDisable、失败关闭、退出、收线控制器正常销毁都不能独立标记成功完成。
完成收口须具备同一动作的全部事实:
1. 原奖励票据确认、无故障/Unknown,三个业务段已关闭。
2. 用户点击成功收下,原同步ResetFishingStatus和回主页事件发布成功;异常则停止。
3. 原奖励面板完成销毁清理,原ShowKVRewardPanelAsync已结束;原呈现Task已完成或已因该面板合法销毁而退出,不能悬挂后借B继续。
4. FishingAct的本次RestartShowHomeUI异步完成。事件携带仅Editor用的显式动作引用;在await前后检查。其他无动作的回主页事件沿用原行为,不能完成钓鱼动作。
完成入口可由这些事实分别到达后调用同一个幂等检查,但只能完成一次。不能在OnDisable里无条件清空三个静态字段,也不能依赖“再等一秒”。前竿完成后将其标为终态,才释放全局活动槽;A对象本身保留终态供迟到回调判定。返回主页过程不自动开始B;B由用户正常入口触发。非v4保留原一次性门,不因增加完成状态而允许第二次抛竿。
收口时保留完成路径自拆除的现有例外,并以动作身份和收口状态限定新的面板销毁例外;未确认奖励时的真取消仍停止。共享句柄关闭仍由既有QuitStage/drain负责,动作完成不关闭/重建会话或丢弃待存。
## 5. 修改白名单
运行代码最多限于下列7个现有文件;不新增通用运行框架。必须逐文件解释实际改动原因,不因列入白名单而重排格式或全面重构。
| 文件(Client下) | 允许改动 |
|---|---|
| Assets/Scripts/Services/UserService.KVGameplayLoop.cs | v4许可、尝试预算、动作创建/完成身份、带动作的取消/错误;保留存储接线 |
| Assets/Scripts/Services/UserService.KVFishingReward.cs | 独立奖励计划/分段、显式动作校验、收口事实与幂等完成 |
| Assets/Scripts/GampPlay/FishingB/FishingBehaviorB.cs | 显式动作传递、普通路径异步/资源准备批次保护 |
| Assets/Scripts/GampPlay/FishingB/FishingUpdateSys.cs | CastLine前置准入、绑定动作、普通战斗延迟与奖励面板请求保护 |
| Assets/Scripts/UI/FishingReward/FishingRewardPanel.cs | 固定奖励引用、收下幂等、资源清理和收口事实 |
| Assets/Scripts/Stages/FishingAct.cs | 仅本次普通回主页事件的动作传递、恢复检查和完成回报 |
| Assets/Editor/KVGameplayLoopSetup.cs | 固定v4准备/验证入口,返回已存在的状态信息 |
测试允许在已有 `UserService.KVFishingValidation.cs`、`UserService.KVFishingRewardValidation.cs` 及本业务包目录内补离线验证/证据,按实际方法签名同步既有测试抽取器,不改断言使失败变绿。DataCenter的消费/保存/引导、UIManager、HomePanel、配置/资产只读。若必须改变这些文件的业务逻辑,先将具体差异补进方案再审,不能以本表授权泛化。
## 6. 验收与实施顺序
| 检查点 | 连续完成的内容 | 必须证据 |
|---|---|---|
| 0 | 主会话核本方案基线,逐项裁决完整独立审查,明确允许编码 | hash、裁决、精确白名单;本方案当前尚未批准 |
| 1 | 生命周期/逐动作隔离与许可;先有红测再修正,覆盖真实生产入口或现有生产代码抽取 | v3仍一次;v4两竿;预算;同Actor/同鱼A→B迟到;重复回调;内存首次修改前拒绝 |
| 2 | 完整UI/普通链接线与回归、编译 | 下表关键负例、原奖励55组243/消费19组81/引导模块12/31模块83相关回归;Editor/SERVICE_HOST双编译;非Editor代码边界检查 |
| 3 | 用户确认101停用其他客户端及本包最多两次尝试后,一次登录连续完成两竿和收下,正常退出,新进程恢复 | 分竿原票据/日志/奖励与主页截图/全量快照;若任一竿失败或门拦截立即停止,不自动补跑 |
| 4 | 统一封存hash、交付、自审和一次独立实施复核 | 准确区分真实两竿成功、只完成一竿或全部未消费;不能离线通过代替实景通过 |
关键测试必须验证结果,而不是只看实现布尔值:
- A尚未confirmed/presented、尚未收下、ShowUI/呈现/回主页未结束、面板未销毁时,B无扣费且无初始化内存改动;各种事实乱序仅完成A一次。
- A已完成且B活动时,注入A的消费续体、战斗延迟、奖励确认、OnKill、Cancel、面板销毁、资源加载失败/成功;B内存、写入记录、显示与故障状态不变。特别覆盖同Actor、同鱼ID/同资源路径及场景对象复用。
- 收下双击只选一次下一鱼、只返回一次主页;面板任意隐藏不计成功;正常收线自拆除不误取消,未确认关闭仍停止。
- 两竿不同计划各自只扣一次;最终鱼数按各自前值和倍率增量,独立票据;第一竿已确认的票据不能用于第二竿;失败、Unknown、Unauthorized后不能续竿。
- 首次CastLine重复/超预算时,不写startTimer、连击等先前在准入前修改的字段。非v4旧用例保留。
- 每竿活动/引导/配置/鱼/倍率变化重新校验;评价解锁/空投候选扣费前停止;收下时条件漂移不进入分支。
- 准备阶段早于动作的有效资源加载不被误拒;同路径旧准备结果只释放自己,不能覆盖新鱼或清空新资源。
- 无真实API的模拟验证必须用既有fake transport,不以变更真实存档造负例。保留失败原证据。
真实验收沿用主会话统一执行:新备份与新进程;许可只认领一次;登录后先分离跨日/签到变化;每次操作前记录对应前值,用户停奖励页,主会话取证后明确“可收下”;之后第二次普通手动动作无需重新评审或重启。意外提前收下保留事实,不再收费补截图。最多两次不是承诺随机鱼必然符合原门。
最终正常QuitStage、待存排空,归档许可且保留claimed;v1新进程只恢复,不钓鱼;核所有备份键的原字符串和两竿累计变化。恢复可能有原同值登录写,不能称零写。101旧停用窗口已结束,须新确认;102不操作,不使用原55键历史档覆盖任何当前进度。
## 7. 自审与审查关注点
作者只读自审完成:本方案承认会话许可仍存在,未把连续钓鱼等同正式启用;没有为了P3新增截图锁;把共享Actor、可变字段、CastLine前置内存、异步回主页和同种鱼资源准备纳入合同。v4尝试预算和每竿完成是局部扩展,不扩展到其他活动。完整4B3B/C和最终平台验收仍未完成。
请审查重点裁定:七文件边界能否实现§4且无遗漏的普通路径上游内存修改;准备批次与动作的分工是否最小;Start先绑定面板而ShowUI后返回的时序是否被收口屏障覆盖;迟到错误不能Fault新竿但真实存储故障必须停止;v1/v2/v3兼容;真实两次授权边界。若这些合同无法在范围内实现,应指出具体调用链与最小修订,不建议泛化重构全部业务。
本方案及审查基线落盘后交完整独立方案审查。评审前不修改生产/测试代码、不生成v4真实许可、不进入Play。