X-Git-Url: http://git.osdn.net/view?p=automap%2Fautomap.git;a=blobdiff_plain;f=Automap%2FSubsystems%2FAutomapSystem.cs;h=abbfc44ecb1fe155f5a93f3893e8f1011e9a6115;hp=d07624f1217bbfc19be8999a2b296002e62090e4;hb=a5cf48106e5ad88de4153de6393b122c5096c3fb;hpb=c01a95257de7335354c985472f6924bf80cce0aa diff --git a/Automap/Subsystems/AutomapSystem.cs b/Automap/Subsystems/AutomapSystem.cs index d07624f..abbfc44 100644 --- a/Automap/Subsystems/AutomapSystem.cs +++ b/Automap/Subsystems/AutomapSystem.cs @@ -33,18 +33,19 @@ namespace Automap internal const string _mapPath = @"Maps"; internal const string _chunkPath = @"Chunks"; - internal const uint editThreshold = 1; + internal const uint editThreshold = 9; private const string _domain = @"automap"; private const string chunkFile_filter = @"*_*.png"; private const string poiFileName = @"poi_binary"; private const string eoiFileName = @"eoi_binary"; private const string pointsTsvFileName = @"points_of_interest.tsv"; + private const string plainMetadataFileName = @"map_metadata.txt"; private static Regex chunkShardRegex = new Regex(@"(?[\d]+)_(?[\d]+)\.png", RegexOptions.Singleline); private ConcurrentDictionary columnCounters = new ConcurrentDictionary(3, 150); private ColumnsMetadata chunkTopMetadata; - private PointsOfInterest POIs = new PointsOfInterest(); - private EntitiesOfInterest EOIs = new EntitiesOfInterest(); + internal PointsOfInterest POIs = new PointsOfInterest(); + internal EntitiesOfInterest EOIs = new EntitiesOfInterest(); internal Dictionary BlockID_Designators { get; private set; } internal Dictionary Entity_Designators { get; private set; } @@ -70,11 +71,11 @@ namespace Automap this.ClientAPI = clientAPI; this.Logger = logger; chunkSize = ClientAPI.World.BlockAccessor.ChunkSize; - ClientAPI.Event.LevelFinalize += EngageAutomap; + configuration = config; + ClientAPI.Event.LevelFinalize += EngageAutomap; - //TODO:Choose which one from GUI - this.ChunkRenderer = new StandardRenderer(clientAPI, logger, this.configuration.SeasonalColors); + this.ChunkRenderer = InstantiateChosenRenderer(config.RendererName); //Listen on bus for commands ClientAPI.Event.RegisterEventBusListener(CommandListener, 1.0, AutomapSystem.AutomapCommandEventKey); @@ -138,7 +139,7 @@ namespace Automap columnCounters.AddOrUpdate(topPosition, new ColumnCounter(chunkSize, newOrEdit, chunkCoord), - (chkPos, chkChng) => chkChng.Update(chunkCoord, chunkSize) + (chkPos, chkChng) => chkChng.Update(chunkCoord, chunkSize, newOrEdit) ); } @@ -203,7 +204,9 @@ namespace Automap if (mapChunk == null) { //TODO: REVISIT THIS CHUNK! + #if DEBUG Logger.Warning("SKIP CHUNK: ({0}) - Map Chunk NULL!", mostActiveCol.Key); + #endif nullMapCount++; columnCounters.TryRemove(mostActiveCol.Key, out ejectedItem); continue; @@ -225,6 +228,7 @@ namespace Automap #endif } ProcessChunkBlocks(mostActiveCol.Key, mapChunk, ref chunkMeta); + mostActiveCol.Value.SetCutoff(chunkMeta.YMax / chunkSize); ChunkRenderer.SetupPngImage(mostActiveCol.Key, path, _chunkPath, ref chunkMeta); ChunkRenderer.GenerateChunkPngShard(mostActiveCol.Key, mapChunk, chunkMeta, ref chunkTopMetadata, out updatedPixels); @@ -295,6 +299,7 @@ namespace Automap Logger.VerboseDebug("Thread '{0}' executing finally block.", Thread.CurrentThread.Name); #endif PersistPointsData(); + Write_PlainMetadata( ); } } @@ -339,7 +344,7 @@ namespace Automap var airBlocksQuery = from airyBlock in ClientAPI.World.Blocks where airyBlock.MatterState == EnumMatterState.Solid where airyBlock.BlockMaterial == EnumBlockMaterial.Plant || airyBlock.BlockMaterial == EnumBlockMaterial.Leaves - where airyBlock.CollisionBoxes == null || airyBlock.CollisionBoxes.Length == 0 + where airyBlock.CollisionBoxes == null || airyBlock.CollisionBoxes.Length == 0 ||airyBlock.RainPermeable == true select airyBlock; //^^ 'Solid' phase - 'Plant' Blocks without any boundg box ? Except water... this.AiryIdCodes = airBlocksQuery.ToDictionary(aBlk => aBlk.BlockId, aBlk => aBlk.Code.Path); @@ -350,34 +355,36 @@ namespace Automap private void Reload_POI_Designators() { - Logger.VerboseDebug("Connecting {0} Configured Block-Designators", configuration.BlockDesignators.Count); + uint poisSetup =0, eoiSetup = 0; foreach (var designator in configuration.BlockDesignators) { + if (designator.Enabled == false) continue; var blockIDs = Helpers.ArbitrarytBlockIdHunter(ClientAPI, designator.Pattern, designator.Material); if (blockIDs.Count > 0) { Logger.VerboseDebug("Designator {0} has {1} associated blockIDs", designator.ToString(), blockIDs.Count); } foreach (var entry in blockIDs) { BlockID_Designators.Add(entry.Key, designator); + poisSetup++; } } this.ChunkRenderer.BlockID_Designators = BlockID_Designators; + Logger.VerboseDebug("Connected {0} IDs from {1} Block-Designators", poisSetup, configuration.BlockDesignators.Count ); - Logger.VerboseDebug("Connecting {0} Configured Entity-Designators", configuration.EntityDesignators.Count); foreach (var designator in configuration.EntityDesignators) { + if (designator.Enabled == false) continue; //Get Variants first, from EntityTypes...better be populated! var matched = ClientAPI.World.EntityTypes.FindAll(entp => entp.Code.BeginsWith(designator.Pattern.Domain, designator.Pattern.Path)); foreach (var match in matched) - { + { Logger.VerboseDebug("Linked Entity: {0} Designator: {1}", match.Code, designator); this.Entity_Designators.Add(match.Code, designator); + eoiSetup++; } - - //EntityProperties props = ClientAPI.World.GetEntityType(designator.Pattern); } - + Logger.VerboseDebug("Connected {0} IDs from {1} Entity-Designators", eoiSetup, configuration.EntityDesignators.Count); } @@ -395,17 +402,19 @@ namespace Automap if (this.POIs.Count > 0) { - using (var poiFile = File.OpenWrite(poiPath)) + using (var poiFile = File.Open(poiPath, FileMode.Create, FileAccess.Write, FileShare.None)) { Serializer.Serialize(poiFile, this.POIs); + poiFile.Flush(true); } } if (this.EOIs.Count > 0) { - using (var eoiFile = File.OpenWrite(eoiPath)) + using (var eoiFile = File.Open(eoiPath, FileMode.Create, FileAccess.Write, FileShare.None)) { Serializer.Serialize(eoiFile, this.EOIs); + eoiFile.Flush(true); } } @@ -414,31 +423,33 @@ namespace Automap using (var tsvWriter = new StreamWriter(pointsTsvPath, false, Encoding.UTF8)) { - tsvWriter.WriteLine("Name\tDescription\tLocation\tTime\tDestination"); + tsvWriter.WriteLine("Name\tDescription\tLocation\tTime\tDestination\tEntity_UID"); foreach (var point in this.POIs) { tsvWriter.Write(point.Name + "\t"); var notes = point.Notes - .Replace("\n", "\\n") + .Replace('\n', '\x001f') .Replace("\t", "\\t") .Replace("\\", "\\\\"); tsvWriter.Write(notes + "\t"); tsvWriter.Write(point.Location.PrettyCoords(ClientAPI) + "\t"); tsvWriter.Write(point.Timestamp.ToString("u") + "\t"); tsvWriter.Write((point.Destination != null ? point.Destination.PrettyCoords(ClientAPI) : "---") +"\t"); + tsvWriter.Write("null\t"); tsvWriter.WriteLine(); } foreach (var entity in this.EOIs) { tsvWriter.Write(entity.Name + "\t"); var notes = entity.Notes - .Replace("\n", "\\n") + .Replace('\n', '\x001f') .Replace("\t", "\\t") .Replace("\\", "\\\\"); tsvWriter.Write(notes + "\t"); tsvWriter.Write(entity.Location.PrettyCoords(ClientAPI) + "\t"); tsvWriter.Write(entity.Timestamp.ToString("u") + "\t"); - tsvWriter.Write("n/a\t"); + tsvWriter.Write("---\t"); + tsvWriter.Write(entity.EntityId.ToString("D")); tsvWriter.WriteLine(); } tsvWriter.WriteLine(); @@ -447,6 +458,32 @@ namespace Automap } + private void Write_PlainMetadata( ) + { + string metaPath = Path.Combine(path, plainMetadataFileName); + + using (var metaDataFile = File.Open(metaPath,FileMode.Create)) { + using (var mdWriter = new StreamWriter(metaDataFile, Encoding.ASCII)) + { + mdWriter.WriteLine("WorldSeed {0}", ClientAPI.World.Seed); + mdWriter.WriteLine("PlayerChunkCoords {0:D} {1:D}", startChunkColumn.X, startChunkColumn.Y); + mdWriter.WriteLine("DefaultSpawnPos {0:D} {1:D} {2:D}", ClientAPI.World.DefaultSpawnPosition.AsBlockPos.X,ClientAPI.World.DefaultSpawnPosition.AsBlockPos.Y,ClientAPI.World.DefaultSpawnPosition.AsBlockPos.Z); + mdWriter.WriteLine("ChunkSize {0}", chunkSize); + mdWriter.WriteLine("SeaLevel {0:D}", ClientAPI.World.SeaLevel); + mdWriter.WriteLine("WorldSize {0:D} {1:D} {2:D}", ClientAPI.World.BulkBlockAccessor.MapSizeX, ClientAPI.World.BulkBlockAccessor.MapSizeY,ClientAPI.World.BulkBlockAccessor.MapSizeZ); + mdWriter.WriteLine("RegionSize {0:D}", ClientAPI.World.BulkBlockAccessor.RegionSize); + mdWriter.WriteLine("AMVersion '{0}'", ClientAPI.Self().Info.Version); + mdWriter.WriteLine("PlayTime {0:F1}", ClientAPI.InWorldEllapsedMilliseconds / 1000); + mdWriter.WriteLine("GameDate {0}", ClientAPI.World.Calendar.PrettyDate()); + mdWriter.WriteLine("Chunks {0:D}", chunkTopMetadata.Count); + mdWriter.WriteLine("Chunks Updated {0:D}", updatedChunksTotal); + mdWriter.WriteLine("Null Chunks {0:D}", nullChunkCount); + mdWriter.Flush( ); + } + } + } + + private ColumnMeta CreateColumnMetadata(KeyValuePair mostActiveCol, IMapChunk mapChunk) { ColumnMeta data = new ColumnMeta(mostActiveCol.Key.Copy(), ClientAPI, (byte) chunkSize, (ClientAPI.World.BlockAccessor.MapSizeY / chunkSize)); @@ -582,7 +619,9 @@ namespace Automap if (worldChunk.IsPacked()) { + #if DEBUG Logger.VerboseDebug("WORLD chunk: Compressed: X{0} Y{1} Z{2}", key.X, targetChunkY, key.Y); + #endif worldChunk.Unpack( );//RESEARCH: Thread Unsafe? } @@ -595,10 +634,10 @@ namespace Automap foreach (var blockEnt in worldChunk.BlockEntities) { - if (blockEnt.Value != null && blockEnt.Value.Block != null && BlockID_Designators.ContainsKey(blockEnt.Value.Block.BlockId)) + if (blockEnt.Key != null && blockEnt.Value != null && blockEnt.Value.Block != null && BlockID_Designators.ContainsKey(blockEnt.Value.Block.BlockId)) { var designator = BlockID_Designators[blockEnt.Value.Block.BlockId]; - designator.SpecialAction(ClientAPI, POIs, blockEnt.Value.Pos.Copy(), blockEnt.Value.Block); + designator?.SpecialAction(ClientAPI, POIs, blockEnt.Value.Pos.Copy(), blockEnt.Value.Block); } } } @@ -610,7 +649,9 @@ namespace Automap //First Chance fail-safe; if (worldChunk.Blocks == null || worldChunk.Blocks.Length <= 0) { + #if DEBUG Logger.VerboseDebug("WORLD chunk; Missing block DATA⁈ X{0} Y{1} Z{2} ⁈", key.X, targetChunkY, key.Y); + #endif nullChunkCount++; continue; } @@ -627,9 +668,11 @@ namespace Automap //'Last' Chance fail-safe; if (worldChunk.Blocks == null || worldChunk.Blocks.Length <= 0) { + #if DEBUG Logger.VerboseDebug("Processing Block: Missing block DATA⁈ X{0} Y{1} Z{2} ⁈", X_index, Y_index, Z_index); + #endif nullChunkCount++; - goto loop_bustout; ; + goto loop_bustout; } int aBlockId = worldChunk.Blocks[indicie]; @@ -660,12 +703,16 @@ namespace Automap } loop_bustout:; } + #if DEBUG Logger.VerboseDebug("COLUMN X{0} Z{1}: {2}, processed.", key.X , key.Y, chunkTally + 1); + #endif } private void UpdateEntityMetadata() { + #if DEBUG Logger.Debug("Presently {0} Entities", ClientAPI.World.LoadedEntities.Count); + #endif //Mabey scan only for 'new' entities by tracking ID in set? foreach (var loadedEntity in ClientAPI.World.LoadedEntities.ToArray()) { @@ -723,12 +770,32 @@ namespace Automap AddNote(cmdData.Notation); break; } -#if DEBUG + ClientAPI.TriggerChatMessage($"Automap commanded to: {cmdData.State} "); -#endif + + } +#endregion + + private AChunkRenderer InstantiateChosenRenderer(string rendererName ) + { + Logger.VerboseDebug("Using '{0}' style Shard Renderer", rendererName); + switch (rendererName) + { + case StandardRenderer.Name: + return new StandardRenderer(ClientAPI, Logger, this.configuration.SeasonalColors); + + case AlternateRenderer.Name: + return new AlternateRenderer(ClientAPI, Logger, this.configuration.SeasonalColors); + + case FlatRenderer.Name: + return new FlatRenderer(ClientAPI, Logger, this.configuration.SeasonalColors); + + default: + throw new ArgumentOutOfRangeException("rendererName",rendererName,"That value isn't supported or known..."); } - #endregion + return null; + } } }