Skip to content

Commit b5e8bf4

Browse files
committed
Fix update-region expanding with force-updates & chunks with broken tile-entity data can now be loaded
1 parent 7afcbee commit b5e8bf4

File tree

10 files changed

+112
-8
lines changed

10 files changed

+112
-8
lines changed

BlueMapCommon/src/main/java/de/bluecolored/bluemap/common/api/WebAppImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public class WebAppImpl implements WebApp {
4444
private final BlueMapService blueMapService;
4545
private final @Nullable Plugin plugin;
4646

47-
private final Timer timer = new Timer();
47+
private final Timer timer = new Timer("BlueMap-WebbAppImpl-Timer", true);
4848
private @Nullable TimerTask scheduledWebAppSettingsUpdate;
4949

5050
public WebAppImpl(BlueMapService blueMapService, @Nullable Plugin plugin) {

BlueMapCommon/src/main/java/de/bluecolored/bluemap/common/rendermanager/MapUpdateTask.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,10 @@
2828
import de.bluecolored.bluemap.core.logger.Logger;
2929
import de.bluecolored.bluemap.core.map.BmMap;
3030
import de.bluecolored.bluemap.core.map.renderstate.MapTileState;
31+
import de.bluecolored.bluemap.core.map.renderstate.TileInfoRegion;
3132
import de.bluecolored.bluemap.core.map.renderstate.TileState;
3233
import de.bluecolored.bluemap.core.storage.GridStorage;
34+
import de.bluecolored.bluemap.core.storage.compression.CompressedInputStream;
3335
import de.bluecolored.bluemap.core.util.Grid;
3436
import de.bluecolored.bluemap.core.world.World;
3537

@@ -134,6 +136,21 @@ private static Collection<Vector2i> getRegions(BmMap map, Vector2i center, int r
134136
Grid cellGrid = MapTileState.GRID.multiply(tileGrid);
135137
try (Stream<GridStorage.Cell> stream = map.getStorage().tileState().stream()) {
136138
stream
139+
.filter(c -> { // filter out files that are fully UNKNOWN
140+
try (CompressedInputStream in = c.read()) {
141+
if (in == null) return false;
142+
TileState[] states = TileInfoRegion.loadPalette(in.decompress());
143+
for (TileState state : states) {
144+
if (
145+
state != TileState.UNKNOWN &&
146+
state != TileState.NOT_GENERATED
147+
) return true;
148+
}
149+
return false;
150+
} catch (IOException ignore) {
151+
return true;
152+
}
153+
})
137154
.map(c -> new Vector2i(c.getX(), c.getZ()))
138155
.flatMap(v -> cellGrid.getIntersecting(v, regionGrid).stream())
139156
.filter(regionRadiusFilter)

BlueMapCore/src/main/java/de/bluecolored/bluemap/core/map/renderstate/TileInfoRegion.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,18 @@
2424
*/
2525
package de.bluecolored.bluemap.core.map.renderstate;
2626

27+
import com.google.gson.reflect.TypeToken;
28+
import de.bluecolored.bluemap.core.util.Key;
29+
import de.bluecolored.bluemap.core.util.RegistryAdapter;
30+
import de.bluecolored.bluenbt.BlueNBT;
2731
import de.bluecolored.bluenbt.NBTName;
2832
import de.bluecolored.bluenbt.NBTPostDeserialize;
2933
import lombok.AllArgsConstructor;
3034
import lombok.Data;
3135
import lombok.Getter;
3236

37+
import java.io.IOException;
38+
import java.io.InputStream;
3339
import java.util.Arrays;
3440
import java.util.Map;
3541
import java.util.Objects;
@@ -122,4 +128,29 @@ public static TileInfoRegion create() {
122128
return region;
123129
}
124130

131+
/**
132+
* Only loads the palette-part from a TileState-file
133+
*/
134+
public static TileState[] loadPalette(InputStream in) throws IOException {
135+
return PaletteOnly.BLUE_NBT.read(in, PaletteOnly.class).tileStates.palette;
136+
}
137+
138+
@Getter
139+
private static class PaletteOnly {
140+
141+
private final static BlueNBT BLUE_NBT = new BlueNBT();
142+
static {
143+
BLUE_NBT.register(TypeToken.get(TileState.class), new RegistryAdapter<>(TileState.REGISTRY, Key.BLUEMAP_NAMESPACE, TileState.UNKNOWN));
144+
}
145+
146+
@NBTName("tile-states")
147+
private TileStates tileStates;
148+
149+
@Getter
150+
private static class TileStates {
151+
private TileState[] palette;
152+
}
153+
154+
}
155+
125156
}

BlueMapCore/src/main/java/de/bluecolored/bluemap/core/world/mca/MCAWorld.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ public void accept(int chunkX, int chunkZ, Chunk chunk) {
203203
}
204204
});
205205
} catch (IOException ex) {
206-
Logger.global.logDebug("Unexpected exception trying to load preload region (x:" + x + ", z:" + z + "):" + ex);
206+
Logger.global.logDebug("Unexpected exception trying to load preload region (x:" + x + ", z:" + z + "): " + ex);
207207
}
208208
}
209209

