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;

namespace XFEEDToolBox.Plugin;

internal static unsafe partial class Navigation
{
    static uint GalaxyAllegianceDefinitionsSelfTest()
    {
        var memory=Platform.Allocate(0x30000);if(memory==0)return 0;
        try
        {
            var expectedImage=memory+0x20000-0x51BBA70;var owner=memory+0x1000;var source=owner+0x58;
            Write(owner,expectedImage+0x51BB940);Write(owner+8,expectedImage+0x51BB970);
            Write(source,expectedImage+0x51BBA70);Write(source+8,expectedImage+0x51BBB60);
            var slots=new(nuint offset,nuint function)[]{(0,0x140EA90),(0x18,0x140F240),(0x20,0x140EC60),(0x48,0x1410000),(0x50,0x140FE60)};
            foreach(var (offset,function) in slots)Write(expectedImage+0x51BBA70+offset,expectedImage+function);
            var offsets=new nuint[]{0x80,0xA8,0xC8,0xE8,0x108,0x128};var node=memory+0x4000;var control=memory+0x5000;var definition=memory+0x6000;var text=memory+0x7000;
            void Reset()
            {
                for(var i=0;i<offsets.Length;i++)
                {
                    var map=source+offsets[i];var buckets=memory+0x8000+(nuint)i*0x100;
                    Write(map,buckets);Write(map+8,17UL);Write(map+0x18,0UL);
                    for(nuint n=0;n<17;n++)Write(buckets+n*8,buckets+n*8);
                }
            }
            void Put(ulong id,string key,int mapIndex=0)
            {
                Reset();var map=source+offsets[mapIndex];var buckets=Pointer(map);
                var hash=mapIndex==5?GalaxyAllegianceLegacyHash((uint)id):GalaxyFactHash(id);var sentinel=buckets+(nuint)(hash%17)*8;
                Write(map+0x18,1UL);Write(sentinel,node);Write(node,sentinel);Write(node+8,id);Write(node+0x10,control);Write(node+0x18,definition);
                Write(control+0xC,1);Write(definition,id);Write(definition+8,text);Write(definition+0x18,(byte)1);
                Write(text,(ulong)key.Length);Write(text+8,(ulong)key.Length);Write(text+0x10,1);Platform.WriteBytes(text+20,Encoding.UTF8.GetBytes(key+"\0"));
            }
            bool Copy(ulong id,out string? key)=>CopyGalaxyAllegianceKey(source,expectedImage,id,out key);
            uint passed=0;var keys=new[]{"None","Federation","Empire","Alliance","Independent"};var all=true;
            for(var i=0;i<keys.Length;i++){var id=9007199254740995UL+(ulong)i;Put(id,keys[i],i);all&=Copy(id,out var key)&&key==keys[i];}
            if(all)passed|=1;
            const ulong address=9007199254740995UL;Put(address,"Federation");
            if(Copy(address,out var result)&&result=="Federation"&&Copy(address+(1UL<<32),out result)&&result is null)passed|=2;
            Reset();if(Copy(ulong.MaxValue,out result)&&result=="None"&&Copy(123,out result)&&result is null)passed|=4;
            Put(address,"Federation");Write(definition+0x18,(byte)0);
            if(Copy(address,out result)&&result is null)passed|=8;
            Put(address,"Federation");Write(control+0xC,0);
            if(Copy(address,out result)&&result is null)passed|=16;
            Put(address,"Some private faction");if(Copy(address,out result)&&result is null)passed|=32;
            Put(address,"Empire",5);if(Copy(address,out result)&&result=="Empire")passed|=64;
            if(Copy(address+(1UL<<32),out result)&&result is null)passed|=128;
            Put(0,"Alliance");if(Copy(0,out result)&&result=="Alliance")passed|=256;
            Put(address,"Federation");var tables=true;
            foreach(var (at,table) in new[]{(owner,expectedImage+0x51BB940),(owner+8,expectedImage+0x51BB970),(source,expectedImage+0x51BBA70),(source+8,expectedImage+0x51BBB60)})
            {Write(at,table+8);tables&=!Copy(address,out _);Write(at,table);}if(tables)passed|=512;
            var getters=true;
            foreach(var (offset,function) in slots)
            {Write(expectedImage+0x51BBA70+offset,expectedImage+function+1);getters&=!Copy(address,out _);Write(expectedImage+0x51BBA70+offset,expectedImage+function);}if(getters)passed|=1024;
            Put(address,"Federation");Write(node+8,address+1);Write(node,node);
            if(!Copy(address,out _))passed|=2048;
            Put(address,"Federation");Write(definition,address+1);
            if(Copy(address,out result)&&result is null)passed|=4096;
            Put(address,"Federation");Write(text+8,1UL);var strings=Copy(address,out result)&&result is null;
            Put(address,"Federation");Write(text+0x10,0);strings&=Copy(address,out result)&&result is null;if(strings)passed|=8192;
            Reset();Write(source+0x80+8,0UL);var malformed=!Copy(address,out _);
            Reset();Write(source+0x80+0x18,4_000_001UL);malformed&=!Copy(address,out _);if(malformed)passed|=16384;
            Put(address,"Independent");var before=Platform.ReadBytes(memory,0x30000);
            if(Copy(address,out result)&&result=="Independent"&&!CopyGalaxyAllegianceKey(0,expectedImage,address,out _)&&
               !CopyGalaxyAllegianceKey(source,expectedImage+8,address,out _)&&Platform.ReadBytes(memory,0x30000).AsSpan().SequenceEqual(before))passed|=32768;
            return passed;
        }
        finally{Platform.Free(memory);}
    }
#if PLUGIN_NAVIGATION
    [UnmanagedCallersOnly(EntryPoint="XFENavigationGalaxyAllegianceDefinitionsSelfTest")]
    internal static uint ExportGalaxyAllegianceDefinitionsSelfTest()=>RunTest(GalaxyAllegianceDefinitionsSelfTest);
#endif
}