2 using System.Collections.Generic;
5 using System.Reflection;
9 using Newtonsoft.Json.Linq;
11 using Vintagestory.API.Client;
12 using Vintagestory.API.Common;
13 using Vintagestory.API.Config;
14 using Vintagestory.API.Datastructures;
15 using Vintagestory.API.MathTools;
16 using Vintagestory.Common;
21 public class JsonGenerator
23 private ICoreClientAPI ClientAPI { get; set; }
24 private ILogger Logger { get; set; }
25 private string path { get; set; }
26 private readonly int chunkSize;
28 internal JArray ColumnMeta_fieldNames,PointsOfInterest_fieldNames,EntitiesOfInterest_fieldNames;
30 public JsonGenerator(ICoreClientAPI _ClientAPI, ILogger _Logger, string _path )
32 this.ClientAPI = _ClientAPI;
33 this.Logger = _Logger;
35 this.chunkSize = ClientAPI.World.BlockAccessor.ChunkSize;
37 ColumnMeta_fieldNames = Dynamic_Names<ColumnMeta>( );
38 PointsOfInterest_fieldNames = Dynamic_Names<PointOfInterest>( );
39 EntitiesOfInterest_fieldNames = Dynamic_Names<EntityOfInterest>( );
40 Logger.VerboseDebug("JSON Ready");
45 /// Generates the JSON Metadata. (in Map object format )
47 public void GenerateJSONMetadata(ColumnsMetadata chunkTopMetadata, Vec2i startChunkColumn, PointsOfInterest POIs, EntitiesOfInterest EOIs, Dictionary<int, string> RockIdCodes )
49 string jsonFilename = Path.Combine(path, "Metadata.js");
51 StreamWriter stream = new StreamWriter(jsonFilename, false, Encoding.UTF8);
54 JsonTextWriter jsonWriter = new JsonTextWriter(stream);
56 jsonWriter.Formatting = Formatting.None;
57 jsonWriter.StringEscapeHandling = StringEscapeHandling.EscapeHtml;
58 jsonWriter.Indentation = 0;
59 //jsonWriter.AutoCompleteOnClose = true;
60 jsonWriter.QuoteChar = '\'';
61 jsonWriter.DateFormatHandling = DateFormatHandling.IsoDateFormat;
62 jsonWriter.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
67 // the basic metadata right now
68 vfc.edges = [northmostedge, eastmost, west, south];
69 vfc.chunkMetadataNames=[...]; // the implementation with reflection
70 vfc.chunkMetadata = new Map([['the keys we have', [...metadatas in the same order as the names, stringified(maybe not for rocks thats complicated)],...]);
74 jsonWriter.WriteRaw("ViewFrame.chunks={};\n");
75 jsonWriter.WriteRaw("ViewFrame.chunks.worldSeedNum=");
76 jsonWriter.WriteValue(ClientAPI.World.Seed);
77 jsonWriter.WriteRaw(";\n");
79 jsonWriter.WriteRaw("ViewFrame.chunks.genTime=");
80 jsonWriter.WriteValue(DateTimeOffset.UtcNow);
81 jsonWriter.WriteRaw(";\n");
83 jsonWriter.WriteRaw("ViewFrame.chunks.startCoords=");
84 jsonWriter.WriteStartArray( );
85 jsonWriter.WriteValue(startChunkColumn.X);
86 jsonWriter.WriteValue(startChunkColumn.Y);
87 jsonWriter.WriteEndArray( );
88 jsonWriter.WriteRaw(";\n");
90 jsonWriter.WriteRaw("ViewFrame.chunks.chunkSize=");
91 jsonWriter.WriteValue(chunkSize);
92 jsonWriter.WriteRaw(";\n");
94 jsonWriter.WriteRaw("ViewFrame.chunks.edges=");//whats NEWS
95 jsonWriter.WriteStartArray( );
96 jsonWriter.WriteValue(chunkTopMetadata.North_mostChunk);
97 jsonWriter.WriteValue(chunkTopMetadata.East_mostChunk);
98 jsonWriter.WriteValue(chunkTopMetadata.South_mostChunk);
99 jsonWriter.WriteValue(chunkTopMetadata.West_mostChunk);
100 jsonWriter.WriteEndArray( );
101 jsonWriter.WriteRaw(";\n");
103 jsonWriter.WriteRaw("ViewFrame.chunks.chunkMetadataNames=");
104 ColumnMeta_fieldNames.WriteTo(jsonWriter);
105 jsonWriter.WriteRaw(";\n");
107 jsonWriter.WriteRaw("ViewFrame.chunks.pointsOfInterestNames=");
108 PointsOfInterest_fieldNames.WriteTo(jsonWriter);
109 jsonWriter.WriteRaw(";\n");
111 jsonWriter.WriteRaw("ViewFrame.chunks.entityOfInterestNames=");
112 EntitiesOfInterest_fieldNames.WriteTo(jsonWriter);
113 jsonWriter.WriteRaw(";\n");
115 //MAP object format - [key, value]: key is "x_y"
116 jsonWriter.WriteRaw("ViewFrame.chunks.chunkMetadata=");
117 jsonWriter.WriteStartConstructor("Map");
118 jsonWriter.WriteStartArray( );//An array of... 2-component arrays
121 foreach (var shard in chunkTopMetadata) {
122 //TODO:Flatten to array of values...Dynamism!
123 jsonWriter.WriteStartArray( );//Start tuple
124 jsonWriter.WriteValue($"{shard.Location.X}_{shard.Location.Y}");//Key of Tuple
126 jsonWriter.WriteStartObject( );
127 jsonWriter.WritePropertyName("prettyCoord");
128 jsonWriter.WriteValue(shard.Location.PrettyCoords(ClientAPI));
130 jsonWriter.WritePropertyName("chunkAge");
131 jsonWriter.WriteValue(shard.ChunkAge);
133 jsonWriter.WritePropertyName("temp");
134 jsonWriter.WriteValue(shard.Temperature);
136 jsonWriter.WritePropertyName("YMax");
137 jsonWriter.WriteValue(shard.YMax);
139 jsonWriter.WritePropertyName("fert");
140 jsonWriter.WriteValue(shard.Fertility);
142 jsonWriter.WritePropertyName("forestDens");
143 jsonWriter.WriteValue(shard.ForestDensity);
145 jsonWriter.WritePropertyName("rain");
146 jsonWriter.WriteValue(shard.Rainfall);
148 jsonWriter.WritePropertyName("shrubDens");
149 jsonWriter.WriteValue(shard.ShrubDensity);
151 jsonWriter.WritePropertyName("airBlocks");
152 jsonWriter.WriteValue(shard.AirBlocks);
154 jsonWriter.WritePropertyName("nonAirBlocks");
155 jsonWriter.WriteValue(shard.NonAirBlocks);
158 //Start rockMap ; FOR a Ratio....on tooltip GUI
159 jsonWriter.WritePropertyName("rockRatio");
160 jsonWriter.WriteStartConstructor("Map");
161 jsonWriter.WriteStartArray( );
162 foreach (var rockEntry in shard.RockRatio) {
163 var rockBlock = ClientAPI.World.GetBlock(rockEntry.Key);
164 jsonWriter.WriteStartArray( );
165 jsonWriter.WriteValue(rockBlock.Code.Path);
166 jsonWriter.WriteValue(rockEntry.Value);//Total per chunk-column
167 jsonWriter.WriteEndArray( );
169 jsonWriter.WriteEndArray( );
170 jsonWriter.WriteEndConstructor( );//end rock-map
172 jsonWriter.WriteEndObject( );//end Map value: {Object}
173 jsonWriter.WriteEndArray( );//end Tuple
176 jsonWriter.WriteEndArray( );//Enclose tuples of chunkMetadata
177 jsonWriter.WriteEndConstructor( );//Close constructor of Map (chunkMetadata)
178 jsonWriter.WriteRaw(";\n");
180 jsonWriter.WriteRaw("ViewFrame.chunks.pointsOfInterest=");
181 jsonWriter.WriteStartConstructor("Map");
182 jsonWriter.WriteStartArray( );//An array of... 2-component arrays
184 foreach (var poi in POIs) {
185 EmitJsonMap(poi, jsonWriter);
188 foreach (var poi in EOIs) {
189 EmitJsonMap(poi, jsonWriter);
192 jsonWriter.WriteEndArray( );
193 jsonWriter.WriteEndConstructor( );
194 jsonWriter.WriteRaw(";\n");
196 jsonWriter.WriteWhitespace("\n");
197 jsonWriter.WriteComment("============= BlockID's for Rockmap / Rock-ratios ===============");
198 jsonWriter.WriteWhitespace("\n");
200 jsonWriter.WriteRaw("ViewFrame.chunks.rock_Lookup =");
201 jsonWriter.WriteStartConstructor("Map");
202 jsonWriter.WriteStartArray( );//An array of... 2-component arrays
204 foreach (var entry in RockIdCodes) {
205 var block = ClientAPI.World.GetBlock(entry.Key);
206 // stream.Write("{0},", Lang.GetUnformatted(block.Code.Path));
207 jsonWriter.WriteStartArray( );
208 jsonWriter.WriteValue(block.Code.Path);
210 jsonWriter.WriteStartObject( );
211 jsonWriter.WritePropertyName("assetCode");
212 jsonWriter.WriteValue(entry.Value);
214 jsonWriter.WritePropertyName("name");
215 jsonWriter.WriteValue(Lang.GetUnformatted(block.Code.Path));
218 jsonWriter.WriteEndObject( );
219 jsonWriter.WriteEndArray( );
221 jsonWriter.WriteEndArray( );
222 jsonWriter.WriteEndConstructor( );
223 //stream.Write("]);\n");
224 jsonWriter.WriteRaw(";\n");
232 public void EmitJsonMap(PointOfInterest @this, JsonTextWriter jsonWriter)
234 jsonWriter.WriteStartArray( );
235 jsonWriter.WriteValue($"{@this.Location.X}_{@this.Location.Z}");
237 jsonWriter.WriteStartArray( );
238 //jsonWriter.WriteValue(@this.Name);
240 jsonWriter.WriteValue(@this.Location.X);
241 jsonWriter.WriteValue(@this.Location.Z); //Y is HEIGHT from Mantle... Z is Right from edge of world
243 jsonWriter.WriteValue(@this.Location.PrettyCoords(ClientAPI));
245 jsonWriter.WriteValue(@this.Notes.Replace('\\', ' '));//put more escaping in Java-script if needed
247 jsonWriter.WriteValue(@this.Timestamp);
249 jsonWriter.WriteEndArray( );
250 jsonWriter.WriteEndArray( );
253 public void EmitJsonMap(EntityOfInterest @this, JsonTextWriter jsonWriter)
255 jsonWriter.WriteStartArray( );
256 jsonWriter.WriteValue($"{@this.Location.X}_{@this.Location.Z}");
259 jsonWriter.WriteStartArray( );
260 //jsonWriter.WriteValue(@this.Name);
262 jsonWriter.WriteValue(@this.Location.X);
263 jsonWriter.WriteValue(@this.Location.Z); //Y is HEIGHT from Mantle... Z is Right from edge of world
265 jsonWriter.WriteValue(@this.Location.PrettyCoords(ClientAPI));
267 jsonWriter.WriteValue(@this.Notes.Replace('\\', ' '));//put more escaping in Java-script if needed
269 jsonWriter.WriteValue(@this.Timestamp);
271 //jsonWriter.WriteValue(@this.EntityId);
273 jsonWriter.WriteEndArray( );
274 jsonWriter.WriteEndArray( );
278 internal JArray Dynamic_Names<TData>( ) where TData : struct
280 Dictionary<byte, string> fieldNames = new Dictionary<byte, string>( );
282 foreach (var fieldInfo in typeof(TData).GetFields(BindingFlags.Instance | BindingFlags.Public)) {
283 DisplayNameAttribute displayName = fieldInfo.GetCustomAttribute<DisplayNameAttribute>();
284 if (displayName != null)
286 if (!fieldNames.ContainsKey(displayName.order))
287 {//No duplicates, no overwrites
288 fieldNames.Add(displayName.order, displayName.name);
293 return new JArray(fieldNames.OrderBy(kf => kf.Key).Select(kf => kf.Value).ToArray());