@@ -257,7 +257,7 @@ private Chunk loadChunk(int x, int z) {
257257
}
258258
}
259259

260-
Logger.global.logDebug("Unexpected exception trying to load chunk (x:" + x + ", z:" + z + "):" + loadException);
260+
Logger.global.logDebug("Unexpected exception trying to load chunk (x:" + x + ", z:" + z + "): " + loadException);
261261
return Chunk.ERRORED_CHUNK;
262262
}
263263

BlueMapCore/src/main/java/de/bluecolored/bluemap/core/world/mca/chunk/ChunkLoader.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,12 @@ private static class ChunkVersionLoader<D extends MCAChunk.Data> {
9595
private final int dataVersion;
9696

9797
public MCAChunk load(MCAWorld world, InputStream in) throws IOException {
98-
D data = MCAUtil.BLUENBT.read(in, dataType);
99-
return mightSupport(data.getDataVersion()) ? constructor.apply(world, data) : new MCAChunk(world, data) {};
98+
try {
99+
D data = MCAUtil.BLUENBT.read(in, dataType);
100+
return mightSupport(data.getDataVersion()) ? constructor.apply(world, data) : new MCAChunk(world, data) {};
101+
} catch (Exception e) {
102+
throw new IOException("Failed to parse chunk-data: " + e, e);
103+
}
100104
}
101105

102106
public boolean mightSupport(int dataVersion) {

BlueMapCore/src/main/java/de/bluecolored/bluemap/core/world/mca/chunk/Chunk_1_13.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
import de.bluecolored.bluemap.core.world.block.entity.BlockEntity;
3434
import de.bluecolored.bluemap.core.world.mca.MCAUtil;
3535
import de.bluecolored.bluemap.core.world.mca.MCAWorld;
36+
import de.bluecolored.bluemap.core.world.mca.data.LenientBlockEntityArrayDeserializer;
37+
import de.bluecolored.bluenbt.NBTDeserializer;
3638
import de.bluecolored.bluenbt.NBTName;
3739
import lombok.Getter;
3840
import org.jetbrains.annotations.Nullable;
@@ -295,7 +297,10 @@ public static class Level {
295297
private HeightmapsData heightmaps = new HeightmapsData();
296298
private SectionData @Nullable [] sections = null;
297299
private int[] biomes = EMPTY_INT_ARRAY;
298-
@NBTName("TileEntities") private @Nullable BlockEntity [] blockEntities = EMPTY_BLOCK_ENTITIES_ARRAY;
300+
301+
@NBTName("TileEntities")
302+
@NBTDeserializer(LenientBlockEntityArrayDeserializer.class)
303+
private @Nullable BlockEntity [] blockEntities = EMPTY_BLOCK_ENTITIES_ARRAY;
299304
}
300305

301306
@Getter

BlueMapCore/src/main/java/de/bluecolored/bluemap/core/world/mca/chunk/Chunk_1_16.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
import de.bluecolored.bluemap.core.world.mca.MCAUtil;
3535
import de.bluecolored.bluemap.core.world.mca.MCAWorld;
3636
import de.bluecolored.bluemap.core.world.mca.PackedIntArrayAccess;
37+
import de.bluecolored.bluemap.core.world.mca.data.LenientBlockEntityArrayDeserializer;
38+
import de.bluecolored.bluenbt.NBTDeserializer;
3739
import de.bluecolored.bluenbt.NBTName;
3840
import lombok.Getter;
3941
import org.jetbrains.annotations.Nullable;
@@ -282,7 +284,10 @@ public static class Level {
282284
private HeightmapsData heightmaps = new HeightmapsData();
283285
private SectionData @Nullable [] sections = null;
284286
private int[] biomes = EMPTY_INT_ARRAY;
285-
@NBTName("TileEntities") private @Nullable BlockEntity [] blockEntities = EMPTY_BLOCK_ENTITIES_ARRAY;
287+
288+
@NBTName("TileEntities")
289+
@NBTDeserializer(LenientBlockEntityArrayDeserializer.class)
290+
private @Nullable BlockEntity [] blockEntities = EMPTY_BLOCK_ENTITIES_ARRAY;
286291
}
287292

288293
@Getter

BlueMapCore/src/main/java/de/bluecolored/bluemap/core/world/mca/chunk/Chunk_1_18.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
import de.bluecolored.bluemap.core.world.mca.MCAUtil;
3535
import de.bluecolored.bluemap.core.world.mca.MCAWorld;
3636
import de.bluecolored.bluemap.core.world.mca.PackedIntArrayAccess;
37+
import de.bluecolored.bluemap.core.world.mca.data.LenientBlockEntityArrayDeserializer;
38+
import de.bluecolored.bluenbt.NBTDeserializer;
3739
import de.bluecolored.bluenbt.NBTName;
3840
import lombok.Getter;
3941
import org.jetbrains.annotations.Nullable;
@@ -290,7 +292,10 @@ public static class Data extends MCAChunk.Data {
290292
private long inhabitedTime = 0;
291293
private HeightmapsData heightmaps = new HeightmapsData();
292294
private SectionData @Nullable [] sections = null;
293-
@NBTName("block_entities") private @Nullable BlockEntity [] blockEntities = EMPTY_BLOCK_ENTITIES_ARRAY;
295+
296+
@NBTName("block_entities")
297+
@NBTDeserializer(LenientBlockEntityArrayDeserializer.class)
298+
private @Nullable BlockEntity [] blockEntities = EMPTY_BLOCK_ENTITIES_ARRAY;
294299
}
295300

296301
@Getter
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package de.bluecolored.bluemap.core.world.mca.data;
2+
3+
import com.google.gson.reflect.TypeToken;
4+
import de.bluecolored.bluemap.core.world.block.entity.BlockEntity;
5+
import de.bluecolored.bluenbt.BlueNBT;
6+
import de.bluecolored.bluenbt.NBTReader;
7+
import de.bluecolored.bluenbt.TagType;
8+
import de.bluecolored.bluenbt.TypeDeserializer;
9+
10+
import java.io.IOException;
11+
12+
/**
13+
* TypeSerializer that returns a default value instead of failing when the serialized field is of the wrong type
14+
*/
15+
public class LenientBlockEntityArrayDeserializer implements TypeDeserializer<BlockEntity[]> {
16+
17+
private static final BlockEntity[] EMPTY_BLOCK_ENTITIES_ARRAY = new BlockEntity[0];
18+
19+
private final TypeDeserializer<BlockEntity[]> delegate;
20+
21+
public LenientBlockEntityArrayDeserializer(BlueNBT blueNBT) {
22+
delegate = blueNBT.getTypeDeserializer(new TypeToken<>(){});
23+
}
24+
25+
@Override
26+
public BlockEntity[] read(NBTReader reader) throws IOException {
27+
if (reader.peek() != TagType.LIST) {
28+
reader.skip();
29+
return EMPTY_BLOCK_ENTITIES_ARRAY;
30+
}
31+
return delegate.read(reader);
32+
}
33+
34+
}

implementations/cli/src/main/java/de/bluecolored/bluemap/cli/BlueMapCLI.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import de.bluecolored.bluemap.common.config.ConfigurationException;
3434
import de.bluecolored.bluemap.common.config.CoreConfig;
3535
import de.bluecolored.bluemap.common.config.WebserverConfig;
36+
import de.bluecolored.bluemap.common.debug.StateDumper;
3637
import de.bluecolored.bluemap.common.plugin.MapUpdateService;
3738
import de.bluecolored.bluemap.common.rendermanager.MapUpdateTask;
3839
import de.bluecolored.bluemap.common.rendermanager.RenderManager;
@@ -209,6 +210,8 @@ public void run() {
209210
Runtime.getRuntime().removeShutdownHook(shutdownHook);
210211
shutdown.run();
211212
}
213+
214+
StateDumper.global().dump(Path.of("teststate.json"));
212215
}
213216

214217
public void startWebserver(BlueMapService blueMap, boolean verbose) throws IOException, ConfigurationException, InterruptedException {

0 commit comments

Comments
 (0)