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

XFEEDToolBox

【WinUI】XFE精英危险工具箱

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

namespace XFEEDToolBox.Test;

[TestFixture]
public sealed class NativeDepartureEntryCleanupTests
{
    [Test]public async Task DirectAndDelegatedPublicDepartureEntriesReleaseTheirOwnObservationClaimAfterCancellation()
    {
        foreach(var delegated in new[]{false,true})foreach(var continuation in new[]{false,true})
        {
            var pid=Random.Shared.Next(200000000,290000000);var hash=new string('a',64);var released=0;string? claimedOwner=null;
            var state=new PlayerState{InGame=true,Docked=!continuation,CommanderId="F1",CurrentShipId=7,LoadGameAt=DateTimeOffset.UtcNow.AddMinutes(-1),
                Navigation=new(){CurrentSystemAddress=1},Ships=[new(){ShipId=7,Type="type9",Modules=[new(){Slot="Slot01",Item="int_dockingcomputer_advanced",Enabled=true}]}]};
            using var serverStop=new CancellationTokenSource(TimeSpan.FromSeconds(5));
            var server=Task.Run(async()=>
            {
                while(!serverStop.IsCancellationRequested)
                {
                    try
                    {
                        await using var pipe=new NamedPipeServerStream($"XFEEDToolBox.Navigation.{pid}",PipeDirection.InOut,1,PipeTransmissionMode.Byte,PipeOptions.Asynchronous);
                        await pipe.WaitForConnectionAsync(serverStop.Token);var buffer=new byte[8192];var count=await pipe.ReadAsync(buffer,serverStop.Token);
                        using var document=JsonDocument.Parse(buffer.AsMemory(0,count));var request=document.RootElement;var op=request.GetProperty("op").GetString();object result;
                        if(op=="describe")result=new{schema=1,name="XFEEDToolBox.Navigation",processId=pid,gameSha256=hash,verified=true,owningThread=1,localTargets=true,evidence="isolated cleanup fixture"};
                        else if(op=="local.select")
                        {
                            claimedOwner=request.GetProperty("owner").GetString();
                            result=new{generation=1,selected=true,target=new{key=request.GetProperty("key").GetInt32(),bodyAddress=request.GetProperty("bodyAddress").GetString(),
                                kind=request.GetProperty("kind").GetInt32(),marketId=request.GetProperty("marketId").GetUInt32(),name=request.GetProperty("name").GetString()}};
                        }
                        else if(op=="release")
                        {Check.That(claimedOwner is not null&&request.GetProperty("owner").GetString()==claimedOwner);released++;result=new{released=true};}
                        else throw new InvalidOperationException("Cancellation cleanup sent an unexpected flight command: "+op);
                        await pipe.WriteAsync(JsonSerializer.SerializeToUtf8Bytes(new{ok=true,result}),serverStop.Token);await pipe.WriteAsync(new byte[]{10},serverStop.Token);
                        if(OperatingSystem.IsWindows())pipe.WaitForPipeDrain();
                    }
                    catch(OperationCanceledException)when(serverStop.IsCancellationRequested){break;}
                }
            });
            var local=new NativeSystemFlightControlDriver(pid,hash,()=>state);
            var galaxy=new NativeFlightControlDriver(pid,hash,()=>state);
            ISystemFlightControlDriver selection=delegated?galaxy:local;IFlightDepartureDriver departure=delegated?galaxy:local;
            try
            {
                await selection.SelectAsync(new(1,101,"Body",SystemTargetKind.Orbit){NativeKey=7,NativeKind=1,NativeIdentity=hash},serverStop.Token);
                using var userStop=new CancellationTokenSource();userStop.Cancel();var cancelled=false;
                try
                {
                    if(continuation)await departure.EnsureDepartureClearanceAsync(null,userStop.Token);
                    else await departure.DepartAsync(userStop.Token);
                }
                catch(OperationCanceledException){cancelled=true;}
                Check.That(cancelled);Check.Equal(1,released);
            }
            finally{serverStop.Cancel();await server;}
        }
    }
}