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

XFEEDToolBox

【WinUI】XFE精英危险工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
using System.Buffers.Binary;
using XFEEDToolBox.Core.Galaxy;
using XFEEDToolBox.Core.Models;
using XFEEDToolBox.Core.Navigation;
using XFEEDToolBox.Core.Rendering;
using XFEExtension.NetCore.XUnit.Attributes;

namespace XFEEDToolBox.Test;

[TestFixture]
public class GalaxyDataTests
{
    private static byte[] Density()
    {
        var data=new byte[48+16*16*4];"XFEGDM2\0"u8.CopyTo(data);
        BinaryPrimitives.WriteInt32LittleEndian(data.AsSpan(8),16);BinaryPrimitives.WriteInt32LittleEndian(data.AsSpan(12),16);
        foreach(var (at,value) in new[]{(16,49985d),(24,24105d),(32,100000d),(40,100000d)})BinaryPrimitives.WriteDoubleLittleEndian(data.AsSpan(at),value);
        BinaryPrimitives.WriteSingleLittleEndian(data.AsSpan(48),.75f);return data;
    }
    [Test] public void GalaxyRasterPreservesOriginalFullGalaxyFrameAndRejectsCorruptPixels()
    {
        var data=Density();var map=GalaxyDensityMap.Parse(data);
        Check.Equal(49985d,map.OriginX);Check.Equal(24105d,map.OriginZ);Check.Equal(100000d,map.ExtentX);Check.That(map.FloatValues);
        Check.Equal(.75f,BinaryPrimitives.ReadSingleLittleEndian(map.Values));
        Check.Throws<InvalidDataException>(()=>GalaxyDensityMap.Parse(data[..^1]));
        BinaryPrimitives.WriteSingleLittleEndian(data.AsSpan(48),float.NaN);
        Check.Throws<InvalidDataException>(()=>GalaxyDensityMap.Parse(data));
        BinaryPrimitives.WriteSingleLittleEndian(data.AsSpan(48),1.01f);
        Check.Throws<InvalidDataException>(()=>GalaxyDensityMap.Parse(data));
    }
    [Test] public void OriginalDdsCubeRetainsSixFacesAndRejectsDepthOrPartialArrays()
    {
        var data=new byte[148+16*16*4*6];"DDS "u8.CopyTo(data);"DX10"u8.CopyTo(data.AsSpan(84));
        foreach(var (at,value) in new[]{(4,124),(12,16),(16,16),(28,1),(76,32),(128,28),(132,3),(136,4),(140,1)})
            BinaryPrimitives.WriteInt32LittleEndian(data.AsSpan(at),value);
        for(var i=0;i<6;i++)data[148+i*16*16*4]=(byte)i;
        var cube=GameSkyboxCube.Parse(data);Check.Equal(64,cube.RowPitch);Check.Equal(6,cube.Faces.Length);
        for(var i=0;i<6;i++)Check.Equal((byte)i,cube.Faces[i][0]);
        Check.Throws<InvalidDataException>(()=>GameSkyboxCube.Parse(data[..^1]));
        BinaryPrimitives.WriteInt32LittleEndian(data.AsSpan(128),40);
        Check.Throws<InvalidDataException>(()=>GameSkyboxCube.Parse(data));
        BinaryPrimitives.WriteInt32LittleEndian(data.AsSpan(128),28);BinaryPrimitives.WriteInt32LittleEndian(data.AsSpan(140),2);
        Check.Throws<InvalidDataException>(()=>GameSkyboxCube.Parse(data));
    }
    [Test] public void FuelDashesNeverAssumeRefuellingAndSupplyMarkersRequireActualScoop()
    {
        var ship=new ShipRecord{ShipId=7,ConfigurationAt=DateTimeOffset.UtcNow,Modules=[
            new(){Slot="FrameShiftDrive",Item="int_hyperdrive_size6_class5",Enabled=true},
            new(){Slot="Slot01_Size6",Item="int_fuelscoop_size6_class5",Enabled=true}]};
        var player=new PlayerState{CurrentShipId=7,Ships=[ship],Navigation=new(){CurrentSystemAddress=1,MainFuel=9,
            Route=[new(1,"Here",new(0,0,0),"G"),new(2,"Supply",new(10,0,0),"K"),new(3,"Neutron",new(20,0,0),"N"),new(4,"End",new(30,0,0),"M")]}};
        var overlay=NavigationFuelOverlay.Build(player,.5);
        Check.That(overlay.DashedLegs.SequenceEqual(new long[]{3,4}));Check.That(overlay.SupplySites.SequenceEqual(new long[]{1,2,4}));Check.Equal(2L,overlay.RecommendedSupply);
        var noScoop=NavigationFuelOverlay.Build(player with{Ships=[ship with{Modules=ship.Modules.Take(1).ToArray()}]},.5);
        Check.Equal(0,noScoop.SupplySites.Count);Check.That(noScoop.RecommendedSupply is null);
        Check.Equal(0,NavigationFuelOverlay.Build(player with{Navigation=player.Navigation with{Route=[]}},.5).DashedLegs.Count);
    }
    [Test] public void SkyInspectionSeparatesSparseStarsFromLongSceneEdges()
    {
        const int size=128;var pixels=new byte[size*size*4];
        for(var i=0;i<pixels.Length;i+=4){pixels[i]=pixels[i+1]=pixels[i+2]=12;pixels[i+3]=255;}
        for(var y=12;y<110;y+=23)for(var x=13;x<110;x+=29){var p=(y*size+x)*4;pixels[p]=pixels[p+1]=pixels[p+2]=240;}
        var stars=SkyboxPixels.Inspect(pixels,size,size);Check.That(stars.Mean>.001&&stars.LongestEdge<8&&stars.LargestEdgeComponent<32);
        for(var y=40;y<90;y++)for(var x=10;x<118;x++){var p=(y*size+x)*4;pixels[p]=pixels[p+1]=pixels[p+2]=160;}
        var scene=SkyboxPixels.Inspect(pixels,size,size);Check.That(scene.LongestEdge>80&&scene.LargestEdgeComponent>192);
        Check.Equal(0d,SkyboxPixels.Inspect(new byte[size*size*4],size,size).Mean);
    }
}