XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEEDToolBox

【WinUI】XFE精英危险工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
using System.Text.Json;
using System.Text.Json.Nodes;
using XFEEDToolBox.Core.Navigation;
using XFEExtension.NetCore.XUnit.Attributes;

namespace XFEEDToolBox.Test;

[TestFixture]
public sealed class ScoTrialFallbackContinuationTests
{
    private static readonly DateTimeOffset Now=DateTimeOffset.FromUnixTimeMilliseconds(2000);
    private static readonly ScoTrialContinuationContext Context=new(42,new('a',64),new('b',64),10,20,1,3,100,10000,0);
    private static JsonObject Status()
    {
        var choice=new ScoExitApproachDecision{Entity=10,World=20,TargetKey=3,At=1899,TrialExpiresAt=10000,SourceSpeed=20*299792458d,
            Mode="trial",Reason=ScoExitApproachDecision.OutsideCalibrationReason,UseEstimatedStop=false};
        return new()
        {
            ["enabled"]=true,["processId"]=42,["service"]=CruiseControlProtocol.Service,["gameSha256"]=Context.GameSha256,["sampleReady"]=true,["owned"]=false,
            ["sample"]=new JsonObject{["verified"]=true,["inSupercruise"]=true,["rawFsdState"]=2,["state"]=0,["entityId"]="10",["referenceWorldAddress"]="20",
                ["observedAtUnixMilliseconds"]=2000,["originalUpdateClockEpoch"]=1,["originalUpdateCompletedSteps"]=160,["originalUpdateClockValid"]=true,["playerOverride"]=false,["healthEmergency"]=false,
                ["target"]=new JsonObject{["key"]=3}},
            ["scoExitEstimate"]=new JsonObject{["mode"]="bounded-trial",["trialExpiresAtUnixMilliseconds"]=10000,["maximumTrialBurstsRemaining"]=1,
                ["trialBurstActive"]=false,["proofAvailable"]=true,["currentSourceDomainVerified"]=true,["currentParameterBindingVerified"]=true,
                ["trustedLoadoutFingerprint"]=Context.LoadoutFingerprint,["lastPolicyRevocationFailure"]=null,
                ["lastExitReceipt"]=new JsonObject{["pass"]=true,["trial"]=false,["production"]=false,["reason"]="same-binding-shadow-completed",
                    ["entityId"]="10",["referenceWorldAddress"]="20",["clockEpoch"]=1,["targetKey"]=3,["startCompletedSteps"]=120,["endCompletedSteps"]=160,["integratedPathDistanceMetres"]=1000}},
            ["lastOriginalStop"]=new JsonObject{["nativeMethodCalled"]=true,["argument"]=false,["nativeMethodRva"]="2eaacd0",["reason"]="approach-or-alignment",
                ["stateBefore"]=2,["stateAfter"]=3,["entityId"]="10",["referenceWorldAddress"]="20",["observedAtUnixMilliseconds"]=1900,
                ["gate"]=new JsonObject{["identityVerified"]=true,["targetVerified"]=true,["geometryVerified"]=true,["emergency"]=false,["collisionCourse"]=false,["assistEnabled"]=false,
                    ["aimErrorDegrees"]=0,["cruiseParametersVerified"]=true,["cruiseApproachSeconds"]=6,["distanceMetres"]=240*299792458d,["speedMetresPerSecond"]=20*299792458d,
                    ["heatPercent"]=30,["thermalForecast"]=new JsonObject{["known"]=true,["shouldStop"]=false},["currentFrameGrossHeatBoundKnown"]=true,["currentFrameGrossHeatPeakPercent"]=31,
                    ["mainFuelTonnes"]=32,["fuelCapacityTonnes"]=128,["requiredFuelReserveTonnes"]=8,["fuelRateUpperTonnesPerSecond"]=1,["scoExitApproach"]=choice.Json()}}
        };
    }
    private static bool Allowed(JsonObject status,ScoTrialContinuationContext? context=null)
        =>ScoTrialFallbackContinuation.CanContinue(JsonSerializer.SerializeToElement(status),context??Context,Now,out _);
    [Test]public void OneNewCompleteDomainFallbackMayUseOnlyTheAlreadyRemainingBurst()
    {
        Check.That(Allowed(Status()));Check.That(!Allowed(Status(),Context with{CompletedFallbacks=1}));
        Check.That(!Allowed(Status(),Context with{ConsumedReceiptSteps=160}));Check.That(!Allowed(Status(),Context with{OriginalTrialDeadline=10001}));
        Check.That(!Allowed(Status(),Context with{OriginalTrialDeadline=2000}));
    }
    [Test]public void HeatAlignmentNonDistanceAndUnknownStopsCannotCountAsDomainFallbacks()
    {
        foreach(var bad in new[]{"heat","alignment","distance","unclassified","estimated","non-native","wrong-state","low-fuel","thermal-unknown"})
        {
            var node=Status();var stop=node["lastOriginalStop"]!;var gate=stop["gate"]!;
            if(bad=="heat")gate["thermalForecast"]!["shouldStop"]=true;
            else if(bad=="alignment")gate["aimErrorDegrees"]=7;
            else if(bad=="distance")gate["distanceMetres"]=300*299792458d;
            else if(bad=="unclassified")gate["scoExitApproach"]!["reason"]="bounded-trial-armed";
            else if(bad=="estimated")gate["scoExitApproach"]!["useEstimatedStop"]=true;
            else if(bad=="non-native")stop["nativeMethodCalled"]=false;
            else if(bad=="wrong-state")stop["stateAfter"]=0;
            else if(bad=="low-fuel")gate["mainFuelTonnes"]=8;
            else gate.AsObject().Remove("thermalForecast");
            Check.That(!Allowed(node));
        }
    }
    [Test]public void TheOriginalAuthorizationSourceAndBindingMustStillBeCurrent()
    {
        foreach(var bad in new[]{"deadline","no-burst","extra-bursts","revoked","unknown-revocation","source","world","epoch","manual","old-sample","foreign-fit"})
        {
            var node=Status();var policy=node["scoExitEstimate"]!;var sample=node["sample"]!;
            if(bad=="deadline")policy["trialExpiresAtUnixMilliseconds"]=10001;
            else if(bad=="no-burst")policy["maximumTrialBurstsRemaining"]=0;
            else if(bad=="extra-bursts")policy["maximumTrialBurstsRemaining"]=2;
            else if(bad=="revoked")policy["lastPolicyRevocationFailure"]=new JsonObject{["reason"]="source"};
            else if(bad=="unknown-revocation")policy.AsObject().Remove("lastPolicyRevocationFailure");
            else if(bad=="source")policy["currentSourceDomainVerified"]=false;
            else if(bad=="world")sample["referenceWorldAddress"]="21";
            else if(bad=="epoch")sample["originalUpdateClockEpoch"]=2;
            else if(bad=="manual")sample["playerOverride"]=true;
            else if(bad=="old-sample")sample["observedAtUnixMilliseconds"]=1799;
            else policy["trustedLoadoutFingerprint"]=new string('c',64);
            Check.That(!Allowed(node));
        }
    }
    [Test]public void FailedForeignOrAlreadyConsumedReceiptsCannotContinueTheTrial()
    {
        foreach(var bad in new[]{"failed","trial","production","old-start","bad-end","foreign-target","foreign-stop","old-choice"})
        {
            var node=Status();var receipt=node["scoExitEstimate"]!["lastExitReceipt"]!;
            if(bad=="failed")receipt["pass"]=false;
            else if(bad=="trial")receipt["trial"]=true;
            else if(bad=="production")receipt["production"]=true;
            else if(bad=="old-start")receipt["startCompletedSteps"]=100;
            else if(bad=="bad-end")receipt["endCompletedSteps"]=120;
            else if(bad=="foreign-target")receipt["targetKey"]=4;
            else if(bad=="foreign-stop")node["lastOriginalStop"]!["entityId"]="11";
            else node["lastOriginalStop"]!["gate"]!["scoExitApproach"]!["observedAtUnixMilliseconds"]=1600;
            Check.That(!Allowed(node));
        }
    }
}