Skip to content

Commit 8bac85c

Browse files
committed
2 parents c5c791b + f467220 commit 8bac85c

File tree

2 files changed

+61
-31
lines changed
  • BlueMapCommon/src/main/java/de/bluecolored/bluemap/common/plugin
  • BlueMapCore/src/main/java/de/bluecolored/bluemap/core/mca/region

2 files changed

+61
-31
lines changed

BlueMapCommon/src/main/java/de/bluecolored/bluemap/common/plugin/Plugin.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -220,13 +220,6 @@ private void load(@Nullable ResourcePack preloadedResourcePack) throws IOExcepti
220220
}
221221
});
222222

223-
//start render-manager
224-
if (pluginState.isRenderThreadsEnabled()) {
225-
checkPausedByPlayerCount(); // <- this also starts the render-manager if it should start
226-
} else {
227-
Logger.global.logInfo("Render-Threads are STOPPED! Use the command 'bluemap start' to start them.");
228-
}
229-
230223
//update webapp and settings
231224
if (webappConfig.isEnabled())
232225
blueMap.createOrUpdateWebApp(false);
@@ -325,6 +318,13 @@ public void run() {
325318
if (webappConfig.isEnabled())
326319
this.getBlueMap().getWebFilesManager().saveSettings();
327320

321+
//start render-manager
322+
if (pluginState.isRenderThreadsEnabled()) {
323+
checkPausedByPlayerCount(); // <- this also starts the render-manager if it should start
324+
} else {
325+
Logger.global.logInfo("Render-Threads are STOPPED! Use the command 'bluemap start' to start them.");
326+
}
327+
328328
//done
329329
loaded = true;
330330
}

BlueMapCore/src/main/java/de/bluecolored/bluemap/core/mca/region/LinearRegion.java

Lines changed: 54 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,14 @@
3838
import java.io.*;
3939
import java.nio.file.Files;
4040
import java.nio.file.Path;
41-
import java.util.ArrayList;
42-
import java.util.Collection;
43-
import java.util.Collections;
44-
import java.util.List;
41+
import java.util.*;
4542

