test(upserver): 归档存档迁移与玩法闭环回归工具
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
using System;using System.Threading.Tasks;using game.PlayerDataStorage;
|
||||
int checks=0;void Check(bool b,string m){checks++;if(!b)throw new Exception(m);}
|
||||
Controller Fresh(){PlayerKVGameplayLoop.Reset();UIManager.Instance=new();return new();}
|
||||
var c=Fresh();c.PiercingFish(3);c.PiercingFish(3);c.End();c.End();
|
||||
Check(c.Strikes==1&&c.Endings==1&&UIManager.Instance.Calls==1,"actual wrappers suppress repeated drawing/end");
|
||||
Check(PlayerKVGameplayLoop.Scope==null,"UI await never holds ending scope");
|
||||
c.Disable();UIManager.Instance.Response.SetResult(new object());await Task.Delay(20);
|
||||
Check(c.Destroyed==1&&PlayerKVGameplayLoop.Faults==1,"actual Disable during UI await disposes stale returned panel");
|
||||
c=Fresh();c.PiercingFish(3);c.Dead();Check(PlayerKVGameplayLoop.Cancelled,"actual Destroy revokes controller");
|
||||
c=Fresh();c.PiercingFish(3);c.fishingData.IsCaughtFish=false;c.End();Check(c.Endings==0&&UIManager.Instance.Calls==0,"natural failure cannot invoke reward core");
|
||||
foreach(int version in new[]{1,2}){c=Fresh();PlayerKVGameplayLoop.Version=version;c.PiercingFish(3);Check(c.Strikes==0&&PlayerKVGameplayLoop.Faults==1,"old permits do not draw");}
|
||||
c=Fresh();c.PiercingFish(3);PlayerKVGameplayLoop.Confirmed=true;c.Disable();Check(PlayerKVGameplayLoop.Faults==0,"confirmed controller normal disable no second fault");
|
||||
c=Fresh();PlayerKVGameplayLoop.Enabled=false;c.PiercingFish(3);c.End();Check(c.Strikes==1&&c.Endings==1,"ordinary PF wrapper takes original core");
|
||||
Console.WriteLine($"PASS actual controller source wrappers/lifecycle {checks} assertions; core/render/storage services are spies; no gameplay or network");
|
||||
public class Controller {
|
||||
public int Strikes,Endings,Destroyed;public FishingData fishingData=new();bool isFail;IDisposable disposables,_comboDisposable;object _hpcoroutine;
|
||||
public void End()=>FishEnd();public void Disable()=>OnDisable();public void Dead()=>OnDestroy();
|
||||
void PiercingFishCore(int zone){Strikes++;}void FishEndCore(){Endings++;}void Destroy(object p){Destroyed++;}
|
||||
void StopSoundCombo(){}void StopRodAudio(){}void StopNotReeling(){}void StopDrawingSplash(){}void AudioRelease(){}void SpSkillFxRelease(){}void StopAllCoroutines(){}
|
||||
public void PiercingFish(int waitingZone)
|
||||
{
|
||||
#if UNITY_EDITOR && !SERVICE_HOST
|
||||
if(game.PlayerDataStorage.PlayerKVGameplayLoop.Enabled)
|
||||
{
|
||||
try
|
||||
{
|
||||
if(!game.PlayerDataStorage.PlayerKVGameplayLoop.BeginRewardDrawing(this)) return;
|
||||
using(game.PlayerDataStorage.PlayerKVGameplayLoop.BeginRewardSegment("strike")) PiercingFishCore(waitingZone);
|
||||
}
|
||||
catch(System.Exception e) { game.PlayerDataStorage.PlayerKVGameplayLoop.Fault(e.Message); }
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
PiercingFishCore(waitingZone);
|
||||
}
|
||||
void FishEnd()
|
||||
{
|
||||
#if UNITY_EDITOR && !SERVICE_HOST
|
||||
if(game.PlayerDataStorage.PlayerKVGameplayLoop.Enabled)
|
||||
{
|
||||
try
|
||||
{
|
||||
if(!game.PlayerDataStorage.PlayerKVGameplayLoop.BeginRewardEnding(this,fishingData.IsCaughtFish && !isFail)) return;
|
||||
using(game.PlayerDataStorage.PlayerKVGameplayLoop.BeginRewardSegment("ending")) FishEndCore();
|
||||
_=ShowKVRewardPanelAsync();
|
||||
}
|
||||
catch(System.Exception e) { game.PlayerDataStorage.PlayerKVGameplayLoop.Fault(e.Message); }
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
FishEndCore();
|
||||
}
|
||||
async Task ShowKVRewardPanelAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
var panel=await UIManager.Instance.ShowUI(UITypes.FishingRewardPanel);
|
||||
if(!game.PlayerDataStorage.PlayerKVGameplayLoop.RewardRunCurrent && panel!=null) Destroy(panel);
|
||||
}
|
||||
catch(System.Exception e) { game.PlayerDataStorage.PlayerKVGameplayLoop.Fault(e.Message); }
|
||||
}
|
||||
private void OnDisable()
|
||||
{
|
||||
#if UNITY_EDITOR && !SERVICE_HOST
|
||||
game.PlayerDataStorage.PlayerKVGameplayLoop.CancelReward(this,"controller disabled");
|
||||
#endif
|
||||
|
||||
StopSoundCombo();
|
||||
StopRodAudio();
|
||||
StopNotReeling();
|
||||
StopDrawingSplash();
|
||||
GContext.container.Resolve<SoundMgr>().StopActiveFishingLoopSounds(0.05f);
|
||||
AudioRelease();
|
||||
SpSkillFxRelease();
|
||||
}
|
||||
private void OnDestroy()
|
||||
{
|
||||
#if UNITY_EDITOR && !SERVICE_HOST
|
||||
game.PlayerDataStorage.PlayerKVGameplayLoop.CancelReward(this,"controller destroyed");
|
||||
#endif
|
||||
|
||||
disposables?.Dispose();
|
||||
_comboDisposable?.Dispose();
|
||||
_hpcoroutine = null;
|
||||
StopAllCoroutines();
|
||||
}
|
||||
}
|
||||
public class FishingData{public bool IsCaughtFish=true;}public enum UITypes{FishingRewardPanel}
|
||||
public class UIManager{public static UIManager Instance=new();public int Calls;public TaskCompletionSource<object> Response=new();public Task<object> ShowUI(UITypes type){Calls++;return Response.Task;}}
|
||||
public static class GContext{public static Container container=new();}public class Container{public T Resolve<T>() where T:new()=>new();}public class SoundMgr{public void StopActiveFishingLoopSounds(float x){}}
|
||||
namespace game.PlayerDataStorage {public static class PlayerKVGameplayLoop{
|
||||
public static bool Enabled,Drawing,Ending,Cancelled,Confirmed;public static int Version,Faults;public static string Scope;
|
||||
public static void Reset(){Enabled=true;Drawing=Ending=Cancelled=Confirmed=false;Version=3;Faults=0;Scope=null;}
|
||||
public static bool RewardRunCurrent=>!Cancelled;
|
||||
public static bool BeginRewardDrawing(object o){if(Version!=3||Cancelled)throw new Exception("no draw");if(Drawing)return false;Drawing=true;return true;}
|
||||
public static bool BeginRewardEnding(object o,bool success){if(Ending)return false;if(!success)throw new Exception("failed catch");Ending=true;return true;}
|
||||
public static IDisposable BeginRewardSegment(string n){Scope=n;return new Batch();}class Batch:IDisposable{public void Dispose(){Scope=null;}}
|
||||
public static void Fault(string s){Faults++;}public static void CancelReward(object o,string r){if(Cancelled)return;Cancelled=true;if(!Confirmed)Fault(r);}
|
||||
}}
|
||||
Reference in New Issue
Block a user