OSDN Git Service

Merge branch 'vgd' of into Split_renderers
authormelchior <melchior@users.osdn.me>
Mon, 30 Mar 2020 15:35:38 +0000 (11:35 -0400)
committermelchior <melchior@users.osdn.me>
Mon, 30 Mar 2020 15:35:38 +0000 (11:35 -0400)
(Pass 1, absent new Json generation, incomplete)

1  2 
Automap/Automap.csproj
Automap/Data/EntitiesOfInterest.cs
Automap/Data/PointOfInterest.cs
Automap/Designators/DefaultDesignators.cs
Automap/Subsystems/AutomapSystem.cs
Automap/Subsystems/JsonGenerator.cs

@@@ -95,6 -95,7 +95,8 @@@
      <Compile Include="Data\CommandData.cs" />
      <Compile Include="Data\CommandType.cs" />
      <Compile Include="Data\PersistedConfiguration.cs" />
+     <Compile Include="Data\DisplayNameAttribute.cs" />
++    <Compile Include="Subsystems\JsonGenerator.cs" />
    </ItemGroup>
    <ItemGroup>
      <Folder Include="VS_libs\" />
@@@ -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
  {
        /// <summary>
-       /// Actual Physical Point in space - that is interesting.
+       /// Basically the same as a POI but for an entity
        /// </summary>
 +      [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;
 -              public DateTimeOffset Timestamp;
 +
+               [DisplayName(2, "Time")]
 +              [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("]]");
 -              }
++
++
        }
  
        /// <summary>
@@@ -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
  {
        /// <summary>
        /// Actual Physical Point in space - that is interesting.
        /// </summary>
 +      [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;
 -              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", "&#13;&#10;").Replace("\\","\\\\"));
 -                      stream.Write("'{0}',", Timestamp);
 -                      stream.Write("]]");
 -              }
 +
+               [DisplayName(2, "Time")]
 +              [ProtoMember(4)]
 +              public DateTime Timestamp;
++
++
        }
  
        public class PointsOfInterest : KeyedCollection<BlockPos, PointOfInterest>
@@@ -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));
                        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);
                                {
                                        //What about chunk updates themselves; a update bitmap isn't kept...
                                        updatedChunksTotal += updatedChunks;
--                                      GenerateJSONMetadata();
++                                      JsonGenerator.GenerateJSONMetadata(chunkTopMetadata, startChunkColumn, POIs, EOIs, RockIdCodes);
                                        updatedChunks = 0;
                                }
  
  
                }
  
-               /// <summary>
-               /// Generates the JSON Metadata. (in Map object format )
-               /// </summary>
-               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();
-                       }
-                       }
-               }
 +
 +
                /// <summary>
 -              /// Generates the JSON Metadata. (in Map object format )
 +              /// Store Points/Entity of Interest
                /// </summary>
 -              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<PointsOfInterest>(poiFile, this.POIs);
 +              }
 +              }
  
 -                              //stream.Write("]);\n");
 +              if (this.EOIs.Count > 0) {
 +              using (var eoiFile = File.OpenWrite(eoiPath)) {
 +                      Serializer.Serialize<EntitiesOfInterest>(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<Vec2i, uint> mostActiveCol, IMapChunk mapChunk)
                {
                        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;
 +                                              }
-                                       }
+                                               }
  
                                        }
                                }
                }
  
  
 -              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<DisplayNameAttribute>();
 -                      // 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<DisplayNameAttribute>();
 -                      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<DisplayNameAttribute>();
 -
 -                      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
  
        }
  
--}
++}
index 0000000,0000000..b74689f
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -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;
++              }
++
++
++              /// <summary>
++              /// Generates the JSON Metadata. (in Map object format )
++              /// </summary>
++              public void GenerateJSONMetadata(ColumnsMetadata chunkTopMetadata, Vec2i startChunkColumn, PointsOfInterest POIs, EntitiesOfInterest EOIs, Dictionary<int, string> 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( );
++              }
++
++              /// <summary>
++              /// Dynamically reflect Points-of-Something fields for metadata descriptors
++              /// </summary>
++              /// <returns>Json-array  names of fields for use in map display.</returns>
++              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<DisplayNameAttribute>( );
++              // 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<DisplayNameAttribute>( );
++
++              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<DisplayNameAttribute>( );
++
++              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( );
++              }
++      }
++}
++