diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_14/BukkitAdapter_1_14.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_14/BukkitAdapter_1_14.java index b26f1474c..df730b96f 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_14/BukkitAdapter_1_14.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_14/BukkitAdapter_1_14.java @@ -9,6 +9,7 @@ import com.boydti.fawe.object.collection.BitArray; import com.boydti.fawe.util.MathMan; import com.boydti.fawe.util.ReflectionUtils; import com.boydti.fawe.util.TaskManager; +import com.google.common.util.concurrent.Striped; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockTypesCache; @@ -18,6 +19,7 @@ import java.lang.invoke.MethodHandles; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.Semaphore; import java.util.concurrent.locks.ReentrantLock; import net.jpountz.util.UnsafeUtils; import net.minecraft.server.v1_14_R1.Block; @@ -32,6 +34,7 @@ import net.minecraft.server.v1_14_R1.GameProfileSerializer; import net.minecraft.server.v1_14_R1.IBlockData; import net.minecraft.server.v1_14_R1.PlayerChunk; import net.minecraft.server.v1_14_R1.PlayerChunkMap; +import net.minecraft.server.v1_14_R1.World; import org.bukkit.craftbukkit.v1_14_R1.CraftChunk; import org.bukkit.craftbukkit.v1_14_R1.CraftWorld; import sun.misc.Unsafe; @@ -63,6 +66,8 @@ public final class BukkitAdapter_1_14 extends NMSAdapter { private static final Field fieldLock; + private static final Striped stripe = Striped.lazyWeakSemaphore(5, 1); + static { try { fieldSize = DataPaletteBlock.class.getDeclaredField("i"); @@ -135,10 +140,15 @@ public final class BukkitAdapter_1_14 extends NMSAdapter { } } - public static Chunk ensureLoaded(net.minecraft.server.v1_14_R1.World nmsWorld, int X, int Z) { - Chunk nmsChunk; - synchronized (nmsWorld) { + public static Chunk ensureLoaded(World nmsWorld, int X, int Z) { + Semaphore lock = stripe.get(nmsWorld.hashCode()); + Chunk nmsChunk = null; + try { + lock.acquire(); nmsChunk = nmsWorld.getChunkIfLoaded(X, Z); + } catch (InterruptedException ignored) { + } finally { + lock.release(); } if (nmsChunk != null) { return nmsChunk; @@ -147,7 +157,8 @@ public final class BukkitAdapter_1_14 extends NMSAdapter { return nmsWorld.getChunkAt(X, Z); } if (PaperLib.isPaper()) { - synchronized (nmsWorld) { + try { + lock.acquire(); CraftWorld craftWorld = nmsWorld.getWorld(); CompletableFuture future = craftWorld.getChunkAtAsync(X, Z, true); try { @@ -156,6 +167,9 @@ public final class BukkitAdapter_1_14 extends NMSAdapter { } catch (Throwable e) { e.printStackTrace(); } + } catch (InterruptedException ignored) { + } finally { + lock.release(); } } // TODO optimize diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15/BukkitAdapter_1_15.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15/BukkitAdapter_1_15.java index 4d96f3ec7..5ca22bcda 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15/BukkitAdapter_1_15.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15/BukkitAdapter_1_15.java @@ -9,6 +9,7 @@ import com.boydti.fawe.object.collection.BitArray; import com.boydti.fawe.util.MathMan; import com.boydti.fawe.util.ReflectionUtils; import com.boydti.fawe.util.TaskManager; +import com.google.common.util.concurrent.Striped; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockTypesCache; @@ -18,6 +19,7 @@ import java.lang.invoke.MethodHandles; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.Semaphore; import java.util.concurrent.locks.ReentrantLock; import net.jpountz.util.UnsafeUtils; import net.minecraft.server.v1_15_R1.*; @@ -52,6 +54,8 @@ public final class BukkitAdapter_1_15 extends NMSAdapter { private static final Field fieldLock; + private static final Striped stripe = Striped.lazyWeakSemaphore(5, 1); + static { try { fieldSize = DataPaletteBlock.class.getDeclaredField("i"); @@ -122,10 +126,15 @@ public final class BukkitAdapter_1_15 extends NMSAdapter { } } - public static Chunk ensureLoaded(net.minecraft.server.v1_15_R1.World nmsWorld, int X, int Z) { - Chunk nmsChunk; - synchronized (nmsWorld) { + public static Chunk ensureLoaded(World nmsWorld, int X, int Z) { + Semaphore lock = stripe.get(nmsWorld.hashCode()); + Chunk nmsChunk = null; + try { + lock.acquire(); nmsChunk = nmsWorld.getChunkIfLoaded(X, Z); + } catch (InterruptedException ignored) { + } finally { + lock.release(); } if (nmsChunk != null) { return nmsChunk; @@ -134,7 +143,8 @@ public final class BukkitAdapter_1_15 extends NMSAdapter { return nmsWorld.getChunkAt(X, Z); } if (PaperLib.isPaper()) { - synchronized (nmsWorld) { + try { + lock.acquire(); CraftWorld craftWorld = nmsWorld.getWorld(); CompletableFuture future = craftWorld.getChunkAtAsync(X, Z, true); try { @@ -143,6 +153,9 @@ public final class BukkitAdapter_1_15 extends NMSAdapter { } catch (Throwable e) { e.printStackTrace(); } + } catch (InterruptedException ignored) { + } finally { + lock.release(); } } // TODO optimize diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitAdapter_1_15_2.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitAdapter_1_15_2.java index 1e2e26c4f..94f4305a1 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitAdapter_1_15_2.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitAdapter_1_15_2.java @@ -9,6 +9,7 @@ import com.boydti.fawe.object.collection.BitArray; import com.boydti.fawe.util.MathMan; import com.boydti.fawe.util.ReflectionUtils; import com.boydti.fawe.util.TaskManager; +import com.google.common.util.concurrent.Striped; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockTypesCache; @@ -18,6 +19,7 @@ import java.lang.invoke.MethodHandles; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.Semaphore; import java.util.concurrent.locks.ReentrantLock; import net.jpountz.util.UnsafeUtils; import net.minecraft.server.v1_15_R1.*; @@ -52,6 +54,8 @@ public final class BukkitAdapter_1_15_2 extends NMSAdapter { private static final Field fieldLock; + private static final Striped stripe = Striped.lazyWeakSemaphore(5, 1); + static { try { fieldSize = DataPaletteBlock.class.getDeclaredField("i"); @@ -124,9 +128,14 @@ public final class BukkitAdapter_1_15_2 extends NMSAdapter { } public static Chunk ensureLoaded(World nmsWorld, int X, int Z) { - Chunk nmsChunk; - synchronized (nmsWorld) { + Semaphore lock = stripe.get(nmsWorld.hashCode()); + Chunk nmsChunk = null; + try { + lock.acquire(); nmsChunk = nmsWorld.getChunkIfLoaded(X, Z); + } catch (InterruptedException ignored) { + } finally { + lock.release(); } if (nmsChunk != null) { return nmsChunk; @@ -135,7 +144,8 @@ public final class BukkitAdapter_1_15_2 extends NMSAdapter { return nmsWorld.getChunkAt(X, Z); } if (PaperLib.isPaper()) { - synchronized (nmsWorld) { + try { + lock.acquire(); CraftWorld craftWorld = nmsWorld.getWorld(); CompletableFuture future = craftWorld.getChunkAtAsync(X, Z, true); try { @@ -144,6 +154,9 @@ public final class BukkitAdapter_1_15_2 extends NMSAdapter { } catch (Throwable e) { e.printStackTrace(); } + } catch (InterruptedException ignored) { + } finally { + lock.release(); } } // TODO optimize