using System.IO.Compression; using System.Security.Cryptography; using System.Text.Json; using XFEEDToolBox.Core.Models; namespace XFEEDToolBox.Core.Rendering; public sealed record GalaxyOriginalZone(int Id,string Name,int Pixels,Coordinates Position,int[] PixelBounds); /// The original 42-region GZM. These are geographic annotations, never stellar catalogue rows. public sealed class GalaxyOriginalZoneMap { private readonly byte[] values; public int Width {get;} public int Height {get;} public int ScaleX {get;} public int ScaleZ {get;} public double OriginX {get;} public double OriginZ {get;} public string SourceSha256 {get;} public string RasterSha256 {get;} public ReadOnlyMemory Values=>values; public IReadOnlyList Zones {get;} internal GalaxyOriginalZoneMap(JsonElement metadata,byte[] raster) { Width=metadata.GetProperty("width").GetInt32();Height=metadata.GetProperty("height").GetInt32(); ScaleX=metadata.GetProperty("scaleX").GetInt32();ScaleZ=metadata.GetProperty("scaleZ").GetInt32(); var origin=metadata.GetProperty("sourceOrigin");OriginX=origin[0].GetDouble();OriginZ=origin[2].GetDouble(); SourceSha256=metadata.GetProperty("sourceSha256").GetString()!;RasterSha256=metadata.GetProperty("rasterSha256").GetString()!; if(Width!=2048||Height!=2048||ScaleX!=83||ScaleZ!=83||raster.Length!=Width*Height|| !string.Equals(Convert.ToHexStringLower(SHA256.HashData(raster)),RasterSha256,StringComparison.Ordinal))throw new InvalidDataException("原银河区域图校验失败。"); values=raster;Zones=JsonSerializer.Deserialize(metadata.GetProperty("zones"),ToolboxSettings.JsonOptions)??[]; if(Zones.Count!=42||!Zones.Select(z=>z.Id).SequenceEqual(Enumerable.Range(1,42))||Zones.Any(z=>string.IsNullOrWhiteSpace(z.Name)||!z.Position.IsValid))throw new InvalidDataException("原银河区域名称无效。"); } public double WorldX(double pixel)=>pixel*4096/ScaleX-OriginX; public double WorldZ(double pixel)=>pixel*4096/ScaleZ-OriginZ; public int? IdAt(Coordinates position) { if(!position.IsValid)return null; var rawX=Math.Round((position.X+OriginX)*32,MidpointRounding.AwayFromZero);var rawZ=Math.Round((position.Z+OriginZ)*32,MidpointRounding.AwayFromZero); if(rawX<0||rawZ<0||rawX>=1L<<25||rawZ>=1L<<25)return null; // Preserve the original 3897C10 unsigned fixed-point arithmetic. var x=((ulong)(uint)((uint)rawX<<7)*(uint)ScaleX>>24)&0xfffff; var z=((ulong)(uint)((uint)rawZ<<7)*(uint)ScaleZ>>24)&0xfffff; return x<(ulong)Width&&z<(ulong)Height?values[(int)z*Width+(int)x]:null; } public GalaxyOriginalZone? At(Coordinates position)=>IdAt(position) is >0 and var id?Zones[id-1]:null; } public static class GalaxyOriginalZones { public static GalaxyOriginalZoneMap Reference {get;}=Read(); private static GalaxyOriginalZoneMap Read() { var assembly=typeof(GalaxyOriginalZones).Assembly; using var metadata=assembly.GetManifestResourceStream("XFEEDToolBox.Core.Rendering.original-galactic-zones.json")!; using var json=JsonDocument.Parse(metadata); using var compressed=assembly.GetManifestResourceStream("XFEEDToolBox.Core.Rendering.original-galactic-zones.bin.gz")!; using var gzip=new GZipStream(compressed,CompressionMode.Decompress);var values=new byte[2048*2048];gzip.ReadExactly(values); if(gzip.ReadByte()!=-1)throw new InvalidDataException("原银河区域像素超出范围。"); return new(json.RootElement,values); } }