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);
/// <summary>The original 42-region GZM. These are geographic annotations, never stellar catalogue rows.</summary>
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<byte> Values=>values;
public IReadOnlyList<GalaxyOriginalZone> 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<GalaxyOriginalZone[]>(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);
}
}
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);
/// <summary>The original 42-region GZM. These are geographic annotations, never stellar catalogue rows.</summary>
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<byte> Values=>values;
public IReadOnlyList<GalaxyOriginalZone> 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<GalaxyOriginalZone[]>(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);
}
}