using Loop=game.PlayerDataStorage.PlayerKVGameplayLoop; int checks=0; void Check(bool ok,string text){checks++;if(!ok)throw new Exception(text);} ControlSlice Fresh(){Loop.Enabled=true;Loop.Ready=true;Loop.Faults=0;GContext.container.Player=new();Application.internetReachability=NetworkReachability.Reachable;return new();} var s=Fresh();var player=GContext.container.Player;var first=s.RunAwaited(); Check(s.Continues==0 && player.Calls==1,"actual method waits for response"); s.Run();await s.RunAwaited();Check(player.Calls==1 && s.Continues==0,"duplicate consume and callback cannot repeat"); player.Response.SetResult();await first;Check(s.Continues==1,"actual success continuation exactly once"); await s.RunAwaited();Check(s.Continues==1 && player.Calls==1,"post-success duplicate suppressed"); foreach(var kind in new[]{"free","retry","duel","pack","special","missing-fish","missing-item","offline","activity","bad-mag"}){ s=Fresh();player=GContext.container.Player; switch(kind){ case "free":s.fishingData.IsFree=true;break;case "retry":s.fishingData.IsRetry=true;break; case "duel":s.fishingData.IsDuel=true;break;case "pack":s.fishingData.Pack=true;break; case "special":s.fishingData.General=false;break;case "missing-fish":s.fishingData.curFishData=null;break; case "missing-item":s.fishingData.fishItem=null;break;case "offline":Application.internetReachability=NetworkReachability.NotReachable;break; case "activity":s._tables.TbFishingEvent.DataList.Add(new());break;case "bad-mag":player.magnification=-1;break;} await s.RunAwaited();Check(player.Calls==0 && s.Continues==0 && Loop.Faults>0,"pre-consumption gate "+kind); } foreach(var kind in new[]{"fish","rod","map","mag","free","retry","duel","disabled","cancelled","fault"}){ s=Fresh();player=GContext.container.Player;var task=s.RunAwaited(); switch(kind){case "fish":s.fishingData.curFishData.ID++;break;case "rod":s.fishingData.RodId++;break; case "map":player.lastMapId++;break;case "mag":player.magnification++;break;case "free":s.fishingData.IsFree=true;break; case "retry":s.fishingData.IsRetry=true;break;case "duel":s.fishingData.IsDuel=true;break; case "disabled":s.isActiveAndEnabled=false;break;case "cancelled":s.kvFishingAction.Cancelled=true;break; case "fault":Loop.Ready=false;break;} player.Response.SetResult();await task;Check(player.Calls==1 && s.Continues==0,"no stale continuation "+kind); } s=Fresh();player=GContext.container.Player;var failed=s.RunAwaited();player.Response.SetException(new InvalidOperationException("Unknown"));await failed; Check(s.Continues==0 && player.Calls==1 && !Loop.Ready,"async exception observed, no retry"); s=Fresh();Loop.Enabled=false;s.Run();Check(s.LegacyCalls==1 && GContext.container.Player.Calls==0,"default paid PF path unchanged"); s.fishingData.IsFree=true;s.Run();Check(s.Continues==1,"default free PF path unchanged"); Console.WriteLine($"PASS {checks} assertions; compiled actual source methods; visual continuation and storage boundaries are spies; no network"); public enum NetworkReachability{NotReachable,Reachable} public static class Application{public static NetworkReachability internetReachability;} public enum ConditionType{ConsumeEnergy} public sealed class Fish{public int ID=1;} public sealed class Item{public int ID=1;public int SubType=1;} public sealed class FishingData{public Item fishItem=new();public Fish curFishData=new();public int RodId=1;public bool IsFree,IsRetry,IsDuel,Pack;public bool General=true;public bool IsGeneralFish()=>General;public bool IsPackItemFish()=>Pack;} public sealed class EnergyDef{public int Mag=3;} public sealed class EnergyTable{public List DataList=new(){new()};} public sealed class ConditionRule{public ConditionType Condition=ConditionType.ConsumeEnergy;} public sealed class Activity{public List ConditionList=new(){new()};} public sealed class ActivityTable{public List DataList=new();} public sealed class Tables{public EnergyTable TbEnergyDef=new();public ActivityTable TbFishingEvent=new();} public sealed class PlayerData{public int Calls,magnification,lastMapId;public TaskCompletionSource Response=new();public async Task ConsumeEnergyForKVLoopAsync(int n,Loop.FishingAction a){Calls++;await Response.Task;a.Confirmed=true;}} public sealed class Container{public PlayerData Player=new();public T Resolve()=>(T)(object)Player;} public static class GContext{public static Container container=new();} namespace game.PlayerDataStorage{public static class PlayerKVGameplayLoop{ public static void PrepareFishingReward(FishingAction a,FishingData d) {} public static bool Enabled,Ready;public static int Faults; public sealed class FishingAction{public bool Consuming,Cancelled,Confirmed,Continued;} public static bool FishingCurrent(FishingAction a)=>Ready && !a.Cancelled; public static bool ClaimFishingConsumption(FishingAction a){if(a.Consuming)return false;a.Consuming=true;return true;} public static InvalidOperationException Stop(string m){Fault(m);return new(m);} public static void Fault(string m){Ready=false;Faults++;} public static void ContinueFishing(FishingAction a,Action next){if(!FishingCurrent(a)||!a.Confirmed)throw Stop("invalid");if(a.Continued)return;a.Continued=true;next();} }}