Automap (client) [VS plugin mod]
Revision | 6f21853a9ca96dc7cd115f471e296e6f8d3ab655 (tree) |
---|---|
Zeit | 2022-01-15 06:24:39 |
Autor | melchior <melchior@user...> |
Commiter | melchior |
Snapshots crash fix
moved snappies to main thread - now also singular use,
fixes multi-click exception
@@ -7,7 +7,7 @@ | ||
7 | 7 | <OutputType>Library</OutputType> |
8 | 8 | <RootNamespace>Automap</RootNamespace> |
9 | 9 | <AssemblyName>Automap</AssemblyName> |
10 | - <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion> | |
10 | + <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> | |
11 | 11 | </PropertyGroup> |
12 | 12 | <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> |
13 | 13 | <DebugSymbols>true</DebugSymbols> |
@@ -239,9 +239,9 @@ namespace Automap | ||
239 | 239 | |
240 | 240 | internal static void DecodeTranslocator(ICoreClientAPI clientAPI, PointsOfInterest poi, BlockPos posn, Block block) |
241 | 241 | { |
242 | -#if DEBUG | |
242 | + #if DEBUG | |
243 | 243 | clientAPI.Logger.VerboseDebug("TRANSLOCATOR Designator Invoked!"); |
244 | -#endif | |
244 | + #endif | |
245 | 245 | //Where to? and from! |
246 | 246 | |
247 | 247 | BlockEntityStaticTranslocator te = clientAPI.World.BlockAccessor.GetBlockEntity(posn) as BlockEntityStaticTranslocator; |
@@ -249,9 +249,9 @@ namespace Automap | ||
249 | 249 | if (te != null) { |
250 | 250 | //FIXME: Delayed rescan ? |
251 | 251 | StringBuilder textTarget = new StringBuilder( ); |
252 | - //translocatorEntity.GetBlockInfo(clientAPI.World.Player, textTarget); | |
252 | + | |
253 | 253 | textTarget.Append(te.FullyRepaired ? "Functional, " : "Broken, "); |
254 | - textTarget.Append(te.Activated ? "Online, " : "Offline, "); | |
254 | + textTarget.Append(te.Activated ? "Online, " : "Offline, ");//Property hardcoded TRUE ?! | |
255 | 255 | textTarget.Append(" Target: [ "); |
256 | 256 | textTarget.Append(te.TargetLocation != null ? "Set ]" : "Invalid ]");//Or ABS coords? |
257 | 257 | textTarget.AppendFormat(", Range ({0} ~ {1})", te.MinTeleporterRangeInBlocks, te.MaxTeleporterRangeInBlocks); |
@@ -24,7 +24,7 @@ namespace Automap | ||
24 | 24 | public class AutomapSystem |
25 | 25 | { |
26 | 26 | private Thread cartographer_thread; |
27 | - private Thread snapshotThread; | |
27 | + | |
28 | 28 | private Snapshotter snapshot; |
29 | 29 | private ICoreClientAPI ClientAPI { get; set; } |
30 | 30 | private ILogger Logger { get; set; } |
@@ -84,7 +84,7 @@ namespace Automap | ||
84 | 84 | if (configuration.Autostart) |
85 | 85 | { |
86 | 86 | CurrentState = CommandType.Run; |
87 | - Logger.Debug("Autostart is Enabled."); | |
87 | + Logger.Notification("Autostart is Enabled."); | |
88 | 88 | } |
89 | 89 | |
90 | 90 | } |
@@ -121,15 +121,7 @@ namespace Automap | ||
121 | 121 | IsBackground = true |
122 | 122 | }; |
123 | 123 | |
124 | - snapshot = new Snapshotter(path, chunkTopMetadata, chunkSize,ClientAPI.World.Seed ); | |
125 | - snapshotThread = new Thread(Snap) | |
126 | - { | |
127 | - Name = "Snapshot", | |
128 | - Priority = ThreadPriority.Lowest, | |
129 | - IsBackground = true | |
130 | - }; | |
131 | - | |
132 | - ClientAPI.Event.RegisterGameTickListener(AwakenCartographer, 6000); | |
124 | + ClientAPI.Event.RegisterGameTickListener(ThreadDecider, 6000); | |
133 | 125 | } |
134 | 126 | |
135 | 127 | private void ChunkAChanging(Vec3i chunkCoord, IWorldChunk chunk, EnumChunkDirtyReason reason) |
@@ -144,14 +136,18 @@ namespace Automap | ||
144 | 136 | |
145 | 137 | } |
146 | 138 | |
147 | - private void AwakenCartographer(float delayed) | |
139 | + /// <summary> | |
140 | + /// Cartographer Thread 'decider' | |
141 | + /// </summary> | |
142 | + /// <param name="delayed">called delay offset</param> | |
143 | + private void ThreadDecider(float delayed) | |
148 | 144 | { |
149 | 145 | |
150 | 146 | if (CurrentState == CommandType.Run && (ClientAPI.IsGamePaused != false || ClientAPI.IsShuttingDown != true)) |
151 | 147 | { |
152 | -#if DEBUG | |
153 | - Logger.VerboseDebug("Cartographer re-trigger from [{0}]", cartographer_thread.ThreadState); | |
154 | -#endif | |
148 | + #if DEBUG | |
149 | + Logger.VerboseDebug("ThreadDecider re-trigger from [{0}]", cartographer_thread.ThreadState); | |
150 | + #endif | |
155 | 151 | |
156 | 152 | if (cartographer_thread.ThreadState.HasFlag(ThreadState.Unstarted)) |
157 | 153 | { |
@@ -168,15 +164,22 @@ namespace Automap | ||
168 | 164 | } |
169 | 165 | else if (CurrentState == CommandType.Snapshot) |
170 | 166 | { |
171 | - if (snapshotThread.ThreadState.HasFlag(ThreadState.Unstarted)) | |
172 | - { | |
173 | - snapshotThread.Start(); | |
174 | - } else if (snapshotThread.ThreadState.HasFlag(ThreadState.WaitSleepJoin)) | |
175 | - { | |
176 | - snapshotThread.Interrupt(); | |
167 | + //Prepare for taking a snopshot | |
168 | + if (snapshot == null) { | |
169 | + snapshot = new Snapshotter(path, chunkTopMetadata, chunkSize, ClientAPI.World.Seed); | |
170 | + #if DEBUG | |
171 | + Logger.VerboseDebug("Starting new Snapshot: {0} Wx{1} Hx{2}", snapshot.fileName, snapshot.Width, snapshot.Height); | |
172 | + #endif | |
173 | + snapshot.Take( ); | |
174 | + } | |
175 | + else if (snapshot != null && snapshot.Finished) { | |
176 | + #if DEBUG | |
177 | + Logger.VerboseDebug("COMPLETED Snapshot: {0} Wx{1} Hx{2}, taking {3}", snapshot.fileName, snapshot.Width, snapshot.Height, snapshot.Timer.Elapsed); | |
178 | + #endif | |
179 | + snapshot = null; | |
180 | + CurrentState = CommandType.Run; | |
177 | 181 | } |
178 | 182 | } |
179 | - | |
180 | 183 | } |
181 | 184 | |
182 | 185 |
@@ -468,6 +471,7 @@ namespace Automap | ||
468 | 471 | mdWriter.WriteLine("WorldSeed {0}", ClientAPI.World.Seed); |
469 | 472 | mdWriter.WriteLine("PlayerChunkCoords {0:D} {1:D}", startChunkColumn.X, startChunkColumn.Y); |
470 | 473 | mdWriter.WriteLine("DefaultSpawnPos {0:D} {1:D} {2:D}", ClientAPI.World.DefaultSpawnPosition.AsBlockPos.X,ClientAPI.World.DefaultSpawnPosition.AsBlockPos.Y,ClientAPI.World.DefaultSpawnPosition.AsBlockPos.Z); |
474 | + //mdWriter.WriteLine("CurrentPlayerSpawn", ClientAPI.World.Player.WorldData.EntityPlayer.); | |
471 | 475 | mdWriter.WriteLine("ChunkSize {0}", chunkSize); |
472 | 476 | mdWriter.WriteLine("SeaLevel {0:D}", ClientAPI.World.SeaLevel); |
473 | 477 | mdWriter.WriteLine("WorldSize {0:D} {1:D} {2:D}", ClientAPI.World.BulkBlockAccessor.MapSizeX, ClientAPI.World.BulkBlockAccessor.MapSizeY,ClientAPI.World.BulkBlockAccessor.MapSizeZ); |
@@ -761,7 +765,7 @@ namespace Automap | ||
761 | 765 | if (CurrentState != cmdData.State) |
762 | 766 | { |
763 | 767 | CurrentState = cmdData.State; |
764 | - AwakenCartographer(0.0f); | |
768 | + ThreadDecider(0.0f); | |
765 | 769 | } |
766 | 770 | break; |
767 | 771 |
@@ -13,37 +13,50 @@ namespace Automap | ||
13 | 13 | { |
14 | 14 | public class Snapshotter |
15 | 15 | { |
16 | - public readonly int chunkSize; | |
17 | 16 | private const string customTimeFormat = @"yyyy.MM.dd.HH.mm.ssZzz"; |
18 | - public string fileName; | |
19 | - public string chunkPath; | |
20 | - public ColumnsMetadata cols; | |
21 | - //TODO: Refactor - so Edges are set at construction time, as ColumnsMetadata is async updating in real time! | |
22 | - public int NorthEdge => cols.North_mostChunk; | |
23 | - public int WestEdge => cols.West_mostChunk; | |
24 | - public int Width => (cols.East_mostChunk - WestEdge + 1); | |
25 | - public int Height => (cols.South_mostChunk - NorthEdge + 1); | |
26 | - | |
17 | + public readonly int chunkSize; | |
18 | + public readonly int worldSeed; | |
19 | + public readonly string fileName; | |
20 | + public readonly string chunkPath; | |
21 | + public readonly int NorthEdge; | |
22 | + public readonly int WestEdge; | |
23 | + public readonly int Width; | |
24 | + public readonly int Height; | |
25 | + | |
26 | + public ColumnsMetadata colMetadata; | |
27 | + public bool Imaging { get; private set; } | |
28 | + public bool Finished { get; private set; } | |
29 | + public Stopwatch Timer { get; private set;} | |
27 | 30 | |
28 | - public Snapshotter(string path, ColumnsMetadata cols, int chunkSize, int worldSeed) | |
29 | - { | |
30 | - this.fileName = Path.Combine(path, $"snapshot_{worldSeed}_{DateTime.Now.ToString(customTimeFormat)}.png"); | |
31 | - this.chunkPath = Path.Combine(path, AutomapSystem._chunkPath); | |
32 | - this.cols = cols; | |
33 | - this.chunkSize = chunkSize; | |
31 | + /// <summary> | |
32 | + /// Prepares class to take "snapshot" (single use!) | |
33 | + /// </summary> | |
34 | + /// <param name="path">path to the map dir</param> | |
35 | + /// <param name="cols">Input metadata</param> | |
36 | + /// <param name="chunkSizeP">size in blocks of std. chunk</param> | |
37 | + /// <param name="worldSeedP">World Seed #</param> | |
38 | + public Snapshotter(string path, ColumnsMetadata cols, int chunkSizeP, int worldSeedP) | |
39 | + { | |
40 | + colMetadata = cols; | |
41 | + chunkSize = chunkSizeP; | |
42 | + worldSeed = worldSeedP; | |
43 | + NorthEdge = cols.North_mostChunk; | |
44 | + WestEdge = cols.West_mostChunk; | |
45 | + Width = (cols.East_mostChunk - WestEdge + 1); | |
46 | + Height = (cols.South_mostChunk - NorthEdge + 1); | |
47 | + fileName = Path.Combine(path, $"snapshot_{worldSeed}_{DateTime.Now.ToString(customTimeFormat)}.png"); | |
48 | + chunkPath = Path.Combine(path, AutomapSystem._chunkPath); | |
34 | 49 | } |
35 | 50 | |
36 | 51 | /// <summary> |
37 | 52 | /// takes a snapshot. this should be called from an extra thread. |
38 | 53 | /// </summary> |
39 | - /// <param name="path">path to the map dir</param> | |
40 | - /// <param name="chunkPath">name of the chunks dir part thing</param> | |
41 | - /// <param name="cols"></param> | |
42 | - /// <param name="chunkSize"></param> | |
43 | 54 | public async void Take() |
44 | 55 | { |
45 | - var t = new Stopwatch(); | |
46 | - t.Start(); | |
56 | + if (Imaging || Finished) return;//Can't take annother photo...this one is started or complete | |
57 | + Imaging = true; | |
58 | + Timer = new Stopwatch(); | |
59 | + Timer.Start(); | |
47 | 60 | |
48 | 61 | Debug.WriteLine("snapshot started"); |
49 | 62 |
@@ -73,7 +86,7 @@ namespace Automap | ||
73 | 86 | |
74 | 87 | |
75 | 88 | var orderedList = |
76 | - from ch in cols | |
89 | + from ch in colMetadata | |
77 | 90 | group ch by ch.Location.Y into g |
78 | 91 | orderby g.Key |
79 | 92 | select g; |
@@ -111,12 +124,15 @@ namespace Automap | ||
111 | 124 | try |
112 | 125 | { |
113 | 126 | snapWriter.End(); |
127 | + Timer.Stop( ); | |
128 | + Imaging = false; | |
129 | + Finished = true; | |
114 | 130 | } |
115 | 131 | catch (Exception) |
116 | 132 | { |
117 | 133 | Debug.WriteLine("Snapshot exception!"); |
118 | 134 | } |
119 | - Debug.WriteLine($"snapshot finished in {t.ElapsedMilliseconds}"); | |
135 | + Debug.WriteLine($"snapshot finished in {Timer.ElapsedMilliseconds}"); | |
120 | 136 | } |
121 | 137 | |
122 | 138 | private async Task<Dictionary<int, byte[][]>> ReadAllInGroup(IGrouping<int, ColumnMeta> group) |
@@ -4,10 +4,10 @@ | ||
4 | 4 | "description" : "Automap; Generates a static HTML5 map dynamically, with P.O.I. Tracking & more.", |
5 | 5 | "authors": ["Melchior","VeryGoodDog"], |
6 | 6 | "contributors":["VeryGoodDog"], |
7 | - "version": "0.1.7", | |
7 | + "version": "0.1.8", | |
8 | 8 | "side":"Client", |
9 | 9 | "dependencies": { |
10 | - "game": "1.14.10" | |
10 | + "game": "1.16.0" | |
11 | 11 | }, |
12 | 12 | "website": "http://automap.osdn.io/" |
13 | 13 | } |
\ No newline at end of file |