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

XFEEDToolBox

【WinUI】XFE精英危险工具箱

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

namespace XFEEDToolBox.Test;

[TestFixture]
public class NativeSystemOrbitReaderTests
{
    private const ulong Resource=0x20000,Body=0x30000,Parent=0x40000,Transforms=0x50000;
    private const ulong ChildAddress=(2UL<<55)|7,ParentAddress=(1UL<<55)|7;
    private static readonly DateTimeOffset At=DateTimeOffset.Parse("2026-10-25T10:00:00Z");
    private sealed class Memory:IReadOnlyGameMemory
    {
        public ulong ImageBase=>0x100000000;public ulong ImageSize=>0x7000000;
        private readonly Dictionary<ulong,byte> bytes=[];public Action<ulong>? BeforeRead;
        public byte[] Read(ulong at,int length){BeforeRead?.Invoke(at);return Enumerable.Range(0,length).Select(i=>bytes.GetValueOrDefault(at+(ulong)i)).ToArray();}
        public void Put(ulong at,byte[] data){for(var i=0;i<data.Length;i++)bytes[at+(ulong)i]=data[i];}
        public void Q(ulong at,ulong value)=>Put(at,BitConverter.GetBytes(value));
        public void U(ulong at,uint value)=>Put(at,BitConverter.GetBytes(value));
        public void D(ulong at,double value)=>Put(at,BitConverter.GetBytes(value));
        public void V(ulong at,Vector3d value){D(at,value.X);D(at+8,value.Y);D(at+16,value.Z);}
        public void Frame(ulong at,Vector3d x,Vector3d y,Vector3d z,Vector3d position)
        {V(at,x);V(at+0x20,y);V(at+0x40,z);V(at+0x60,position);}
    }
    private static Memory Scene()
    {
        var m=new Memory();
        // Original instructions independently copied from the pinned PE proof.
        m.Put(m.ImageBase+0x29EB59A,Convert.FromHexString("410f108f300100000f540dd7f43f02660f2f0dafac730276754d8d4770450fb6ce488d542468498bcde828190000"));
        m.Put(m.ImageBase+0x3D00FA0,Convert.FromHexString("48895c2408574883ec30488bd90f297424204883c170498bf90f28f1e8ff936bfe"));
        m.Put(m.ImageBase+0x23BA7A7,Convert.FromHexString("4c8d87800100000f28050b6fa202488d542440"));
        m.Put(m.ImageBase+0x3D0180D,Convert.FromHexString("49039e88030000488bd3e824ffbbfc"));
        m.Q(Body,m.ImageBase+0x553F860);m.Q(m.ImageBase+0x553F880,m.ImageBase+0x3D00FA0);
        m.Q(Body+0x18,ChildAddress);m.U(Body+0x20,2);m.Q(Body+0x378,Resource);m.Q(Body+0x350,Parent);
        m.D(Body+0x70,.3);m.D(Body+0x90,.4);m.D(Body+0xB0,.5);m.D(Body+0x130,86400);m.D(Body+0x150,.2);m.D(Body+0x170,1000);
        m.Frame(Body+0x1F0,new(1,0,0),new(0,1,0),new(0,0,1),Vector3d.Zero);
        m.Q(Parent+0x18,ParentAddress);m.Q(Parent+0x378,Resource);m.U(Parent+0x384,1);m.Q(Resource+0x380,2);m.Q(Resource+0x388,Transforms);
        // Parent orbit frame rotates90degrees; independent spin (+80) is a
        // different rotation that the orbit reader must not accidentally add.
        m.Frame(Transforms+0x180+0x100,new(0,1,0),new(-1,0,0),new(0,0,1),new(10000,20000,30000));
        m.Frame(Transforms+0x180+0x80,new(0,0,-1),new(0,1,0),new(1,0,0),Vector3d.Zero);
        return m;
    }
    private static SystemLocation Child=>new(1,ChildAddress,"Fixture planet","",3,SystemLocationCategory.Planet,null,
        new(10000,19800,30000+1000*Math.Sqrt(.96)),null,false,"child-identity");
    private static SystemLocation ParentLocation=>new(2,ParentAddress,"Fixture star","",1,SystemLocationCategory.Star,null,
        new(10000,20000,30000),null,false,"parent-identity");
    private static SystemOrbit Read(Memory memory,IReadOnlyList<SystemLocation>? locations=null)
        =>NativeSystemOrbitReader.Read(memory,Resource,7,At,locations??[Child],id=>id==ChildAddress?Body:id==ParentAddress?Parent:0).First();
    [Test]public void OriginalOrbitAxesComposeWithParentOrbitFrameWithoutTheIndependentSpin()
    {
        var orbit=Read(Scene(),[Child,ParentLocation]);Check.That(orbit.Renderable);Check.Equal(SystemOrbitQuality.NativeVerified,orbit.Quality);
        Check.Equal(new Vector3d(0,1,0),orbit.PeriapsisDirection);Check.Equal(new Vector3d(0,0,1),orbit.TransverseDirection);
        Check.Equal(ParentLocation.Position,orbit.ParentPosition);Check.Equal("parent-identity",orbit.ParentIdentity);
        Check.Equal(1000d,orbit.SemiMajorAxisMetres);Check.Equal(.2,orbit.Eccentricity);Check.Equal(86400d,orbit.PeriodSeconds);
        Check.That(Math.Abs(orbit.OrbitalInclinationDegrees!.Value-.3*180/Math.PI)<1e-10);
    }
    [Test]public void ARealParentFrameWithoutACatalogueRowSuppliesAFocusWithoutInventingASelectableBody()
    {
        var orbit=Read(Scene());Check.That(orbit.Renderable);Check.Equal(ParentAddress,orbit.ParentWorldAddress);
        Check.Equal("native-body:7:"+ParentAddress,orbit.ParentIdentity);Check.That(orbit.ParentPosition is {Finite:true});
        Check.That(!orbit.ParentIsBarycentre);Check.Equal("原生父焦点",orbit.ParentName);
    }
    [Test]public void CarriersAndPoisSharingAParentsReferenceWorldAreNotItsCelestialIdentity()
    {
        var carrier=ParentLocation with{Category=SystemLocationCategory.Carrier,Name="Carrier",Identity="carrier",Position=new(11000,21000,31000)};
        var signal=carrier with{Category=SystemLocationCategory.Signal,Identity="signal"};
        var orbit=Read(Scene(),[Child,carrier,ParentLocation,signal]);
        Check.That(orbit.Renderable);Check.Equal("parent-identity",orbit.ParentIdentity);Check.Equal(ParentLocation.Position,orbit.ParentPosition);
    }
    [Test]public void UnknownLayoutAndWrongBodyKindsCannotAuthorizeOrbitGeometry()
    {
        var m=Scene();m.Put(m.ImageBase+0x23BA7A7,[0]);
        Check.Equal(0,NativeSystemOrbitReader.Read(m,Resource,7,At,[Child],_=>Body).Count);
        m=Scene();m.U(Body+0x20,7);Check.That(!Read(m).Renderable);
        m=Scene();m.Q(Body,m.ImageBase+0x553F908);Check.That(!Read(m).Renderable);
    }
    [Test]public void AFiniteEllipseInTheWrongFrameOrWithConflictingParentIdentityIsRejected()
    {
        var m=Scene();m.Frame(Body+0x1F0,new(0,1,0),new(-1,0,0),new(0,0,1),Vector3d.Zero);
        Check.That(!Read(m).Renderable);
        Check.That(!Read(Scene(),[Child,ParentLocation with{Position=new(10002,20000,30000)}]).Renderable);
        Check.That(!Read(Scene(),[Child,ParentLocation,ParentLocation with{Identity="duplicate"}]).Renderable);
        Check.That(!Read(Scene(),[Child with{Position=Child.Position!.Value+new Vector3d(2000,0,0)}]).Renderable);
    }
    [Test]public void ChangedResourceOrElementsDuringReadCannotPublishVerifiedOrbit()
    {
        var m=Scene();var reads=0;m.BeforeRead=at=>{if(at==Body+0x70&&++reads==2)m.D(Body+0x170,2000);};
        Check.That(!Read(m).Renderable);
        m=Scene();m.Q(Parent+0x378,Resource+8);Check.That(!Read(m).Renderable);
        m=Scene();m.D(Body+0x150,1);Check.That(!Read(m).Renderable);
        m=Scene();m.D(Body+0x170,double.NaN);Check.That(!Read(m).Renderable);
    }
}