• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#objective-cqt誰得windowscocoapythonphprubygameguibathyscaphec翻訳omegat計画中(planning stage)frameworktwittertestdomvb.netdirectxbtronarduinopreviewerゲームエンジン

Automap (client) [VS plugin mod]


Commit MetaInfo

Revisionb5737970d216cb6abba36243b7437fa092b88fdf (tree)
Time2021-08-27 05:15:41
Authormelchior <melchior@user...>
Commitermelchior

Log Message

Minimap Export

Shard Processor experimental Mini-map (from DB) EXPORT feature

Change Summary

Incremental Difference

--- /dev/null
+++ b/ShardProcessor/LogAdaptor.cs
@@ -0,0 +1,36 @@
1+using System;
2+using System.IO;
3+
4+using Vintagestory.API.Common;
5+
6+namespace ShardProcessor
7+{
8+ public class LogAdaptor : LoggerBase
9+ {
10+ private StreamWriter fileOutput;
11+
12+ public LogAdaptor( )
13+ {
14+ fileOutput = File.CreateText("SP_Log.txt");
15+ fileOutput.AutoFlush = true;
16+ }
17+
18+ protected override void LogImpl(EnumLogType logType, string format, params object[ ] args)
19+ {
20+ string formatedText = null;
21+ if (args != null && args.Length > 0) {
22+ formatedText = string.Format(format, args);
23+ }
24+ else { formatedText = format; }
25+
26+ fileOutput.WriteLine($"«{logType}» {formatedText}");
27+ }
28+
29+ ~LogAdaptor( )
30+ {
31+ fileOutput.Flush( );
32+ fileOutput.Close( );
33+ }
34+ }
35+}
36+
--- /dev/null
+++ b/ShardProcessor/ProcessingMethods.cs
@@ -0,0 +1,354 @@
1+using System;
2+using System.Diagnostics;
3+using System.IO;
4+using System.Linq;
5+using System.Text.RegularExpressions;
6+
7+using Automap;
8+
9+using Hjg.Pngcs;
10+using Hjg.Pngcs.Chunks;
11+
12+using ProtoBuf;
13+using Vintagestory.API.Common;
14+using Vintagestory.API.MathTools;
15+using Vintagestory.GameContent;
16+
17+namespace ShardProcessor
18+{
19+ public partial class MainClass
20+ {
21+ internal const int chunkDefaultSize = 32;
22+
23+ private static void Process_ShardData( )
24+ {
25+ var shardsDir = new DirectoryInfo(Path.Combine(mapPath, _chunkPath));
26+
27+ var shardFiles = shardsDir.GetFiles(chunkFile_filter);
28+
29+ if (shardFiles.Length > 0) {
30+ #if DEBUG
31+ //Logger.VerboseDebug("Metadata reloading from {0} shards", shardFiles.Length);
32+ #endif
33+
34+ foreach (var shardFile in shardFiles) {
35+
36+ if (shardFile.Length < 1024) continue;
37+ var result = chunkShardRegex.Match(shardFile.Name);
38+ if (!result.Success) continue;
39+
40+ int X_chunk_pos = int.Parse(result.Groups["X"].Value);
41+ int Z_chunk_pos = int.Parse(result.Groups["Z"].Value);
42+
43+ try {
44+ using (var fileStream = shardFile.OpenRead( )) {
45+
46+ PngReader pngRead = new PngReader(fileStream);
47+ pngRead.ReadSkippingAllRows( );
48+ pngRead.End( );
49+ //Parse PNG chunks for METADATA in shard
50+ PngMetadataChunk metadataFromPng = pngRead.GetChunksList( ).GetById1(PngMetadataChunk.ID) as PngMetadataChunk;
51+ ColumnMeta columnData = metadataFromPng.ChunkMetadata;
52+ //columnData.HeightMap //Should be sane Heightmap...
53+
54+
55+
56+ }
57+
58+ } catch (PngjException someEx) {
59+ //Logger.Error("PNG Corruption file '{0}' - Reason: {1}", shardFile.Name, someEx);
60+ continue;
61+ } catch (ProtoException protoEx) {
62+ //Logger.Error("ProtoBuf invalid! file:'{0}' - Reason: {1}", shardFile.Name, protoEx);
63+ continue;
64+ }
65+ }
66+ }
67+
68+
69+ }
70+
71+
72+ private static void Scan_PointsData( )
73+ {
74+ try {
75+ var eoiFile = new FileInfo(Path.Combine(mapPath, @"eoi_binary"));
76+ var poiFile = new FileInfo(Path.Combine(mapPath, @"poi_binary"));
77+ uint entities = 0, points = 0;
78+
79+ if (eoiFile.Exists) {
80+ using (var eoiStream = eoiFile.OpenRead( )) {
81+
82+ EntitiesOfInterest eoiData = Serializer.Deserialize<EntitiesOfInterest>(eoiStream);
83+
84+ foreach (var entry in eoiData) {
85+ Console.WriteLine("#{0}, [{1}], '{2}', {3}",
86+ entry.EntityId,
87+ entry.Location,
88+ entry.Name,
89+ entry.Timestamp.ToUniversalTime( )
90+ );
91+ entities++;
92+ }
93+ Console.WriteLine("Entities Of Interest: {0}", entities);
94+ }
95+
96+
97+ if (poiFile.Exists) {
98+ using (var poiStream = poiFile.OpenRead( )) {
99+
100+ PointsOfInterest poiData = Serializer.Deserialize<PointsOfInterest>(poiStream);
101+ foreach (var entry in poiData) {
102+ Console.WriteLine("[{0}], {1}, {2}, {3}",
103+ entry.Location,
104+ entry.Name,
105+ entry.Destination,
106+ entry.Timestamp.ToUniversalTime( )
107+ );
108+ points++;
109+ }
110+ }
111+ Console.WriteLine("Points Of Interest: {0}", points);
112+ }
113+
114+ }
115+ } catch (Exception uhOh) {
116+ Console.WriteLine(uhOh);
117+ }
118+
119+ }
120+
121+ private static void Scan_ShardData( )
122+ {
123+ var shardsDir = new DirectoryInfo(Path.Combine(mapPath, _chunkPath));
124+ ulong count = 0, errors = 0, flat = 0;
125+ var shardFiles = shardsDir.GetFiles(chunkFile_filter);
126+
127+ if (shardFiles.Length > 0) {
128+ #if DEBUG
129+ //Logger.VerboseDebug("Metadata reloading from {0} shards", shardFiles.Length);
130+ #endif
131+
132+ foreach (var shardFile in shardFiles) {
133+
134+ if (shardFile.Length < 1024) {
135+ Console.WriteLine("File: '{0}' too small to be valid; skipping!", shardFile.FullName);
136+ errors++;
137+ continue;
138+ }
139+
140+ var result = chunkShardRegex.Match(shardFile.Name);
141+ if (!result.Success) continue;
142+
143+ int X_chunk_pos = int.Parse(result.Groups["X"].Value);
144+ int Z_chunk_pos = int.Parse(result.Groups["Z"].Value);
145+
146+ try {
147+ using (var fileStream = shardFile.OpenRead( )) {
148+
149+ PngReader pngRead = new PngReader(fileStream);
150+ pngRead.ReadSkippingAllRows( );
151+ pngRead.End( );
152+ //Parse PNG chunks for METADATA in shard
153+ PngMetadataChunk metadataFromPng = pngRead.GetChunksList( ).GetById1(PngMetadataChunk.ID) as PngMetadataChunk;
154+ ColumnMeta columnData = metadataFromPng.ChunkMetadata;
155+
156+ Console.Write("X{0,6:D} Y{1,6:D} Age:{2:N1} ", columnData.Location.X, columnData.Location.Y, columnData.ChunkAge.TotalDays);
157+ Console.Write("YMax:{0:D3} ChkS:{1} Air:{2,7:D} NotAir:{3,7:D} ",
158+ columnData.YMax, columnData.ChunkSize, columnData.AirBlocks, columnData.NonAirBlocks
159+ );
160+ if (columnData.HeightMap != null) {
161+ Console.Write("(Heights [{0}x{1}] ", columnData.HeightMap.GetLength(0), columnData.HeightMap.GetLength(1));
162+ ushort lowest = ushort.MaxValue, highest = 0;
163+ ulong sum = 0;
164+ foreach (var hmEntry in columnData.HeightMap) {
165+ lowest = Math.Min(lowest, hmEntry);
166+ highest = Math.Max(highest, hmEntry);
167+ sum += hmEntry;
168+ }
169+ Console.Write("Max:{0,3}, Min:{1,3}, ", highest, lowest);
170+ if (sum > 0) Console.Write("Avg:{0:F1})", ( float )sum / (columnData.ChunkSize * columnData.ChunkSize));
171+ Console.WriteLine( );
172+ /*------ROCK RATIOs mini-table----------*/
173+ if (columnData.RockRatio != null && columnData.RockRatio.Count > 0) {
174+ Console.Write("Ratios({0,2:D})[", columnData.RockRatio.Count);
175+ foreach (var rock in columnData.RockRatio) {
176+ Console.Write("ID:{0,5:D} x{1,4:D}, ", rock.Key, rock.Value);
177+ }
178+ Console.Write(" ]\n");
179+ }
180+
181+ if (sum == 0 || columnData.YMax == 0) flat++;
182+ }
183+ else {
184+ flat++;
185+ }
186+
187+
188+ }
189+
190+ } catch (PngjException someEx) {
191+ Console.WriteLine("PNG Corruption file '{0}' - Reason: {1}", shardFile.Name, someEx);
192+ errors++;
193+ continue;
194+ } catch (ProtoException protoEx) {
195+ Console.WriteLine("ProtoBuf invalid! file:'{0}' - Reason: {1}", shardFile.Name, protoEx);
196+ errors++;
197+ continue;
198+ }
199+ count++;
200+ }
201+ }
202+
203+ Console.WriteLine("Scanned {0} files, {1} errors, {2} FLAT entries", count, errors, flat);
204+ }
205+
206+ private static void Scan_OneShard( )
207+ {
208+ //--oneshard ~/ApplicationData/vintagestory/Maps/World_1316328588/Chunks/9363_9379.png
209+ var oneChunkFile = new FileInfo(mapPath);
210+ if (oneChunkFile.Exists) {
211+
212+
213+ try {
214+ using (var fileStream = oneChunkFile.OpenRead( )) {
215+
216+ PngReader pngRead = new PngReader(fileStream);
217+ pngRead.ReadSkippingAllRows( );
218+
219+ //Parse PNG chunks for METADATA in shard
220+ PngMetadataChunk metadataFromPng = pngRead.GetChunksList( ).GetById1(PngMetadataChunk.ID) as PngMetadataChunk;
221+ ColumnMeta columnData = metadataFromPng.ChunkMetadata;
222+ var metadata = pngRead.GetMetadata( );
223+ var pngWriteTime = metadata.GetTime( );
224+ var chunkX = metadata.GetTxtForKey(@"Chunk_X");
225+ var chunkY = metadata.GetTxtForKey(@"Chunk_Y");
226+ var pixelSize = metadata.GetTxtForKey(@"PxSz");
227+ var gameDate = metadata.GetTxtForKey(@"GameDY");
228+ var dateBlob = pngWriteTime.GetYMDHMS( );
229+ /*
230+ return new int[] {
231+ this.year,
232+ this.mon,
233+ this.day,
234+ this.hour,
235+ this.min,
236+ this.sec
237+ */
238+
239+ Console.WriteLine($"PNG-Timestamp: Y{dateBlob[0] - 456960} M{dateBlob[1]} D{dateBlob[2]} H{dateBlob[3]} M {dateBlob[4]} S{dateBlob[5]} Chunk: X {chunkX} Y {chunkY} PixelSize:{pixelSize} Game-Date: {gameDate}");
240+
241+ pngRead.End( );
242+ }
243+ } catch (Exception darn) {
244+ Debug.Write("Oops! File causes: {0}", darn.ToString( ));
245+ }
246+
247+ }
248+ }
249+
250+ private static void Emit_ProtoHeader( )
251+ {
252+ Console.WriteLine("Created Protobuf Header files.");
253+ using (var entitiesProto = File.CreateText("Entities.proto")) {
254+ entitiesProto.Write(Serializer.GetProto<EntitiesOfInterest>( ));
255+ entitiesProto.Flush( );
256+ }
257+
258+
259+ using (var pointsProto = File.CreateText("Points.proto")) {
260+ pointsProto.Write(Serializer.GetProto<PointsOfInterest>( ));
261+ pointsProto.Flush( );
262+ }
263+
264+ using (var metadataProto = File.CreateText("ColumnMeta.proto")) {
265+ metadataProto.Write(Serializer.GetProto<ColumnMeta>( ));
266+ metadataProto.Flush( );
267+ }
268+ }
269+
270+ private static void Dump_Minimap( )
271+ {
272+ //Extract MapDB -> Shard compatible PNG?
273+ var logger = new LogAdaptor( );
274+ WalkableMapDB minimapDatabase = new WalkableMapDB(logger);
275+ string outmsg = string.Empty;
276+ logger.Event("Started Logging @{0}", DateTimeOffset.UtcNow.ToString("u"));
277+ Console.WriteLine("Starting to Dump Minimap data");
278+ var tilesPath = Path.GetDirectoryName(mapPath);
279+ Directory.CreateDirectory(Path.Combine(tilesPath, _minimapTilesPath));
280+
281+ if (minimapDatabase.OpenOrCreate(mapPath, ref outmsg, false, false, false)) {
282+
283+ foreach (var mapPiece in minimapDatabase.WalkMapTiles( )) {
284+ logger.VerboseDebug("ScanDB Tile - X:{0} Y:{1}, Bitmap Int#{2}", mapPiece.ChunkPos.X, mapPiece.ChunkPos.Y, mapPiece.Pixels.Length);
285+ MinimalShardWriter(mapPiece.ChunkPos, mapPiece.Pixels, tilesPath,logger);
286+ }
287+
288+ }
289+ else {
290+ logger.Error("Failed to access Minimap Database: '{0}'", outmsg);
291+ }
292+
293+ Console.WriteLine("DONE Dumping Minimap data!");
294+ }
295+
296+ private static void MinimalShardWriter(Vec2i coord, int[] pixelData, string tilesPath, ILogger logger )
297+ {
298+ ImageInfo imageInf = new ImageInfo(chunkDefaultSize, chunkDefaultSize, 8, false);
299+
300+ string filename = $"{coord.X}_{coord.Y}.png";
301+ filename = Path.Combine(tilesPath, _minimapTilesPath, filename);
302+
303+ var PngWriter = FileHelper.CreatePngWriter(filename, imageInf, true);
304+ PngMetadata meta = PngWriter.GetMetadata( );
305+ meta.SetTimeYMDHMS(
306+ DateTime.UtcNow.Year,
307+ DateTime.UtcNow.Month,
308+ DateTime.UtcNow.Day,
309+ DateTime.UtcNow.Hour,
310+ DateTime.UtcNow.Minute,
311+ DateTime.UtcNow.Second);
312+ meta.SetText("Chunk_X", coord.X.ToString("D"));
313+ meta.SetText("Chunk_Y", coord.Y.ToString("D"));
314+ meta.SetText("PxSz", "1");
315+ /*
316+ var transparencyChunk = meta.CreateTRNSChunk( );
317+ transparencyChunk.SetRGB(0, 0, 0);//Same as Snapshots
318+ */
319+ var minimalMetadata = new ColumnMeta(coord);
320+
321+ //Setup specialized meta-data PNG chunks here...
322+ PngMetadataChunk pngChunkMeta = new PngMetadataChunk(PngWriter.ImgInfo) {
323+ ChunkMetadata = minimalMetadata
324+ };
325+ PngWriter.GetChunksList( ).Queue(pngChunkMeta);
326+ PngWriter.CompLevel = 5;// 9 is the maximum compression but thats too high for the small benefit it gives
327+ PngWriter.CompressionStrategy = Hjg.Pngcs.Zlib.EDeflateCompressStrategy.Huffman;
328+
329+ //pre-create PNG line slices...
330+ ImageLine[ ] lines = Enumerable.Repeat(new object( ), chunkDefaultSize).Select(l => new ImageLine(PngWriter.ImgInfo)).ToArray( );
331+
332+ Vec2i pixelPosn = new Vec2i();
333+ for (int pixelIndex = 0; pixelIndex < (chunkDefaultSize * chunkDefaultSize); pixelIndex++) {
334+ MapUtil.PosInt2d(pixelIndex, chunkDefaultSize, pixelPosn);
335+ int red, green, blue;
336+ red = ColorUtil.ColorB(pixelData[pixelIndex]);
337+ green = ColorUtil.ColorG(pixelData[pixelIndex]);
338+ blue = ColorUtil.ColorR(pixelData[pixelIndex]);
339+
340+ ImageLineHelper.SetPixel(lines[pixelPosn.Y], pixelPosn.X, red, green, blue);
341+
342+
343+ }
344+
345+ for (int row = 0; row < PngWriter.ImgInfo.Rows; row++) {
346+ PngWriter.WriteRow(lines[row], row);
347+ }
348+ PngWriter.End( );
349+
350+ logger.Debug("Wrote mini map tile: {0}", coord);
351+ }
352+ }
353+}
354+
--- a/ShardProcessor/Program.cs
+++ b/ShardProcessor/Program.cs
@@ -9,16 +9,18 @@ using Hjg.Pngcs;
99 using Hjg.Pngcs.Chunks;
1010
1111 using ProtoBuf;
12+using Vintagestory.GameContent;
1213
1314 namespace ShardProcessor
1415 {
15- class MainClass
16+ public partial class MainClass
1617 {
1718 //private ILogger Logger { get; set; }
1819 const string chunkFile_filter = @"*_*.png";
1920 static Regex chunkShardRegex = new Regex(@"(?<X>[\d]+)_(?<Z>[\d]+)\.png", RegexOptions.Singleline);
2021 static string mapPath;
2122 internal const string _chunkPath = @"Chunks";
23+ internal const string _minimapTilesPath = @"Tiles";
2224
2325 /* TODO:
2426 -Process existing PNGs: Report/Dump contents of Chunk Metadata, as per current version
@@ -67,6 +69,10 @@ namespace ShardProcessor
6769 Emit_ProtoHeader();
6870 break;
6971
72+ case "--minidump":
73+ Dump_Minimap( );
74+ break;
75+
7076 default:
7177 Console.WriteLine("Unrecognized Command: {0}", command);
7278 break;
@@ -76,247 +82,7 @@ namespace ShardProcessor
7682
7783 }
7884
79- private static void Process_ShardData( )
80- {
81- var shardsDir = new DirectoryInfo( Path.Combine(mapPath , _chunkPath));
82-
83- var shardFiles = shardsDir.GetFiles(chunkFile_filter);
84-
85- if (shardFiles.Length > 0) {
86- #if DEBUG
87- //Logger.VerboseDebug("Metadata reloading from {0} shards", shardFiles.Length);
88- #endif
89-
90- foreach (var shardFile in shardFiles) {
91-
92- if (shardFile.Length < 1024) continue;
93- var result = chunkShardRegex.Match(shardFile.Name);
94- if (!result.Success) continue;
95-
96- int X_chunk_pos = int.Parse(result.Groups["X"].Value);
97- int Z_chunk_pos = int.Parse(result.Groups["Z"].Value);
98-
99- try {
100- using (var fileStream = shardFile.OpenRead( )) {
101-
102- PngReader pngRead = new PngReader(fileStream);
103- pngRead.ReadSkippingAllRows( );
104- pngRead.End( );
105- //Parse PNG chunks for METADATA in shard
106- PngMetadataChunk metadataFromPng = pngRead.GetChunksList( ).GetById1(PngMetadataChunk.ID) as PngMetadataChunk;
107- ColumnMeta columnData = metadataFromPng.ChunkMetadata;
108- //columnData.HeightMap //Should be sane Heightmap...
109-
110-
111-
112- }
113-
114- } catch (PngjException someEx) {
115- //Logger.Error("PNG Corruption file '{0}' - Reason: {1}", shardFile.Name, someEx);
116- continue;
117- } catch (ProtoException protoEx) {
118- //Logger.Error("ProtoBuf invalid! file:'{0}' - Reason: {1}", shardFile.Name, protoEx);
119- continue;
120- }
121- }
122- }
123-
124-
125- }
126-
127-
128- private static void Scan_PointsData( )
129- {
130- try {
131- var eoiFile = new FileInfo(Path.Combine(mapPath, @"eoi_binary"));
132- var poiFile = new FileInfo(Path.Combine(mapPath, @"poi_binary"));
133- uint entities = 0, points = 0;
134-
135- if (eoiFile.Exists) {
136- using (var eoiStream = eoiFile.OpenRead( )) {
137-
138- EntitiesOfInterest eoiData = Serializer.Deserialize<EntitiesOfInterest>(eoiStream);
139-
140- foreach (var entry in eoiData) {
141- Console.WriteLine("#{0}, [{1}], '{2}', {3}",
142- entry.EntityId,
143- entry.Location,
144- entry.Name,
145- entry.Timestamp.ToUniversalTime( )
146- );
147- entities++;
148- }
149- Console.WriteLine("Entities Of Interest: {0}", entities);
150- }
151-
152-
153- if (poiFile.Exists) {
154- using (var poiStream = poiFile.OpenRead( )) {
155-
156- PointsOfInterest poiData = Serializer.Deserialize<PointsOfInterest>(poiStream);
157- foreach (var entry in poiData) {
158- Console.WriteLine("[{0}], {1}, {2}, {3}",
159- entry.Location,
160- entry.Name,
161- entry.Destination,
162- entry.Timestamp.ToUniversalTime( )
163- );
164- points++;
165- }
166- }
167- Console.WriteLine("Points Of Interest: {0}", points);
168- }
169-
170- }
171- } catch (Exception uhOh) {
172- Console.WriteLine(uhOh);
173- }
174-
175- }
176-
177- private static void Scan_ShardData( )
178- {
179- var shardsDir = new DirectoryInfo(Path.Combine(mapPath, _chunkPath));
180- ulong count = 0,errors = 0, flat = 0;
181- var shardFiles = shardsDir.GetFiles(chunkFile_filter);
182-
183- if (shardFiles.Length > 0) {
184- #if DEBUG
185- //Logger.VerboseDebug("Metadata reloading from {0} shards", shardFiles.Length);
186- #endif
18785
188- foreach (var shardFile in shardFiles) {
18986
190- if (shardFile.Length < 1024) {
191- Console.WriteLine("File: '{0}' too small to be valid; skipping!", shardFile.FullName);
192- errors++;
193- continue;
194- }
195-
196- var result = chunkShardRegex.Match(shardFile.Name);
197- if (!result.Success) continue;
198-
199- int X_chunk_pos = int.Parse(result.Groups["X"].Value);
200- int Z_chunk_pos = int.Parse(result.Groups["Z"].Value);
201-
202- try {
203- using (var fileStream = shardFile.OpenRead( )) {
204-
205- PngReader pngRead = new PngReader(fileStream);
206- pngRead.ReadSkippingAllRows( );
207- pngRead.End( );
208- //Parse PNG chunks for METADATA in shard
209- PngMetadataChunk metadataFromPng = pngRead.GetChunksList( ).GetById1(PngMetadataChunk.ID) as PngMetadataChunk;
210- ColumnMeta columnData = metadataFromPng.ChunkMetadata;
211-
212- Console.Write("X{0,6:D} Y{1,6:D} Age:{2:N1} ", columnData.Location.X, columnData.Location.Y, columnData.ChunkAge.TotalDays);
213- Console.Write("YMax:{0:D3} ChkS:{1} Air:{2,7:D} NotAir:{3,7:D} ",
214- columnData.YMax,columnData.ChunkSize , columnData.AirBlocks, columnData.NonAirBlocks
215- );
216- if (columnData.HeightMap != null) {
217- Console.Write("(Heights [{0}x{1}] ", columnData.HeightMap.GetLength(0), columnData.HeightMap.GetLength(1));
218- ushort lowest = ushort.MaxValue, highest = 0;
219- ulong sum = 0;
220- foreach (var hmEntry in columnData.HeightMap) {
221- lowest = Math.Min(lowest, hmEntry);
222- highest = Math.Max(highest, hmEntry);
223- sum += hmEntry;
224- }
225- Console.Write("Max:{0,3}, Min:{1,3}, ", highest, lowest);
226- if (sum > 0) Console.Write("Avg:{0:F1})", ( float )sum / (columnData.ChunkSize * columnData.ChunkSize));
227- Console.WriteLine( );
228- /*------ROCK RATIOs mini-table----------*/
229- if (columnData.RockRatio != null && columnData.RockRatio.Count > 0) {
230- Console.Write("Ratios({0,2:D})[",columnData.RockRatio.Count);
231- foreach (var rock in columnData.RockRatio) {
232- Console.Write("ID:{0,5:D} x{1,4:D}, ", rock.Key, rock.Value);
233- }
234- Console.Write(" ]\n");
235- }
236-
237- if ( sum == 0 || columnData.YMax == 0) flat++;
238- }
239- else {
240- flat++;
241- }
242-
243-
244- }
245-
246- } catch (PngjException someEx) {
247- Console.WriteLine("PNG Corruption file '{0}' - Reason: {1}", shardFile.Name, someEx);
248- errors++;
249- continue;
250- } catch (ProtoException protoEx) {
251- Console.WriteLine("ProtoBuf invalid! file:'{0}' - Reason: {1}", shardFile.Name, protoEx);
252- errors++;
253- continue;
254- }
255- count++;
256- }
257- }
258-
259- Console.WriteLine("Scanned {0} files, {1} errors, {2} FLAT entries", count, errors, flat);
260- }
261-
262- private static void Scan_OneShard( )
263- {
264- //--oneshard ~/ApplicationData/vintagestory/Maps/World_1316328588/Chunks/9363_9379.png
265- var oneChunkFile = new FileInfo(mapPath);
266- if (oneChunkFile.Exists) {
267-
268-
269- try {
270- using (var fileStream = oneChunkFile.OpenRead( )) {
271-
272- PngReader pngRead = new PngReader(fileStream);
273- pngRead.ReadSkippingAllRows( );
274-
275- //Parse PNG chunks for METADATA in shard
276- PngMetadataChunk metadataFromPng = pngRead.GetChunksList( ).GetById1(PngMetadataChunk.ID) as PngMetadataChunk;
277- ColumnMeta columnData = metadataFromPng.ChunkMetadata;
278- var metadata = pngRead.GetMetadata( );
279- var pngWriteTime = metadata.GetTime( );
280- var chunkX = metadata.GetTxtForKey(@"Chunk_X");
281- var chunkY = metadata.GetTxtForKey(@"Chunk_Y");
282- var pixelSize = metadata.GetTxtForKey(@"PxSz");
283- var gameDate = metadata.GetTxtForKey(@"GameDY");
284- var dateBlob = pngWriteTime.GetYMDHMS( );
285- /*
286- return new int[] {
287- this.year,
288- this.mon,
289- this.day,
290- this.hour,
291- this.min,
292- this.sec
293- */
294-
295- Console.WriteLine($"PNG-Timestamp: Y{dateBlob[0] - 456960} M{dateBlob[1]} D{dateBlob[2]} H{dateBlob[3]} M {dateBlob[4]} S{dateBlob[5]} Chunk: X {chunkX} Y {chunkY} PixelSize:{pixelSize} Game-Date: {gameDate}");
296-
297- pngRead.End( );
298- }
299- } catch (Exception darn) {
300- Debug.Write("Oops! File causes: {0}", darn.ToString( ));
301- }
302-
303- }
304- }
305-
306- private static void Emit_ProtoHeader( )
307- {
308- Console.WriteLine("Created Protobuf Header files.");
309- using (var entitiesProto = File.CreateText("Entities.protoc"))
310- {
311- entitiesProto.Write(Serializer.GetProto<EntitiesOfInterest>( ));
312- entitiesProto.Flush( );
313- }
314-
315-
316- using (var pointsProto = File.CreateText("Points.protoc")) {
317- pointsProto.Write(Serializer.GetProto<PointsOfInterest>( ));
318- pointsProto.Flush( );
319- }
320- }
32187 }
32288 }
--- a/ShardProcessor/ShardProcessor.csproj
+++ b/ShardProcessor/ShardProcessor.csproj
@@ -53,10 +53,17 @@
5353 <Reference Include="VSSurvivalMod">
5454 <HintPath>..\Automap\VS_libs\VSSurvivalMod.dll</HintPath>
5555 </Reference>
56+ <Reference Include="System.Data" />
57+ <Reference Include="System.Data.SQLite">
58+ <HintPath>..\Automap\VS_libs\System.Data.SQLite.dll</HintPath>
59+ </Reference>
5660 </ItemGroup>
5761 <ItemGroup>
5862 <Compile Include="Program.cs" />
5963 <Compile Include="Properties\AssemblyInfo.cs" />
64+ <Compile Include="LogAdaptor.cs" />
65+ <Compile Include="WalkableMapDB.cs" />
66+ <Compile Include="ProcessingMethods.cs" />
6067 </ItemGroup>
6168 <ItemGroup>
6269 <ProjectReference Include="..\Automap\Automap.csproj">
--- /dev/null
+++ b/ShardProcessor/WalkableMapDB.cs
@@ -0,0 +1,81 @@
1+using System;
2+using System.Linq;
3+using System.Collections.Generic;
4+using System.Data;
5+using System.Data.Common;
6+using System.Data.SQLite;
7+
8+using ProtoBuf;
9+
10+
11+
12+using Vintagestory.API.Common;
13+using Vintagestory.GameContent;
14+using Vintagestory.API.Util;
15+using Vintagestory.API.MathTools;
16+
17+namespace ShardProcessor
18+{
19+ public class WalkableMapDB : MapDB
20+ {
21+ private SQLiteCommand walkMapPieceCmd;
22+
23+ public WalkableMapDB(ILogger logger) : base(logger)
24+ {
25+ }
26+
27+ public override void OnOpened( )
28+ {
29+ base.OnOpened( );
30+
31+ walkMapPieceCmd = sqliteConn.CreateCommand( );
32+ walkMapPieceCmd.CommandText = @"SELECT position, data FROM mappiece";
33+ walkMapPieceCmd.Prepare( );
34+ }
35+
36+
37+ public IEnumerable<LocalizedMapPiece> WalkMapTiles( )
38+ {
39+ using (SQLiteDataReader sqlite_datareader = walkMapPieceCmd.ExecuteReader( ))
40+ {
41+ int numForPos = sqlite_datareader.GetOrdinal(@"position");
42+ int numForData = sqlite_datareader.GetOrdinal(@"data");
43+
44+ while (sqlite_datareader.Read( ))
45+ {
46+ var posInteger = sqlite_datareader.GetInt64(numForPos);//[];//Integer KEY
47+ object data = sqlite_datareader[numForData];
48+ if (data == null) yield return null;
49+
50+ var rawMapP = SerializerUtil.Deserialize<MapPieceDB>(data as byte[ ]);
51+
52+ var nextPiece = new LocalizedMapPiece( ) {
53+ ChunkPos = posInteger.Convert(),
54+ Pixels = rawMapP.Pixels,
55+ };
56+
57+ yield return nextPiece;
58+ }
59+ }
60+ }
61+ }
62+
63+ public class LocalizedMapPiece : MapPieceDB
64+ {
65+ public Vec2i ChunkPos;
66+
67+ }
68+
69+ public static class MapDB_Assist
70+ {
71+ public static Vec2i Convert(this long input)
72+ {
73+ var vector = new Vec2i( );
74+ vector.X = ( int )(0x7FFFFFF & input); //Passthru only last 27 bits
75+ vector.Y = ( int )(input >> 27 );//Shift 27 right
76+ return vector;
77+ }
78+ }
79+
80+}
81+