# 单账号连续普通钓鱼最小方案(待完整评审) 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。