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;
using System.Text.Json;
using XFEExtension.NetCore.XUnit.Attributes;
using XFEEDToolBox.Core.Session;

namespace XFEEDToolBox.Test;

[TestFixture]
public class NativeRelogCapabilityTests
{
    private static async Task Serve(int pid,object[] responses,List<string> commands,CancellationToken token)
    {
        foreach(var response in responses)
        {
            await using var pipe=new NamedPipeServerStream($"XFEEDToolBox.Navigation.{pid}",PipeDirection.InOut,1,PipeTransmissionMode.Byte,PipeOptions.Asynchronous);
            await pipe.WaitForConnectionAsync(token);var buffer=new byte[4096];var count=await pipe.ReadAsync(buffer,token);
            using var request=JsonDocument.Parse(buffer.AsMemory(0,count));commands.Add(request.RootElement.GetProperty("op").GetString()!);
            await pipe.WriteAsync(Encoding.UTF8.GetBytes(JsonSerializer.Serialize(new{ok=true,result=response})+"\n"),token);await pipe.FlushAsync(token);
            pipe.WaitForPipeDrain();
        }
    }
    private static object Hello(int pid)=>new{processId=pid,gameSha256=NativeRelogChannel.SupportedGameSha256,nativeRelog=true};
    [Test] public async Task EntryCapabilityCannotMutateTheUnverifiedReturnToMenuPath()
    {
        var pid=Random.Shared.Next(20000000,29000000);using var stop=new CancellationTokenSource(TimeSpan.FromSeconds(5));var commands=new List<string>();
        var server=Serve(pid,[Hello(pid)],commands,stop.Token);var channel=new NativeRelogChannel(pid,NativeRelogChannel.SupportedGameSha256);
        var refused=false;try{await channel.BeginAsync(Guid.NewGuid().ToString("N"),stop.Token);}catch(NotSupportedException){refused=true;}
        await server;Check.That(refused);Check.Equal("describe",string.Join(',',commands));
    }
    [Test] public async Task VerifiedMenuEntryRemainsAvailableWithoutAClaimAboutMenuReturn()
    {
        var pid=Random.Shared.Next(20000000,29000000);using var stop=new CancellationTokenSource(TimeSpan.FromSeconds(5));var commands=new List<string>();
        var server=Serve(pid,[Hello(pid),new{schema=1,name="XFEEDToolBox.Session",processId=pid,gameSha256=NativeRelogChannel.SupportedGameSha256}],commands,stop.Token);
        await new NativeRelogChannel(pid,NativeRelogChannel.SupportedGameSha256,entryOnly:true).BeginAsync(Guid.NewGuid().ToString("N"),stop.Token);
        await server;Check.Equal("describe,session.begin",string.Join(',',commands));
    }
    [Test] public async Task StartupNoticePreparationCannotRunDuringReleaseOrAfterCancellation()
    {
        var pid=Random.Shared.Next(20000000,29000000);using var stop=new CancellationTokenSource(TimeSpan.FromSeconds(5));var commands=new List<string>();var preparations=0;
        var response=new{schema=1,name="XFEEDToolBox.Session",processId=pid,gameSha256=NativeRelogChannel.SupportedGameSha256};
        var server=Serve(pid,[Hello(pid),response,response],commands,stop.Token);
        var channel=new NativeRelogChannel(pid,NativeRelogChannel.SupportedGameSha256,entryOnly:true,prepareEntry:_=>{preparations++;return Task.CompletedTask;});
        await channel.BeginAsync("owner",stop.Token);await channel.EndAsync("owner");await server;
        Check.Equal(1,preparations);Check.Equal("describe,session.begin,session.end",string.Join(',',commands));
        using var cancelled=new CancellationTokenSource();cancelled.Cancel();var refused=false;
        try{await channel.BeginAsync("other",cancelled.Token);}catch(OperationCanceledException){refused=true;}
        Check.That(refused);Check.Equal(1,preparations);
    }
}