4643
public class LinearRegion implements Region {
4744

4845
public static final String FILE_SUFFIX = ".linear";
4946

47+
private static final List<Byte> SUPPORTED_VERSIONS = Arrays.asList((byte) 1, (byte) 2);
5048
private static final long SUPERBLOCK = -4323716122432332390L;
51-
private static final byte VERSION = 1;
5249
private static final int HEADER_SIZE = 32;
5350
private static final int FOOTER_SIZE = 8;
5451

@@ -80,26 +77,28 @@ public Chunk loadChunk(int chunkX, int chunkZ, boolean ignoreMissingLightData) t
8077

8178
long superBlock = rawDataStream.readLong();
8279
if (superBlock != SUPERBLOCK)
83-
throw new RuntimeException("Superblock invalid: " + superBlock + " file " + regionFile);
80+
throw new RuntimeException("Invalid superblock: " + superBlock + " file " + regionFile);
8481

8582
byte version = rawDataStream.readByte();
86-
if (version != VERSION)
87-
throw new RuntimeException("Version invalid: " + version + " file " + regionFile);
83+
if (!SUPPORTED_VERSIONS.contains(version))
84+
throw new RuntimeException("Invalid version: " + version + " file " + regionFile);
8885

89-
rawDataStream.skipBytes(11); // newestTimestamp + compression level + chunk count
86+
// Skip newestTimestamp (Long) + Compression level (Byte) + Chunk count (Short): Unused.
87+
rawDataStream.skipBytes(11);
9088

9189
int dataCount = rawDataStream.readInt();
9290
if (fileLength != HEADER_SIZE + dataCount + FOOTER_SIZE)
93-
throw new RuntimeException("File length invalid " + this.regionFile + " " + fileLength + " " + (HEADER_SIZE + dataCount + FOOTER_SIZE));
91+
throw new RuntimeException("Invalid file length: " + this.regionFile + " " + fileLength + " " + (HEADER_SIZE + dataCount + FOOTER_SIZE));
9492

95-
rawDataStream.skipBytes(8); // Data Hash
93+
// Skip data hash (Long): Unused.
94+
rawDataStream.skipBytes(8);
9695

9796
byte[] rawCompressed = new byte[dataCount];
9897
rawDataStream.readFully(rawCompressed, 0, dataCount);
9998

10099
superBlock = rawDataStream.readLong();
101100
if (superBlock != SUPERBLOCK)
102-
throw new RuntimeException("Footer superblock invalid " + this.regionFile);
101+
throw new RuntimeException("Invalid footer superblock: " + this.regionFile);
103102

104103
try (DataInputStream dis = new DataInputStream(new ZstdInputStream(new ByteArrayInputStream(rawCompressed)))) {
105104
int x = chunkX - (regionPos.getX() << 5);
@@ -108,8 +107,8 @@ public Chunk loadChunk(int chunkX, int chunkZ, boolean ignoreMissingLightData) t
108107
int skip = 0;
109108

110109
for (int i = 0; i < pos; i++) {
111-
skip += dis.readInt(); // size of the chunk (bytes) to skip
112-
dis.skipBytes(4); // skip 0 (will be timestamps)
110+
skip += dis.readInt(); // Size of the chunk (bytes) to skip
111+
dis.skipBytes(4); // Skip timestamps
113112
}
114113

115114
int size = dis.readInt();
@@ -136,8 +135,9 @@ public Chunk loadChunk(int chunkX, int chunkZ, boolean ignoreMissingLightData) t
136135
public Collection<Vector2i> listChunks(long modifiedSince) {
137136
if (Files.notExists(regionFile)) return Collections.emptyList();
138137

138+
long fileLength;
139139
try {
140-
long fileLength = Files.size(regionFile);
140+
fileLength = Files.size(regionFile);
141141
if (fileLength == 0) return Collections.emptyList();
142142
} catch (IOException ex) {
143143
Logger.global.logWarning("Failed to read file-size for file: " + regionFile);
@@ -149,21 +149,51 @@ public Collection<Vector2i> listChunks(long modifiedSince) {
149149
DataInputStream rawDataStream = new DataInputStream(inputStream)) {
150150

151151
long superBlock = rawDataStream.readLong();
152-
if (superBlock != SUPERBLOCK) throw new RuntimeException("Superblock invalid: " + superBlock + " file " + regionFile);
152+
if (superBlock != SUPERBLOCK)
153+
throw new RuntimeException("Invalid superblock: " + superBlock + " file " + regionFile);
153154

154155
byte version = rawDataStream.readByte();
155-
if (version != VERSION) throw new RuntimeException("Version invalid: " + version + " file " + regionFile);
156+
if (!SUPPORTED_VERSIONS.contains(version))
157+
throw new RuntimeException("Invalid version: " + version + " file " + regionFile);
156158

157-
long newestTimestamp = rawDataStream.readLong();
159+
int date = (int) (modifiedSince / 1000);
158160

159161
// If whole region is the same - skip.
160-
if (newestTimestamp < modifiedSince / 1000) return Collections.emptyList();
162+
long newestTimestamp = rawDataStream.readLong();
163+
if (newestTimestamp < date) return Collections.emptyList();
164+
165+
// Linear v1 files store whole region timestamp, not chunk timestamp. We need to render the whole region file.
166+
if (version == 1) {
167+
for(int i = 0 ; i < 1024; i++)
168+
chunks.add(new Vector2i((regionPos.getX() << 5) + (i & 31), (regionPos.getY() << 5) + (i >> 5)));
169+
return chunks;
170+
}
171+
// Linear v2: Chunk timestamps are here!
172+
// Skip Compression level (Byte) + Chunk count (Short): Unused.
173+
rawDataStream.skipBytes(3);
174+
175+
int dataCount = rawDataStream.readInt();
176+
if (fileLength != HEADER_SIZE + dataCount + FOOTER_SIZE)
177+
throw new RuntimeException("Invalid file length: " + this.regionFile + " " + fileLength + " " + (HEADER_SIZE + dataCount + FOOTER_SIZE));
178+
179+
// Skip data hash (Long): Unused.
180+
rawDataStream.skipBytes(8);
161181

162-
// Linear files store whole region timestamp, not chunk timestamp. We need to render the while region file.
163-
// TODO: Add per-chunk timestamps when .linear add support for per-chunk timestamps (soon)
164-
for(int i = 0 ; i < 1024; i++)
165-
chunks.add(new Vector2i((regionPos.getX() << 5) + (i & 31), (regionPos.getY() << 5) + (i >> 5)));
166-
return chunks;
182+
byte[] rawCompressed = new byte[dataCount];
183+
rawDataStream.readFully(rawCompressed, 0, dataCount);
184+
185+
superBlock = rawDataStream.readLong();
186+
if (superBlock != SUPERBLOCK)
187+
throw new RuntimeException("Invalid footer SuperBlock: " + this.regionFile);
188+
189+
try (DataInputStream dis = new DataInputStream(new ZstdInputStream(new ByteArrayInputStream(rawCompressed)))) {
190+
for (int i = 0; i < 1024; i++) {
191+
dis.skipBytes(4); // Skip size of the chunk
192+
int timestamp = dis.readInt();
193+
if (timestamp >= date) // Timestamps
194+
chunks.add(new Vector2i((regionPos.getX() << 5) + (i & 31), (regionPos.getY() << 5) + (i >> 5)));
195+
}
196+
}
167197
} catch (RuntimeException | IOException ex) {
168198
Logger.global.logWarning("Failed to read .linear file: " + regionFile + " (" + ex + ")");
169199
}

0 commit comments

Comments
 (0)