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

XFEEDToolBox

【WinUI】XFE精英危险工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
using System.Runtime.InteropServices;
using System.Text.Json;
using XFEEDToolBox.Core.Models;
using XFEEDToolBox.Core.Native;
using XFEEDToolBox.Core.Navigation;
using XFEEDToolBox.Core.Plugins;

internal static class CruiseControlAcceptance
{
    internal static async Task LoadAsync(int pid,string package,string report)
    {
        package=Path.GetFullPath(package);report=Path.GetFullPath(report);if(File.Exists(report))throw new IOException("Use a fresh original SCO control report.");
        using var timeout=new CancellationTokenSource(TimeSpan.FromSeconds(20));var token=timeout.Token;
        var hello=await new NavigationPipeClient(pid).CallAsync(new{op="describe"},token);
        if(hello.GetProperty("processId").GetInt32()!=pid||hello.GetProperty("gameSha256").GetString()!=NativeSystemLocationReader.GameSha256)
            throw new InvalidDataException("Original SCO control game identity differs.");
        var library=NativeLibrary.Load(Path.Combine(package,"XFEEDInteraction.dll"));
        var test=Marshal.GetDelegateForFunctionPointer<Probe>(NativeLibrary.GetExport(library,"XFECruiseControlSelfTest"));
        var start=Marshal.GetDelegateForFunctionPointer<Start>(NativeLibrary.GetExport(library,"XFEInteractionStart"));
        var masks=Enumerable.Range(0,8).Select(_=>test()).ToArray();
        if(masks.Any(mask=>mask!=4095)||start(0)!=0||start(nuint.MaxValue)!=0)throw new InvalidDataException("Original SCO controller fixtures failed.");
        await RuntimeInteractionModule.LoadAsync(pid,NativeSystemLocationReader.GameSha256,hello.GetProperty("owningThread").GetInt32(),package,token);
        var observed=await new NavigationPipeClient(pid,NativeCruiseControlChannel.Service).CallAsync(new{op="watch"},token);
        await File.WriteAllTextAsync(report,JsonSerializer.Serialize(new{at=DateTimeOffset.UtcNow,pid,loadProtocolPassed=true,fixtureMasks=masks,
            actualScoSampleReady=observed.GetProperty("sampleReady").GetBoolean(),controlQualified=observed.GetProperty("overchargeControlQualified").GetBoolean(),
            observed,inputsSentByProbe=0},ToolboxSettings.JsonOptions));
        Console.WriteLine(JsonSerializer.Serialize(new{pid,loadProtocolPassed=true,controlQualified=observed.GetProperty("overchargeControlQualified").GetBoolean(),report,inputsSentByProbe=0}));
    }
    internal static async Task ReadAsync(int pid,string report,bool watch)
    {
        if(File.Exists(report))throw new IOException("Preserve existing original SCO evidence.");
        var observed=await new NavigationPipeClient(pid,NativeCruiseControlChannel.Service).CallAsync(new{op=watch?"watch":"read"});
        await File.WriteAllTextAsync(report,JsonSerializer.Serialize(observed,ToolboxSettings.JsonOptions));
        Console.WriteLine(JsonSerializer.Serialize(new{pid,report,inputsSentByProbe=0}));
    }
    internal static async Task DeactivateAsync(int pid,string service,string report)
    {
        if(service is not("CruiseControl0514a" or "CruiseControl0514b" or "CruiseControl0514c" or "CruiseControl0514d")||File.Exists(report))throw new IOException("Use a known module and preserve previous SCO evidence.");
        var observed=await new NavigationPipeClient(pid,service).CallAsync(new{op="deactivate"});
        if(observed.GetProperty("enabled").GetBoolean()||observed.GetProperty("owned").GetBoolean())throw new InvalidDataException("Original SCO hook did not deactivate.");
        await File.WriteAllTextAsync(report,JsonSerializer.Serialize(observed,ToolboxSettings.JsonOptions));
        Console.WriteLine(JsonSerializer.Serialize(new{pid,service,report,deactivated=true,inputsSentByProbe=0}));
    }
    [UnmanagedFunctionPointer(CallingConvention.Winapi)]private delegate uint Probe();
    [UnmanagedFunctionPointer(CallingConvention.Winapi)]private delegate uint Start(nuint thread);
}