diff --git a/DynmapCore/src/main/java/org/dynmap/common/chunk/GenericMapChunkCache.java b/DynmapCore/src/main/java/org/dynmap/common/chunk/GenericMapChunkCache.java
index 2cfc7ce4..a43c9198 100644
--- a/DynmapCore/src/main/java/org/dynmap/common/chunk/GenericMapChunkCache.java
+++ b/DynmapCore/src/main/java/org/dynmap/common/chunk/GenericMapChunkCache.java
@@ -766,7 +766,7 @@ public abstract class GenericMapChunkCache extends MapChunkCache {
}
/**
- * Read NBT data from loaded chunks - do not needs to be called from server/world
+ * Read NBT data from loaded chunks - do not needs to be called from server/world
* Will throw {@link IllegalStateException} if not supporting
*/
public void getLoadedChunksAsync() {
@@ -836,7 +836,9 @@ public abstract class GenericMapChunkCache extends MapChunkCache {
}
/**
- * Prepare the chunks async
+ * Loads all chunks in the world asynchronously.
+ *
+ * If it is not supported, it will throw {@link IllegalStateException}
*/
public void loadChunksAsync() {
getLoadedChunksAsync();
@@ -923,6 +925,12 @@ public abstract class GenericMapChunkCache extends MapChunkCache {
return cnt;
}
+ /**
+ * It loads chunks from the cache or from the world, and if the chunk is not visible, it fills it with stone, ocean or
+ * empty chunk
+ *
+ * if it's not supported, will throw {@link IllegalStateException}
+ */
public void readChunksAsync() {
class SimplePair { //pair of the chunk and the data which is readed async
private final Supplier supplier;
diff --git a/DynmapCore/src/main/java/org/dynmap/hdmap/CustomBlockModel.java b/DynmapCore/src/main/java/org/dynmap/hdmap/CustomBlockModel.java
index ec298d08..a89670e8 100644
--- a/DynmapCore/src/main/java/org/dynmap/hdmap/CustomBlockModel.java
+++ b/DynmapCore/src/main/java/org/dynmap/hdmap/CustomBlockModel.java
@@ -16,7 +16,7 @@ public class CustomBlockModel extends HDBlockModel {
super(bstate, databits, blockset);
try {
Class> cls = Class.forName(classname); /* Get class */
- render = (CustomRenderer) cls.newInstance();
+ render = (CustomRenderer) cls.getDeclaredConstructor().newInstance();
if(render.initializeRenderer(HDBlockModels.pdf, bstate.blockName, databits, classparm) == false) {
Log.severe("Error loading custom renderer - " + classname);
render = null;
diff --git a/DynmapCore/src/main/java/org/dynmap/hdmap/TexturePack.java b/DynmapCore/src/main/java/org/dynmap/hdmap/TexturePack.java
index dc59fa18..c81cc5c8 100644
--- a/DynmapCore/src/main/java/org/dynmap/hdmap/TexturePack.java
+++ b/DynmapCore/src/main/java/org/dynmap/hdmap/TexturePack.java
@@ -2097,7 +2097,7 @@ public class TexturePack {
else if(av[0].equals("custColorMult")) {
try {
Class> cls = Class.forName(av[1]);
- custColorMult = (CustomColorMultiplier)cls.newInstance();
+ custColorMult = (CustomColorMultiplier)cls.getDeclaredConstructor().newInstance();
} catch (Exception x) {
Log.severe("Error loading custom color multiplier - " + av[1] + ": " + x.getMessage());
}
@@ -2263,7 +2263,7 @@ public class TexturePack {
else if(av[0].equals("custColorMult")) {
try {
Class> cls = Class.forName(av[1]);
- custColorMult = (CustomColorMultiplier)cls.newInstance();
+ custColorMult = (CustomColorMultiplier)cls.getDeclaredConstructor().newInstance();
} catch (Exception x) {
Log.severe("Error loading custom color multiplier - " + av[1] + ": " + x.getMessage());
}
diff --git a/DynmapCore/src/main/resources/extracted/web/standalone/MySQL_tiles.php b/DynmapCore/src/main/resources/extracted/web/standalone/MySQL_tiles.php
index 17dc4f93..51699bc1 100644
--- a/DynmapCore/src/main/resources/extracted/web/standalone/MySQL_tiles.php
+++ b/DynmapCore/src/main/resources/extracted/web/standalone/MySQL_tiles.php
@@ -94,7 +94,7 @@ if ($stmt->fetch()) {
header('Content-Type: image/jpeg');
}
header('ETag: \'' . $thash . '\'');
- header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $tlast / 1000) . ' GMT');
+ header('Last-Modified: ' . gmdate('D, d M Y H:i:s', (int) ($tlast / 1000)) . ' GMT');
if (is_null($tnewimage)) {
echo $timage;
} else {
diff --git a/DynmapCore/src/main/resources/extracted/web/standalone/PostgreSQL_tiles.php b/DynmapCore/src/main/resources/extracted/web/standalone/PostgreSQL_tiles.php
index 5afd0338..b95d00cd 100644
--- a/DynmapCore/src/main/resources/extracted/web/standalone/PostgreSQL_tiles.php
+++ b/DynmapCore/src/main/resources/extracted/web/standalone/PostgreSQL_tiles.php
@@ -99,7 +99,7 @@ if ($res && $timage) {
header('Content-Type: image/jpeg');
}
header('ETag: \'' . $thash . '\'');
- header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $tlast / 1000) . ' GMT');
+ header('Last-Modified: ' . gmdate('D, d M Y H:i:s', (int) ($tlast / 1000)) . ' GMT');
echo stream_get_contents($timage);
} else {
header('Location: ../images/blank.png');
diff --git a/DynmapCore/src/main/resources/texture_1.txt b/DynmapCore/src/main/resources/texture_1.txt
index 42cde168..7e092c41 100644
--- a/DynmapCore/src/main/resources/texture_1.txt
+++ b/DynmapCore/src/main/resources/texture_1.txt
@@ -3431,7 +3431,7 @@ block:id=%melon_stem,patch0=0:melon_stem,blockcolor=foliagebiome,transparency=TR
[1.19-]block:id=%mangrove_sign,patch0=0,patch1=1,patch2=2,patch3=3,patch4=4,patch5=5,patch6=6,patch7=7,patch8=8,patch9=9,transparency=TRANSPARENT,txtid=mangrove_sign
[1.19-]block:id=%mangrove_wall_sign,patch0=0,patch1=1,patch2=2,patch3=3,patch4=4,patch5=5,transparency=TRANSPARENT,txtid=mangrove_sign
[1.19-]block:id=%packed_mud,patch0=0:packed_mud,patch1=0:packed_mud,patch2=0:packed_mud,patch3=0:packed_mud,patch4=0:packed_mud,patch5=0:packed_mud,stdrot=true
-[1.19-]block:id=%mud_bricks,patch0=0:mud_bricks,stdrot=true
+[1.19-]block:id=%mud_bricks,patch0=0:mud_bricks,patch1=0:mud_bricks,patch2=0:mud_bricks,patch3=0:mud_bricks,patch4=0:mud_bricks,patch5=0:mud_bricks,stdrot=true
[1.19-]block:id=%mud_brick_stairs,state=facing:north/half:top/shape:straight,patch0=0:mud_bricks,transparency=SEMITRANSPARENT,stdrot=true
[1.19-]block:id=%mud_brick_stairs,state=facing:north/half:top/shape:inner_left,patch0=0:mud_bricks,transparency=SEMITRANSPARENT,stdrot=true
[1.19-]block:id=%mud_brick_stairs,state=facing:north/half:top/shape:inner_right,patch0=0:mud_bricks,transparency=SEMITRANSPARENT,stdrot=true
diff --git a/bukkit-helper-118-2/src/main/java/org/dynmap/bukkit/helper/v118_2/AsyncChunkProvider118_2.java b/bukkit-helper-118-2/src/main/java/org/dynmap/bukkit/helper/v118_2/AsyncChunkProvider118_2.java
index 9c21562d..745527e6 100644
--- a/bukkit-helper-118-2/src/main/java/org/dynmap/bukkit/helper/v118_2/AsyncChunkProvider118_2.java
+++ b/bukkit-helper-118-2/src/main/java/org/dynmap/bukkit/helper/v118_2/AsyncChunkProvider118_2.java
@@ -1,31 +1,54 @@
package org.dynmap.bukkit.helper.v118_2;
import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.WorldServer;
+import net.minecraft.world.level.chunk.Chunk;
+import net.minecraft.world.level.chunk.IChunkAccess;
+import net.minecraft.world.level.chunk.storage.ChunkRegionLoader;
+import org.bukkit.Bukkit;
+import org.bukkit.craftbukkit.v1_18_R2.CraftServer;
+import org.bukkit.craftbukkit.v1_18_R2.CraftWorld;
+import org.dynmap.MapManager;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.function.Predicate;
+import java.util.function.Supplier;
/**
* The provider used to work with paper libs
* Because paper libs need java 17 we can't interact with them directly
*/
+@SuppressWarnings({"JavaReflectionMemberAccess"}) //java don't know about paper
public class AsyncChunkProvider118_2 {
private final Thread ioThread;
private final Method getChunk;
private final Predicate ifFailed;
+ private final Method getAsyncSaveData;
+ private final Method save;
+ private int currTick = MinecraftServer.currentTick;
+ private int currChunks = 0;
+
AsyncChunkProvider118_2 () {
try {
Predicate ifFailed1 = null;
- Method getChunk1 = null;
+ Method getChunk1 = null, getAsyncSaveData1 = null, save1 = null;
Thread ioThread1 = null;
try {
Class> threadClass = Class.forName("com.destroystokyo.paper.io.PaperFileIOThread");
+ Class> asyncChunkData = Arrays.stream(ChunkRegionLoader.class.getClasses())
+ .filter(c -> c.getSimpleName().equals("AsyncSaveData"))
+ .findFirst()
+ .orElseThrow(RuntimeException::new);
+ getAsyncSaveData1 = ChunkRegionLoader.class.getMethod("getAsyncSaveData", WorldServer.class, IChunkAccess.class);
+ save1 = ChunkRegionLoader.class.getMethod("saveChunk", WorldServer.class, IChunkAccess.class, asyncChunkData);
Class>[] classes = threadClass.getClasses();
Class> holder = Arrays.stream(classes).filter(aClass -> aClass.getSimpleName().equals("Holder")).findAny().orElseThrow(RuntimeException::new);
ioThread1 = (Thread) holder.getField("INSTANCE").get(null);
@@ -35,6 +58,8 @@ public class AsyncChunkProvider118_2 {
} catch (ClassNotFoundException | NoSuchFieldException | IllegalAccessException | NoSuchMethodException e) {
e.printStackTrace();
}
+ getAsyncSaveData = Objects.requireNonNull(getAsyncSaveData1);
+ save = Objects.requireNonNull(save1);
ifFailed = Objects.requireNonNull(ifFailed1);
getChunk = Objects.requireNonNull(getChunk1);
ioThread = Objects.requireNonNull(ioThread1);
@@ -57,4 +82,38 @@ public class AsyncChunkProvider118_2 {
return null;
});
}
+
+ public synchronized Supplier getLoadedChunk(CraftWorld world, int x, int z) {
+ if (!world.isChunkLoaded(x, z)) return () -> null;
+ Chunk c = world.getHandle().getChunkIfLoaded(x, z); //already safe async on vanilla
+ if ((c == null) || !c.o) return () -> null; // c.loaded
+ if (currTick != MinecraftServer.currentTick) {
+ currTick = MinecraftServer.currentTick;
+ currChunks = 0;
+ }
+ //prepare data synchronously
+ CompletableFuture> future = CompletableFuture.supplyAsync(() -> {
+ try {
+ return getAsyncSaveData.invoke(null, world.getHandle(), c);
+ } catch (IllegalAccessException | InvocationTargetException e) {
+ throw new RuntimeException(e);
+ }
+ }, ((CraftServer) Bukkit.getServer()).getServer());
+ //we shouldn't stress main thread
+ if (++currChunks > MapManager.mapman.getMaxChunkLoadsPerTick()) {
+ try {
+ Thread.sleep(25); //hold the lock so other threads also won't stress main thread
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ //save data asynchronously
+ return () -> {
+ try {
+ return (NBTTagCompound) save.invoke(null, world.getHandle(), c, future.get());
+ } catch (ReflectiveOperationException | ExecutionException | InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ };
+ }
}
diff --git a/bukkit-helper-118-2/src/main/java/org/dynmap/bukkit/helper/v118_2/MapChunkCache118_2.java b/bukkit-helper-118-2/src/main/java/org/dynmap/bukkit/helper/v118_2/MapChunkCache118_2.java
index 3971de10..c96b6670 100644
--- a/bukkit-helper-118-2/src/main/java/org/dynmap/bukkit/helper/v118_2/MapChunkCache118_2.java
+++ b/bukkit-helper-118-2/src/main/java/org/dynmap/bukkit/helper/v118_2/MapChunkCache118_2.java
@@ -1,10 +1,12 @@
package org.dynmap.bukkit.helper.v118_2;
+import net.minecraft.server.MinecraftServer;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_18_R2.CraftServer;
import org.bukkit.craftbukkit.v1_18_R2.CraftWorld;
import org.dynmap.DynmapChunk;
+import org.dynmap.MapManager;
import org.dynmap.bukkit.helper.BukkitVersionHelper;
import org.dynmap.bukkit.helper.BukkitWorld;
import org.dynmap.common.chunk.GenericChunk;
@@ -20,6 +22,7 @@ import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Supplier;
/**
@@ -37,11 +40,20 @@ public class MapChunkCache118_2 extends GenericMapChunkCache {
// Load generic chunk from existing and already loaded chunk
protected GenericChunk getLoadedChunk(DynmapChunk chunk) {
- return getLoadedChunk(chunk, false).get();
+ CraftWorld cw = (CraftWorld) w;
+ if (!cw.isChunkLoaded(chunk.x, chunk.z)) return null;
+ Chunk c = cw.getHandle().getChunkIfLoaded(chunk.x, chunk.z); //already safe async on vanilla
+ if ((c == null) || !c.o) return null; // c.loaded
+ NBTTagCompound nbt = ChunkRegionLoader.a(cw.getHandle(), c);
+ return nbt != null ? parseChunkFromNBT(new NBT.NBTCompound(nbt)) : null;
}
@Override
protected Supplier getLoadedChunkAsync(DynmapChunk ch) {
- return getLoadedChunk(ch, true);
+ Supplier nbtSupplier = provider.getLoadedChunk((CraftWorld) w, ch.x, ch.z);
+ return () -> {
+ NBTTagCompound nbt = nbtSupplier.get();
+ return nbt == null ? null : parseChunkFromNBT(new NBT.NBTCompound(nbt));
+ };
}
@Override
@@ -57,26 +69,6 @@ public class MapChunkCache118_2 extends GenericMapChunkCache {
}
}
- private Supplier getLoadedChunk(DynmapChunk chunk, boolean async) {
- CraftWorld cw = (CraftWorld) w;
- if (!cw.isChunkLoaded(chunk.x, chunk.z)) return () -> null;
- Chunk c = cw.getHandle().getChunkIfLoaded(chunk.x, chunk.z); //already safe async on vanilla
- if ((c == null) || c.o) return () -> null; // c.loaded
- if (async) { //the data of the chunk may change while we write, better to write it sync
- CompletableFuture nbt = CompletableFuture.supplyAsync(() -> ChunkRegionLoader.a(cw.getHandle(), c), ((CraftServer) Bukkit.getServer()).getServer());
- return () -> {
- NBTTagCompound compound = nbt.join();
- return compound == null ? null : parseChunkFromNBT(new NBT.NBTCompound(compound));
- };
- } else {
- NBTTagCompound nbt = ChunkRegionLoader.a(cw.getHandle(), c);
- GenericChunk genericChunk;
- if (nbt != null) genericChunk = parseChunkFromNBT(new NBT.NBTCompound(nbt));
- else genericChunk = null;
- return () -> genericChunk;
- }
-
- }
// Load generic chunk from unloaded chunk
protected GenericChunk loadChunk(DynmapChunk chunk) {
CraftWorld cw = (CraftWorld) w;
diff --git a/bukkit-helper-119/src/main/java/org/dynmap/bukkit/helper/v119/AsyncChunkProvider119.java b/bukkit-helper-119/src/main/java/org/dynmap/bukkit/helper/v119/AsyncChunkProvider119.java
index 7438575c..ac93ee97 100644
--- a/bukkit-helper-119/src/main/java/org/dynmap/bukkit/helper/v119/AsyncChunkProvider119.java
+++ b/bukkit-helper-119/src/main/java/org/dynmap/bukkit/helper/v119/AsyncChunkProvider119.java
@@ -1,31 +1,53 @@
package org.dynmap.bukkit.helper.v119;
import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.WorldServer;
+import net.minecraft.world.level.chunk.Chunk;
+import net.minecraft.world.level.chunk.IChunkAccess;
+import net.minecraft.world.level.chunk.storage.ChunkRegionLoader;
+import org.bukkit.Bukkit;
+import org.bukkit.craftbukkit.v1_19_R1.CraftServer;
+import org.bukkit.craftbukkit.v1_19_R1.CraftWorld;
+import org.dynmap.MapManager;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
import java.util.function.Consumer;
import java.util.function.Predicate;
+import java.util.function.Supplier;
/**
* The provider used to work with paper libs
* Because paper libs need java 17 we can't interact with them directly
*/
+@SuppressWarnings({"JavaReflectionMemberAccess"}) //java don't know about paper
public class AsyncChunkProvider119 {
private final Thread ioThread;
private final Method getChunk;
private final Predicate ifFailed;
- AsyncChunkProvider119 () {
+ private final Method getAsyncSaveData;
+ private final Method save;
+ private int currTick = MinecraftServer.currentTick;
+ private int currChunks = 0;
+
+ AsyncChunkProvider119() {
try {
Predicate ifFailed1 = null;
- Method getChunk1 = null;
+ Method getChunk1 = null, getAsyncSaveData1 = null, save1 = null;
Thread ioThread1 = null;
try {
Class> threadClass = Class.forName("com.destroystokyo.paper.io.PaperFileIOThread");
+ Class> asyncChunkData = Arrays.stream(ChunkRegionLoader.class.getClasses())
+ .filter(c -> c.getSimpleName().equals("AsyncSaveData"))
+ .findFirst()
+ .orElseThrow(RuntimeException::new);
+ getAsyncSaveData1 = ChunkRegionLoader.class.getMethod("getAsyncSaveData", WorldServer.class, IChunkAccess.class);
+ save1 = ChunkRegionLoader.class.getMethod("saveChunk", WorldServer.class, IChunkAccess.class, asyncChunkData);
Class>[] classes = threadClass.getClasses();
Class> holder = Arrays.stream(classes).filter(aClass -> aClass.getSimpleName().equals("Holder")).findAny().orElseThrow(RuntimeException::new);
ioThread1 = (Thread) holder.getField("INSTANCE").get(null);
@@ -35,6 +57,8 @@ public class AsyncChunkProvider119 {
} catch (ClassNotFoundException | NoSuchFieldException | IllegalAccessException | NoSuchMethodException e) {
e.printStackTrace();
}
+ getAsyncSaveData = Objects.requireNonNull(getAsyncSaveData1);
+ save = Objects.requireNonNull(save1);
ifFailed = Objects.requireNonNull(ifFailed1);
getChunk = Objects.requireNonNull(getChunk1);
ioThread = Objects.requireNonNull(ioThread1);
@@ -57,4 +81,38 @@ public class AsyncChunkProvider119 {
return null;
});
}
+
+ public synchronized Supplier getLoadedChunk(CraftWorld world, int x, int z) {
+ if (!world.isChunkLoaded(x, z)) return () -> null;
+ Chunk c = world.getHandle().getChunkIfLoaded(x, z); //already safe async on vanilla
+ if ((c == null) || !c.o) return () -> null; // c.loaded
+ if (currTick != MinecraftServer.currentTick) {
+ currTick = MinecraftServer.currentTick;
+ currChunks = 0;
+ }
+ //prepare data synchronously
+ CompletableFuture> future = CompletableFuture.supplyAsync(() -> {
+ try {
+ return getAsyncSaveData.invoke(null, world.getHandle(), c);
+ } catch (ReflectiveOperationException e) {
+ throw new RuntimeException(e);
+ }
+ }, ((CraftServer) Bukkit.getServer()).getServer());
+ //we shouldn't stress main thread
+ if (++currChunks > MapManager.mapman.getMaxChunkLoadsPerTick()) {
+ try {
+ Thread.sleep(25); //hold the lock so other threads also won't stress main thread
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ //save data asynchronously
+ return () -> {
+ try {
+ return (NBTTagCompound) save.invoke(null, world.getHandle(), c, future.get());
+ } catch (ReflectiveOperationException | ExecutionException | InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ };
+ }
}
diff --git a/bukkit-helper-119/src/main/java/org/dynmap/bukkit/helper/v119/MapChunkCache119.java b/bukkit-helper-119/src/main/java/org/dynmap/bukkit/helper/v119/MapChunkCache119.java
index 4743e94f..a94c0898 100644
--- a/bukkit-helper-119/src/main/java/org/dynmap/bukkit/helper/v119/MapChunkCache119.java
+++ b/bukkit-helper-119/src/main/java/org/dynmap/bukkit/helper/v119/MapChunkCache119.java
@@ -1,8 +1,6 @@
package org.dynmap.bukkit.helper.v119;
-import org.bukkit.Bukkit;
import org.bukkit.World;
-import org.bukkit.craftbukkit.v1_19_R1.CraftServer;
import org.bukkit.craftbukkit.v1_19_R1.CraftWorld;
import org.dynmap.DynmapChunk;
import org.dynmap.bukkit.helper.BukkitVersionHelper;
@@ -16,7 +14,6 @@ import net.minecraft.world.level.ChunkCoordIntPair;
import net.minecraft.world.level.chunk.storage.ChunkRegionLoader;
import net.minecraft.world.level.chunk.Chunk;
-import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.NoSuchElementException;
@@ -38,14 +35,24 @@ public class MapChunkCache119 extends GenericMapChunkCache {
}
// Load generic chunk from existing and already loaded chunk
- protected GenericChunk getLoadedChunk(DynmapChunk chunk) {
- return getLoadedChunk(chunk, false).get();
- }
@Override
- protected Supplier getLoadedChunkAsync(DynmapChunk ch) {
- return getLoadedChunk(ch, true);
+ protected Supplier getLoadedChunkAsync(DynmapChunk chunk) {
+ Supplier supplier = provider.getLoadedChunk((CraftWorld) w, chunk.x, chunk.z);
+ return () -> {
+ NBTTagCompound nbt = supplier.get();
+ return nbt != null ? parseChunkFromNBT(new NBT.NBTCompound(nbt)) : null;
+ };
+ }
+ protected GenericChunk getLoadedChunk(DynmapChunk chunk) {
+ CraftWorld cw = (CraftWorld) w;
+ if (!cw.isChunkLoaded(chunk.x, chunk.z)) return null;
+ Chunk c = cw.getHandle().getChunkIfLoaded(chunk.x, chunk.z);
+ if (c == null || !c.o) return null; // c.loaded
+ NBTTagCompound nbt = ChunkRegionLoader.a(cw.getHandle(), c);
+ return nbt != null ? parseChunkFromNBT(new NBT.NBTCompound(nbt)) : null;
}
+ // Load generic chunk from unloaded chunk
@Override
protected Supplier loadChunkAsync(DynmapChunk chunk){
try {
@@ -59,27 +66,6 @@ public class MapChunkCache119 extends GenericMapChunkCache {
}
}
- private Supplier getLoadedChunk(DynmapChunk chunk, boolean async) {
- CraftWorld cw = (CraftWorld) w;
- if (!cw.isChunkLoaded(chunk.x, chunk.z)) return () -> null;
- Chunk c = cw.getHandle().getChunkIfLoaded(chunk.x, chunk.z); //already safe async on vanilla
- if ((c == null) || c.o) return () -> null; // c.loaded
- if (async) { //the data of the chunk may change while we write, better to write it sync
- CompletableFuture nbt = CompletableFuture.supplyAsync(() -> ChunkRegionLoader.a(cw.getHandle(), c), ((CraftServer) Bukkit.getServer()).getServer());
- return () -> {
- NBTTagCompound compound = nbt.join();
- return compound == null ? null : parseChunkFromNBT(new NBT.NBTCompound(compound));
- };
- } else {
- NBTTagCompound nbt = ChunkRegionLoader.a(cw.getHandle(), c);
- GenericChunk genericChunk;
- if (nbt != null) genericChunk = parseChunkFromNBT(new NBT.NBTCompound(nbt));
- else genericChunk = null;
- return () -> genericChunk;
- }
-
- }
- // Load generic chunk from unloaded chunk
protected GenericChunk loadChunk(DynmapChunk chunk) {
CraftWorld cw = (CraftWorld) w;
NBTTagCompound nbt = null;
diff --git a/bukkit-helper/src/main/java/org/dynmap/bukkit/helper/BukkitVersionHelperGeneric.java b/bukkit-helper/src/main/java/org/dynmap/bukkit/helper/BukkitVersionHelperGeneric.java
index 22eec1cf..edb0faf8 100644
--- a/bukkit-helper/src/main/java/org/dynmap/bukkit/helper/BukkitVersionHelperGeneric.java
+++ b/bukkit-helper/src/main/java/org/dynmap/bukkit/helper/BukkitVersionHelperGeneric.java
@@ -397,7 +397,7 @@ public abstract class BukkitVersionHelperGeneric extends BukkitVersionHelper {
/**
* Get inhabited ticks count from chunk
*/
- private static final Long zero = new Long(0);
+ private static final Long zero = Long.valueOf(0);
public long getInhabitedTicks(Chunk c) {
if (nmsc_inhabitedticks == null) {
return 0;
@@ -557,25 +557,25 @@ public abstract class BukkitVersionHelperGeneric extends BukkitVersionHelper {
if (profile != null) {
Object propmap = callMethod(profile, cmaprofile_getproperties, nullargs, null);
if ((propmap != null) && (propmap instanceof ForwardingMultimap)) {
- ForwardingMultimap fmm = (ForwardingMultimap) propmap;
- Collection