From: melchior Date: Mon, 30 Mar 2020 15:35:38 +0000 (-0400) Subject: Merge branch 'vgd' of into Split_renderers X-Git-Tag: PR7x~12 X-Git-Url: http://git.osdn.net/view?p=automap%2Fautomap.git;a=commitdiff_plain;h=01a930a1c73adca96b7f4b23b4cffff18f24c45d Merge branch 'vgd' of into Split_renderers (Pass 1, absent new Json generation, incomplete) --- 01a930a1c73adca96b7f4b23b4cffff18f24c45d diff --cc Automap/Automap.csproj index cc48c10,24c5382..68b2350 --- a/Automap/Automap.csproj +++ b/Automap/Automap.csproj @@@ -95,6 -95,7 +95,8 @@@ + ++ diff --cc Automap/Data/EntitiesOfInterest.cs index 3d5042d,1da27e9..e006d3c --- a/Automap/Data/EntitiesOfInterest.cs +++ b/Automap/Data/EntitiesOfInterest.cs @@@ -1,36 -1,40 +1,46 @@@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; - + using System.IO; using System.Linq; + using Vintagestory.API.Common.Entities; using Vintagestory.API.MathTools; + using Vintagestory.API.Client; +using ProtoBuf; + ++using Newtonsoft.Json; ++ namespace Automap { /// - /// Actual Physical Point in space - that is interesting. + /// Basically the same as a POI but for an entity /// + [ProtoContract] public struct EntityOfInterest { ++ + [ProtoMember(1)] + public string Name; - ++ + [DisplayName(1, "Notes")] + [ProtoMember(2)] public string Notes; + + [DisplayName(0, "Loc.")] + [ProtoMember(3)] public BlockPos Location; + + [DisplayName(2, "Time")] - public DateTimeOffset Timestamp; + [ProtoMember(4)] + public DateTime Timestamp; + + [DisplayName(3, "ID")] + [ProtoMember(5)] public long EntityId; - public void Write(StreamWriter stream, ICoreClientAPI ClientApi) - { - // this is gross i hate this - stream.Write("['{0}_{1}',[", - Location.X, - Location.Y - ); - stream.Write("'{0}',", Location.PrettyCoords(ClientApi)); - stream.Write("'{0}',", System.Web.HttpUtility.HtmlEncode(Notes)); - stream.Write("'{0}',", Timestamp); - stream.Write("'{0}',", EntityId); - stream.Write("]]"); - } ++ ++ } /// diff --cc Automap/Data/PointOfInterest.cs index 16f49ff,4876957..a65c827 --- a/Automap/Data/PointOfInterest.cs +++ b/Automap/Data/PointOfInterest.cs @@@ -1,30 -1,35 +1,39 @@@ using System; using System.Collections.ObjectModel; + using System.IO; + + using Vintagestory.API.Client; using Vintagestory.API.Common; using Vintagestory.API.MathTools; +using ProtoBuf; + ++using Newtonsoft.Json; ++ namespace Automap { /// /// Actual Physical Point in space - that is interesting. /// + [ProtoContract] public struct PointOfInterest { + [ProtoMember(1)] + public string Name; + + [DisplayName(1, "Notes")] + [ProtoMember(2)] public string Notes; + + [DisplayName(0, "Loc.")] + [ProtoMember(3)] public BlockPos Location; + + [DisplayName(2, "Time")] - public DateTimeOffset Timestamp; - public void Write(StreamWriter stream, ICoreClientAPI ClientApi) - { - // this is gross i hate this - stream.Write("['{0}_{1}',[", - Location.X, - Location.Y - ); - stream.Write("'{0}',", Location.PrettyCoords(ClientApi)); - stream.Write("'{0}',", System.Web.HttpUtility.HtmlEncode(Notes).Replace("\n", " ").Replace("\\","\\\\")); - stream.Write("'{0}',", Timestamp); - stream.Write("]]"); - } + [ProtoMember(4)] + public DateTime Timestamp; ++ ++ } public class PointsOfInterest : KeyedCollection diff --cc Automap/Subsystems/AutomapSystem.cs index 8295017,53a785f..858a563 --- a/Automap/Subsystems/AutomapSystem.cs +++ b/Automap/Subsystems/AutomapSystem.cs @@@ -1,8 -1,10 +1,9 @@@ using System; using System.Collections.Concurrent; using System.Collections.Generic; -using System.Diagnostics; using System.IO; using System.Linq; + using System.Reflection; using System.Text; using System.Text.RegularExpressions; using System.Threading; @@@ -29,6 -29,6 +30,7 @@@ namespace Automa private ICoreClientAPI ClientAPI { get; set; } private ILogger Logger { get; set; } private IChunkRenderer ChunkRenderer { get; set; } ++ private JsonGenerator JsonGenerator { get; set; } private const string _mapPath = @"Maps"; private const string _chunkPath = @"Chunks"; @@@ -72,7 -70,7 +75,6 @@@ configuration = config; -- //TODO:Choose which one from GUI this.ChunkRenderer = new StandardRenderer(clientAPI, logger); @@@ -93,7 -91,7 +95,7 @@@ { path = ClientAPI.GetOrCreateDataPath(_mapPath); path = ClientAPI.GetOrCreateDataPath(Path.Combine(path, "World_" + ClientAPI.World.Seed));//Add name of World too...'ServerApi.WorldManager.CurrentWorldName' -- ++ JsonGenerator = new JsonGenerator(ClientAPI, Logger, path); string mapFilename = Path.Combine(path, "automap.html"); StreamWriter outputText = new StreamWriter(File.Open(mapFilename, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)); @@@ -102,6 -100,8 +104,8 @@@ outputText.Write(staticMap.ToText()); outputText.Flush(); - MakePreBuiltJSON(); ++ jsonPreBuilt = JsonGenerator.MakePreBuiltJSON(); + Prefill_POI_Designators(); startChunkColumn = new Vec2i((ClientAPI.World.Player.Entity.LocalPos.AsBlockPos.X / chunkSize), (ClientAPI.World.Player.Entity.LocalPos.AsBlockPos.Z / chunkSize)); chunkTopMetadata = new ColumnsMetadata(startChunkColumn); @@@ -225,7 -227,7 +231,7 @@@ { //What about chunk updates themselves; a update bitmap isn't kept... updatedChunksTotal += updatedChunks; -- GenerateJSONMetadata(); ++ JsonGenerator.GenerateJSONMetadata(chunkTopMetadata, startChunkColumn, POIs, EOIs, RockIdCodes); updatedChunks = 0; } @@@ -309,272 -310,97 +315,55 @@@ } + - /// - /// Generates the JSON Metadata. (in Map object format ) - /// - private void GenerateJSONMetadata() - { - string jsonFilename = Path.Combine(path, "Metadata.js"); - - StreamWriter stream = new StreamWriter(jsonFilename, false, Encoding.UTF8); - - using (stream) { - JsonTextWriter jsonWriter = new JsonTextWriter(stream); - - jsonWriter.Formatting = Formatting.None; - jsonWriter.StringEscapeHandling = StringEscapeHandling.EscapeHtml; - jsonWriter.Indentation = 0; - //jsonWriter.AutoCompleteOnClose = true; - jsonWriter.QuoteChar = '\''; - jsonWriter.DateFormatHandling = DateFormatHandling.IsoDateFormat; - jsonWriter.DateTimeZoneHandling = DateTimeZoneHandling.Utc; - - using (jsonWriter) - { - jsonWriter.WriteRaw("ViewFrame.chunks={};\n"); - jsonWriter.WriteRaw("ViewFrame.chunks.worldSeedNum=" ); - jsonWriter.WriteValue(ClientAPI.World.Seed); - jsonWriter.WriteRaw(";\n"); - - jsonWriter.WriteRaw("ViewFrame.chunks.genTime="); - jsonWriter.WriteValue(DateTimeOffset.UtcNow); - jsonWriter.WriteRaw(";\n"); - - jsonWriter.WriteRaw("ViewFrame.chunks.startCoords="); - jsonWriter.WriteStartArray( ); - jsonWriter.WriteValue(startChunkColumn.X); - jsonWriter.WriteValue(startChunkColumn.Y); - jsonWriter.WriteEndArray( ); - jsonWriter.WriteRaw(";\n"); - - jsonWriter.WriteRaw("ViewFrame.chunks.chunkSize="); - jsonWriter.WriteValue(chunkSize); - jsonWriter.WriteRaw(";\n"); - - jsonWriter.WriteRaw("ViewFrame.chunks.northMostChunk="); - jsonWriter.WriteValue(chunkTopMetadata.North_mostChunk); - jsonWriter.WriteRaw(";\n"); - - jsonWriter.WriteRaw("ViewFrame.chunks.southMostChunk="); - jsonWriter.WriteValue(chunkTopMetadata.South_mostChunk); - jsonWriter.WriteRaw(";\n"); - - jsonWriter.WriteRaw("ViewFrame.chunks.westMostChunk="); - jsonWriter.WriteValue(chunkTopMetadata.West_mostChunk); - jsonWriter.WriteRaw(";\n"); - - jsonWriter.WriteRaw("ViewFrame.chunks.eastMostChunk="); - jsonWriter.WriteValue(chunkTopMetadata.East_mostChunk); - jsonWriter.WriteRaw(";\n"); - - - //MAP object format - [key, value]: key is "x_y" - jsonWriter.WriteRaw("ViewFrame.chunks.chunkMetadata="); - jsonWriter.WriteStartConstructor("Map"); - jsonWriter.WriteStartArray( );//An array of... 2-component arrays - - - foreach (var shard in chunkTopMetadata) - { - jsonWriter.WriteStartArray( );//Start tuple - jsonWriter.WriteValue($"{shard.Location.X}_{shard.Location.Y}");//Key of Tuple - - jsonWriter.WriteStartObject( ); - jsonWriter.WritePropertyName("prettyCoord"); - jsonWriter.WriteValue( shard.Location.PrettyCoords(ClientAPI)); - - jsonWriter.WritePropertyName("chunkAge"); - jsonWriter.WriteValue(shard.ChunkAge); - - jsonWriter.WritePropertyName("temp"); - jsonWriter.WriteValue(shard.Temperature); - - jsonWriter.WritePropertyName("YMax"); - jsonWriter.WriteValue(shard.YMax); - - jsonWriter.WritePropertyName("fert"); - jsonWriter.WriteValue(shard.Fertility); - - jsonWriter.WritePropertyName("forestDens"); - jsonWriter.WriteValue( shard.ForestDensity); - - jsonWriter.WritePropertyName("rain"); - jsonWriter.WriteValue( shard.Rainfall); - - jsonWriter.WritePropertyName("shrubDens"); - jsonWriter.WriteValue( shard.ShrubDensity); - - jsonWriter.WritePropertyName("airBlocks"); - jsonWriter.WriteValue( shard.AirBlocks); - - jsonWriter.WritePropertyName("nonAirBlocks"); - jsonWriter.WriteValue( shard.NonAirBlocks); - - //TODO: Heightmap ? - //Start rockMap ; FOR a Ratio....on tooltip GUI - jsonWriter.WritePropertyName("rockRatio"); - jsonWriter.WriteStartConstructor("Map"); - jsonWriter.WriteStartArray( ); - foreach (var rockEntry in shard.RockRatio) { - var rockBlock = ClientAPI.World.GetBlock(rockEntry.Key); - jsonWriter.WriteStartArray( ); - jsonWriter.WriteValue(rockBlock.Code.Path); - jsonWriter.WriteValue(rockEntry.Value);//Total per chunk-column - jsonWriter.WriteEndArray( ); - } - jsonWriter.WriteEndArray( ); - jsonWriter.WriteEndConstructor( );//end rock-map - - jsonWriter.WriteEndObject( );//end Map value: {Object} - jsonWriter.WriteEndArray( );//end Tuple - } - - jsonWriter.WriteEndArray( );//Enclose tuples of chunkMetadata - jsonWriter.WriteEndConstructor( );//Close constructor of Map (chunkMetadata) - jsonWriter.WriteRaw(";\n"); - - jsonWriter.WriteRaw("ViewFrame.chunks.pointsOfInterest="); - jsonWriter.WriteStartConstructor("Map"); - jsonWriter.WriteStartArray( );//An array of... 2-component arrays - - foreach (var poi in POIs) - { - jsonWriter.WriteStartArray( ); - jsonWriter.WriteValue($"{poi.Location.X}_{poi.Location.Z}"); - - jsonWriter.WriteStartObject(); - jsonWriter.WritePropertyName("Name"); - jsonWriter.WriteValue(poi.Name); - - jsonWriter.WritePropertyName("prettyCoord"); - jsonWriter.WriteValue(poi.Location.PrettyCoords(ClientAPI) ); - - jsonWriter.WritePropertyName("notes"); - jsonWriter.WriteValue(poi.Notes);//Encoded to HTML Entities - - jsonWriter.WritePropertyName("time"); - jsonWriter.WriteValue(poi.Timestamp); - - jsonWriter.WritePropertyName("chunkPos"); - jsonWriter.WriteValue($"{(poi.Location.X / chunkSize)}_{(poi.Location.Z / chunkSize)}"); - - jsonWriter.WriteEndObject( ); - jsonWriter.WriteEndArray( ); - } - - foreach (var poi in EOIs) - { - jsonWriter.WriteStartArray( ); - jsonWriter.WriteValue($"{poi.Location.X}_{poi.Location.Z}"); - - jsonWriter.WriteStartObject( ); - jsonWriter.WritePropertyName("Name"); - jsonWriter.WriteValue(poi.Name); - - jsonWriter.WritePropertyName("prettyCoord"); - jsonWriter.WriteValue(poi.Location.PrettyCoords(ClientAPI)); - - jsonWriter.WritePropertyName("notes"); - jsonWriter.WriteValue(poi.Notes);//Encoded to HTML Entities - - jsonWriter.WritePropertyName("time"); - jsonWriter.WriteValue(poi.Timestamp); - - jsonWriter.WritePropertyName("chunkPos"); - jsonWriter.WriteValue($"{(poi.Location.X / chunkSize)}_{(poi.Location.Z / chunkSize)}"); - - jsonWriter.WriteEndObject( ); - jsonWriter.WriteEndArray( ); - } - - jsonWriter.WriteEndArray( ); - jsonWriter.WriteEndConstructor( ); - jsonWriter.WriteRaw(";\n"); - - jsonWriter.WriteWhitespace("\n"); - jsonWriter.WriteComment("============= BlockID's for Rockmap / Rock-ratios ==============="); - jsonWriter.WriteWhitespace("\n"); - - jsonWriter.WriteRaw("ViewFrame.chunks.rock_Lookup ="); - jsonWriter.WriteStartConstructor("Map"); - jsonWriter.WriteStartArray( );//An array of... 2-component arrays - - foreach (var entry in RockIdCodes) { - var block = ClientAPI.World.GetBlock(entry.Key); - - jsonWriter.WriteStartArray( ); - jsonWriter.WriteValue(block.Code.Path); - - jsonWriter.WriteStartObject( ); - jsonWriter.WritePropertyName("assetCode"); - jsonWriter.WriteValue(entry.Value); - - jsonWriter.WritePropertyName("name"); - jsonWriter.WriteValue(Lang.GetUnformatted(block.Code.Path)); - //Color? - - jsonWriter.WriteEndObject( ); - jsonWriter.WriteEndArray( ); - } - jsonWriter.WriteEndArray( ); - jsonWriter.WriteEndConstructor(); - - jsonWriter.WriteRaw(";\n"); - - jsonWriter.Flush(); - } - } - - } + /// - /// Generates the JSON Metadata. (in Map object format ) + /// Store Points/Entity of Interest /// - private void GenerateJSONMetadata() + private void PersistPointsData( ) { - string jsonFilename = Path.Combine(path, "Metadata.js"); - - StreamWriter stream = new StreamWriter(jsonFilename, false, Encoding.UTF8); - - using (stream) - { - Stopwatch stopWatch = new Stopwatch(); - stopWatch.Start(); - - stream.Write(jsonPreBuilt); - - stream.Write("ViewFrame.chunks.genTime='{0}';", - DateTimeOffset.UtcNow - ); - - stream.Write("ViewFrame.chunks.startCoords=[{0},{1}];", - startChunkColumn.X, startChunkColumn.Y - ); - - stream.Write("ViewFrame.chunks.bounds=[{0},{1},{2},{3}];", - chunkTopMetadata.North_mostChunk, - chunkTopMetadata.South_mostChunk, - chunkTopMetadata.West_mostChunk, - chunkTopMetadata.East_mostChunk - ); - - - //MAP object format - [key, value]: key is "x_y" - stream.Write("ViewFrame.chunks.chunkMetadata=new Map(["); - - foreach (var shard in chunkTopMetadata) - { - shard.Write(stream, ClientAPI); - stream.Write(","); - } - stream.Write("]);");// Close constructor of Map (chunkMetadata) - - - stream.Write("ViewFrame.chunks.pointsOfInterest=new Map(["); - - foreach (var poi in POIs) - { - poi.Write(stream, ClientAPI); - stream.Write(","); - } - - stream.Write("]);"); - - stream.Write("ViewFrame.chunks.entitiesOfInterest=new Map(["); - foreach (var eoi in EOIs) - { - eoi.Write(stream, ClientAPI); - stream.Write(","); - } - stream.Write("]);\n"); - - //stream.Write("//============= BlockID's for Rockmap / Rock-ratios ==============="); - - //stream.Write("ViewFrame.chunks.rockLookup=new Map(["); - - //foreach (var entry in RockIdCodes) - //{ - // var block = ClientAPI.World.GetBlock(entry.Key); - - // stream.Write("["); - // stream.Write("'{0},", block.Code.Path); - - // stream.Write("["); - // stream.Write("'{0}',", entry.Value); - - // stream.Write("{0},", Lang.GetUnformatted(block.Code.Path)); - // //Color? - - // stream.Write("]],"); - //} + //POI and EOI raw dump files ~ WRITE em! + //var poiRawFile = File. + string poiPath = Path.Combine(path, poiFileName); + string eoiPath = Path.Combine(path, eoiFileName); + + if (this.POIs.Count > 0) { + using (var poiFile = File.OpenWrite(poiPath)) { + Serializer.Serialize(poiFile, this.POIs); + } + } - //stream.Write("]);\n"); + if (this.EOIs.Count > 0) { + using (var eoiFile = File.OpenWrite(eoiPath)) { + Serializer.Serialize(eoiFile, this.EOIs); + } + } - //Create Easy to Parse CSV file for tool/human use.... - stream.Flush(); ++ //Create Easy to Parse TSV file for tool/human use.... + string pointsTsvPath = Path.Combine(path, pointsTsvFileName); - stopWatch.Stop(); - Logger.Debug("Run time of chunk write {0}", stopWatch.Elapsed); + using (var tsvWriter = new StreamWriter(pointsTsvPath, false, Encoding.UTF8)) + { + tsvWriter.WriteLine("Name\tDescription\tLocation\tTime\t"); + foreach (var point in this.POIs) { + tsvWriter.Write(point.Name + "\t"); + tsvWriter.Write(point.Notes + "\t"); + tsvWriter.Write(point.Location.PrettyCoords(ClientAPI) + "\t"); + tsvWriter.Write(point.Timestamp.ToString("u")+"\t"); + tsvWriter.WriteLine(); } - + foreach (var entity in this.EOIs) { + tsvWriter.Write(entity.Name + "\t"); + tsvWriter.Write(entity.Notes + "\t"); + tsvWriter.Write(entity.Location.PrettyCoords(ClientAPI) + "\t"); + tsvWriter.Write(entity.Timestamp.ToString("u") + "\t"); + tsvWriter.WriteLine( ); + } + tsvWriter.WriteLine(); + tsvWriter.Flush( ); } + } private ColumnMeta CreateColumnMetadata(KeyValuePair mostActiveCol, IMapChunk mapChunk) { @@@ -600,42 -426,45 +389,42 @@@ if (worldmapDir.Exists) { - var files = worldmapDir.GetFiles(chunkFile_filter); + var shardFiles = worldmapDir.GetFiles(chunkFile_filter); - if (files.Length > 0) + if (shardFiles.Length > 0) { -#if DEBUG - Logger.VerboseDebug("{0} Existing world chunk shards", files.Length); -#endif - - foreach (var shardFile in files) - { - - if (shardFile.Length < 1024) continue; - var result = chunkShardRegex.Match(shardFile.Name); - if (result.Success) + #if DEBUG + Logger.VerboseDebug("Metadata reloading from {0} shards", shardFiles.Length); + #endif + + foreach (var shardFile in shardFiles) { + + if (shardFile.Length < 1024) continue; + var result = chunkShardRegex.Match(shardFile.Name); + if (result.Success) { + int X_chunk_pos = int.Parse(result.Groups["X"].Value); + int Z_chunk_pos = int.Parse(result.Groups["Z"].Value); + + try { - int X_chunk_pos = int.Parse(result.Groups["X"].Value); - int Z_chunk_pos = int.Parse(result.Groups["Z"].Value); + using (var fileStream = shardFile.OpenRead( )) { - try - { - using (var fileStream = shardFile.OpenRead()) - { - - PngReader pngRead = new PngReader(fileStream); - pngRead.ReadSkippingAllRows(); - pngRead.End(); - //Parse PNG chunks for METADATA in shard - PngMetadataChunk metadataFromPng = pngRead.GetChunksList().GetById1(PngMetadataChunk.ID) as PngMetadataChunk; + PngReader pngRead = new PngReader(fileStream); + pngRead.ReadSkippingAllRows( ); + pngRead.End( ); + //Parse PNG chunks for METADATA in shard + PngMetadataChunk metadataFromPng = pngRead.GetChunksList( ).GetById1(PngMetadataChunk.ID) as PngMetadataChunk; - chunkTopMetadata.Add(metadataFromPng.ChunkMetadata); - } + chunkTopMetadata.Add(metadataFromPng.ChunkMetadata); + } - } - catch (PngjException someEx) - { - Logger.Error("PNG Corruption file '{0}' - Reason: {1}", shardFile.Name, someEx); - continue; - } + } - catch (PngjException someEx) ++ catch (PngjException someEx) + { - Logger.Error("PNG Corruption in file '{0}' - Reason: {1}", shardFile.Name, someEx); ++ Logger.Error("PNG Corruption file '{0}' - Reason: {1}", shardFile.Name, someEx); + continue; + } - } + } } } @@@ -860,8 -672,67 +649,10 @@@ } - private void MakePreBuiltJSON() - { - var builder = new StringBuilder(512); - builder.Append("ViewFrame.chunks={};\n"); - builder.AppendFormat("ViewFrame.chunks.worldSeedNum='{0}';", - ClientAPI.World.Seed - ); - builder.AppendFormat("ViewFrame.chunks.chunkSize={0};", - chunkSize - ); - - builder.Append("ViewFrame.chunks.chunkMetadataNames=["); - var fields = typeof(ColumnMeta).GetFields(); - var attsToSort = new List(); - // this is so gross - foreach (var f in fields) - { - var att = f.GetCustomAttribute(typeof(DisplayNameAttribute)); - if (att != null) - { - attsToSort.Add((DisplayNameAttribute) att); - } - - } - foreach (var att in attsToSort.OrderBy(a => a.order)) - builder.AppendFormat("'{0}',", att.name); - builder.Append("];\n"); - - builder.Append("ViewFrame.chunks.pointsOfInterestNames=["); - fields = typeof(PointOfInterest).GetFields(); - attsToSort = new List(); + - foreach (var f in fields) - { - var att = f.GetCustomAttribute(typeof(DisplayNameAttribute)); - if (att != null) - attsToSort.Add((DisplayNameAttribute) att); - } - foreach (var att in attsToSort.OrderBy(a => a.order)) - builder.AppendFormat("'{0}',", att.name); - builder.Append("];\n"); - - builder.Append("ViewFrame.chunks.entityOfInterestNames=["); - fields = typeof(EntityOfInterest).GetFields(); - attsToSort = new List(); - - foreach (var f in fields) - { - var att = f.GetCustomAttribute(typeof(DisplayNameAttribute)); - if (att != null) - attsToSort.Add((DisplayNameAttribute) att); - } - foreach (var att in attsToSort.OrderBy(a => a.order)) - builder.AppendFormat("'{0}',", att.name); - builder.Append("];\n"); - - jsonPreBuilt = builder.ToString(); - } + #endregion } --} ++} diff --cc Automap/Subsystems/JsonGenerator.cs index 0000000,0000000..b74689f new file mode 100644 --- /dev/null +++ b/Automap/Subsystems/JsonGenerator.cs @@@ -1,0 -1,0 +1,318 @@@ ++using System; ++using System.Collections.Generic; ++using System.IO; ++using System.Linq; ++using System.Reflection; ++using System.Text; ++using System.Text.RegularExpressions; ++ ++using Newtonsoft.Json; ++ ++using Vintagestory.API.Client; ++using Vintagestory.API.Common; ++using Vintagestory.API.Config; ++using Vintagestory.API.Datastructures; ++using Vintagestory.API.MathTools; ++using Vintagestory.Common; ++ ++ ++ ++namespace Automap ++{ ++ public class JsonGenerator ++ { ++ private ICoreClientAPI ClientAPI { get; set; } ++ private ILogger Logger { get; set; } ++ private string path { get; set; } ++ private readonly int chunkSize; ++ ++ ++ public JsonGenerator(ICoreClientAPI _ClientAPI, ILogger _Logger, string _path ) ++ { ++ this.ClientAPI = _ClientAPI; ++ this.Logger = _Logger; ++ this.path = _path; ++ this.chunkSize = ClientAPI.World.BlockAccessor.ChunkSize; ++ } ++ ++ ++ /// ++ /// Generates the JSON Metadata. (in Map object format ) ++ /// ++ public void GenerateJSONMetadata(ColumnsMetadata chunkTopMetadata, Vec2i startChunkColumn, PointsOfInterest POIs, EntitiesOfInterest EOIs, Dictionary RockIdCodes ) ++ { ++ string jsonFilename = Path.Combine(path, "Metadata.js"); ++ ++ StreamWriter stream = new StreamWriter(jsonFilename, false, Encoding.UTF8); ++ ++ using (stream) { ++ JsonTextWriter jsonWriter = new JsonTextWriter(stream); ++ ++ jsonWriter.Formatting = Formatting.None; ++ jsonWriter.StringEscapeHandling = StringEscapeHandling.EscapeHtml; ++ jsonWriter.Indentation = 0; ++ //jsonWriter.AutoCompleteOnClose = true; ++ jsonWriter.QuoteChar = '\''; ++ jsonWriter.DateFormatHandling = DateFormatHandling.IsoDateFormat; ++ jsonWriter.DateTimeZoneHandling = DateTimeZoneHandling.Utc; ++ ++ using (jsonWriter) { ++ jsonWriter.WriteRaw("ViewFrame.chunks={};\n"); ++ jsonWriter.WriteRaw("ViewFrame.chunks.worldSeedNum="); ++ jsonWriter.WriteValue(ClientAPI.World.Seed); ++ jsonWriter.WriteRaw(";\n"); ++ ++ jsonWriter.WriteRaw("ViewFrame.chunks.genTime="); ++ jsonWriter.WriteValue(DateTimeOffset.UtcNow); ++ jsonWriter.WriteRaw(";\n"); ++ ++ jsonWriter.WriteRaw("ViewFrame.chunks.startCoords="); ++ jsonWriter.WriteStartArray( ); ++ jsonWriter.WriteValue(startChunkColumn.X); ++ jsonWriter.WriteValue(startChunkColumn.Y); ++ jsonWriter.WriteEndArray( ); ++ jsonWriter.WriteRaw(";\n"); ++ ++ jsonWriter.WriteRaw("ViewFrame.chunks.chunkSize="); ++ jsonWriter.WriteValue(chunkSize); ++ jsonWriter.WriteRaw(";\n"); ++ ++ jsonWriter.WriteRaw("ViewFrame.chunks.northMostChunk="); ++ jsonWriter.WriteValue(chunkTopMetadata.North_mostChunk); ++ jsonWriter.WriteRaw(";\n"); ++ ++ jsonWriter.WriteRaw("ViewFrame.chunks.southMostChunk="); ++ jsonWriter.WriteValue(chunkTopMetadata.South_mostChunk); ++ jsonWriter.WriteRaw(";\n"); ++ ++ jsonWriter.WriteRaw("ViewFrame.chunks.westMostChunk="); ++ jsonWriter.WriteValue(chunkTopMetadata.West_mostChunk); ++ jsonWriter.WriteRaw(";\n"); ++ ++ jsonWriter.WriteRaw("ViewFrame.chunks.eastMostChunk="); ++ jsonWriter.WriteValue(chunkTopMetadata.East_mostChunk); ++ jsonWriter.WriteRaw(";\n"); ++ ++ ++ //MAP object format - [key, value]: key is "x_y" ++ jsonWriter.WriteRaw("ViewFrame.chunks.chunkMetadata="); ++ jsonWriter.WriteStartConstructor("Map"); ++ jsonWriter.WriteStartArray( );//An array of... 2-component arrays ++ ++ ++ foreach (var shard in chunkTopMetadata) { ++ jsonWriter.WriteStartArray( );//Start tuple ++ jsonWriter.WriteValue($"{shard.Location.X}_{shard.Location.Y}");//Key of Tuple ++ ++ jsonWriter.WriteStartObject( ); ++ jsonWriter.WritePropertyName("prettyCoord"); ++ jsonWriter.WriteValue(shard.Location.PrettyCoords(ClientAPI)); ++ ++ jsonWriter.WritePropertyName("chunkAge"); ++ jsonWriter.WriteValue(shard.ChunkAge); ++ ++ jsonWriter.WritePropertyName("temp"); ++ jsonWriter.WriteValue(shard.Temperature); ++ ++ jsonWriter.WritePropertyName("YMax"); ++ jsonWriter.WriteValue(shard.YMax); ++ ++ jsonWriter.WritePropertyName("fert"); ++ jsonWriter.WriteValue(shard.Fertility); ++ ++ jsonWriter.WritePropertyName("forestDens"); ++ jsonWriter.WriteValue(shard.ForestDensity); ++ ++ jsonWriter.WritePropertyName("rain"); ++ jsonWriter.WriteValue(shard.Rainfall); ++ ++ jsonWriter.WritePropertyName("shrubDens"); ++ jsonWriter.WriteValue(shard.ShrubDensity); ++ ++ jsonWriter.WritePropertyName("airBlocks"); ++ jsonWriter.WriteValue(shard.AirBlocks); ++ ++ jsonWriter.WritePropertyName("nonAirBlocks"); ++ jsonWriter.WriteValue(shard.NonAirBlocks); ++ ++ //TODO: Heightmap ? ++ //Start rockMap ; FOR a Ratio....on tooltip GUI ++ jsonWriter.WritePropertyName("rockRatio"); ++ jsonWriter.WriteStartConstructor("Map"); ++ jsonWriter.WriteStartArray( ); ++ foreach (var rockEntry in shard.RockRatio) { ++ var rockBlock = ClientAPI.World.GetBlock(rockEntry.Key); ++ jsonWriter.WriteStartArray( ); ++ jsonWriter.WriteValue(rockBlock.Code.Path); ++ jsonWriter.WriteValue(rockEntry.Value);//Total per chunk-column ++ jsonWriter.WriteEndArray( ); ++ } ++ jsonWriter.WriteEndArray( ); ++ jsonWriter.WriteEndConstructor( );//end rock-map ++ ++ jsonWriter.WriteEndObject( );//end Map value: {Object} ++ jsonWriter.WriteEndArray( );//end Tuple ++ } ++ ++ jsonWriter.WriteEndArray( );//Enclose tuples of chunkMetadata ++ jsonWriter.WriteEndConstructor( );//Close constructor of Map (chunkMetadata) ++ jsonWriter.WriteRaw(";\n"); ++ ++ jsonWriter.WriteRaw("ViewFrame.chunks.pointsOfInterest="); ++ jsonWriter.WriteStartConstructor("Map"); ++ jsonWriter.WriteStartArray( );//An array of... 2-component arrays ++ ++ foreach (var poi in POIs) { ++ EmitJsonMap(poi, jsonWriter); ++ } ++ ++ foreach (var poi in EOIs) { ++ EmitJsonMap(poi, jsonWriter); ++ } ++ ++ jsonWriter.WriteEndArray( ); ++ jsonWriter.WriteEndConstructor( ); ++ jsonWriter.WriteRaw(";\n"); ++ ++ jsonWriter.WriteWhitespace("\n"); ++ jsonWriter.WriteComment("============= BlockID's for Rockmap / Rock-ratios ==============="); ++ jsonWriter.WriteWhitespace("\n"); ++ ++ jsonWriter.WriteRaw("ViewFrame.chunks.rock_Lookup ="); ++ jsonWriter.WriteStartConstructor("Map"); ++ jsonWriter.WriteStartArray( );//An array of... 2-component arrays ++ ++ foreach (var entry in RockIdCodes) { ++ var block = ClientAPI.World.GetBlock(entry.Key); ++ // stream.Write("{0},", Lang.GetUnformatted(block.Code.Path)); ++ jsonWriter.WriteStartArray( ); ++ jsonWriter.WriteValue(block.Code.Path); ++ ++ jsonWriter.WriteStartObject( ); ++ jsonWriter.WritePropertyName("assetCode"); ++ jsonWriter.WriteValue(entry.Value); ++ ++ jsonWriter.WritePropertyName("name"); ++ jsonWriter.WriteValue(Lang.GetUnformatted(block.Code.Path)); ++ //} ++ ++ jsonWriter.WriteEndObject( ); ++ jsonWriter.WriteEndArray( ); ++ } ++ jsonWriter.WriteEndArray( ); ++ jsonWriter.WriteEndConstructor( ); ++ //stream.Write("]);\n"); ++ jsonWriter.WriteRaw(";\n"); ++ ++ jsonWriter.Flush( ); ++ } ++ } ++ ++ } ++ ++ public void EmitJsonMap(PointOfInterest @this, JsonTextWriter jsonWriter) ++ { ++ jsonWriter.WriteStartArray( ); ++ jsonWriter.WriteValue($"{@this.Location.X}_{@this.Location.Z}"); ++ ++ jsonWriter.WriteStartArray( ); ++ //jsonWriter.WriteValue(@this.Name); ++ ++ jsonWriter.WriteValue(@this.Location.X); ++ jsonWriter.WriteValue(@this.Location.Z); //Y is HEIGHT from Mantle... Z is Right from edge of world ++ ++ jsonWriter.WriteValue(@this.Location.PrettyCoords(ClientAPI)); ++ ++ jsonWriter.WriteValue(@this.Notes);//put more escaping in Java-script if needed ++ ++ jsonWriter.WriteValue(@this.Timestamp); ++ ++ jsonWriter.WriteEndArray( ); ++ jsonWriter.WriteEndArray( ); ++ } ++ ++ public void EmitJsonMap(EntityOfInterest @this, JsonTextWriter jsonWriter) ++ { ++ jsonWriter.WriteStartArray( ); ++ jsonWriter.WriteValue($"{@this.Location.X}_{@this.Location.Z}"); ++ ++ ++ jsonWriter.WriteStartArray( ); ++ //jsonWriter.WriteValue(@this.Name); ++ ++ jsonWriter.WriteValue(@this.Location.X); ++ jsonWriter.WriteValue(@this.Location.Z); //Y is HEIGHT from Mantle... Z is Right from edge of world ++ ++ jsonWriter.WriteValue(@this.Location.PrettyCoords(ClientAPI)); ++ ++ jsonWriter.WriteValue(@this.Notes);//put more escaping in Java-script if needed ++ ++ jsonWriter.WriteValue(@this.Timestamp); ++ ++ jsonWriter.WriteValue(@this.EntityId); ++ ++ jsonWriter.WriteEndArray( ); ++ jsonWriter.WriteEndArray( ); ++ } ++ ++ /// ++ /// Dynamically reflect Points-of-Something fields for metadata descriptors ++ /// ++ /// Json-array names of fields for use in map display. ++ public string MakePreBuiltJSON( ) ++ { ++ var builder = new StringBuilder(512); ++ builder.Append("ViewFrame.chunks={};\n"); ++ builder.AppendFormat("ViewFrame.chunks.worldSeedNum='{0}';", ++ ClientAPI.World.Seed ++ ); ++ builder.AppendFormat("ViewFrame.chunks.chunkSize={0};", ++ chunkSize ++ ); ++ ++ builder.Append("ViewFrame.chunks.chunkMetadataNames=["); ++ var fields = typeof(ColumnMeta).GetFields( ); ++ var attsToSort = new List( ); ++ // this is so gross ++ foreach (var f in fields) { ++ var att = f.GetCustomAttribute(typeof(DisplayNameAttribute)); ++ if (att != null) { ++ attsToSort.Add(( DisplayNameAttribute )att); ++ } ++ ++ } ++ foreach (var att in attsToSort.OrderBy(a => a.order)) ++ builder.AppendFormat("'{0}',", att.name); ++ builder.Append("];\n"); ++ ++ builder.Append("ViewFrame.chunks.pointsOfInterestNames=["); ++ fields = typeof(PointOfInterest).GetFields( ); ++ attsToSort = new List( ); ++ ++ foreach (var f in fields) { ++ var att = f.GetCustomAttribute(typeof(DisplayNameAttribute)); ++ if (att != null) ++ attsToSort.Add(( DisplayNameAttribute )att); ++ } ++ foreach (var att in attsToSort.OrderBy(a => a.order)) ++ builder.AppendFormat("'{0}',", att.name); ++ builder.Append("];\n"); ++ ++ builder.Append("ViewFrame.chunks.entityOfInterestNames=["); ++ fields = typeof(EntityOfInterest).GetFields( ); ++ attsToSort = new List( ); ++ ++ foreach (var f in fields) { ++ var att = f.GetCustomAttribute(typeof(DisplayNameAttribute)); ++ if (att != null) ++ attsToSort.Add(( DisplayNameAttribute )att); ++ } ++ foreach (var att in attsToSort.OrderBy(a => a.order)) ++ builder.AppendFormat("'{0}',", att.name); ++ builder.Append("];\n"); ++ ++ return builder.ToString( ); ++ } ++ } ++} ++