소스 검색

Update BlockTracker to use Spigot API directly instead of compatibility
layer
Fixes #4692 Fixes #4698

nossr50 3 년 전
부모
커밋
dd550feb65

+ 8 - 21
src/main/java/com/gmail/nossr50/listeners/BlockListener.java

@@ -21,7 +21,6 @@ import com.gmail.nossr50.skills.repair.Repair;
 import com.gmail.nossr50.skills.salvage.Salvage;
 import com.gmail.nossr50.skills.woodcutting.WoodcuttingManager;
 import com.gmail.nossr50.util.*;
-import com.gmail.nossr50.util.compat.layers.world.WorldCompatibilityLayer;
 import com.gmail.nossr50.util.player.UserManager;
 import com.gmail.nossr50.util.skills.SkillUtils;
 import com.gmail.nossr50.util.sounds.SoundManager;
@@ -131,12 +130,10 @@ public class BlockListener implements Listener {
 
         BlockFace direction = event.getDirection();
         Block movedBlock;
-        WorldCompatibilityLayer worldCompatibilityLayer = mcMMO.getCompatibilityManager().getWorldCompatibilityLayer();
-
         for (Block block : event.getBlocks()) {
             movedBlock = block.getRelative(direction);
 
-            if(BlockUtils.isWithinWorldBounds(worldCompatibilityLayer, movedBlock)) {
+            if(BlockUtils.isWithinWorldBounds(movedBlock)) {
                 mcMMO.getPlaceStore().setTrue(movedBlock);
             }
         }
@@ -161,15 +158,13 @@ public class BlockListener implements Listener {
         BlockFace direction = event.getDirection();
         Block movedBlock = event.getBlock().getRelative(direction);
 
-        WorldCompatibilityLayer worldCompatibilityLayer = mcMMO.getCompatibilityManager().getWorldCompatibilityLayer();
-
         //Spigot makes bad things happen in its API
-        if(BlockUtils.isWithinWorldBounds(worldCompatibilityLayer, movedBlock)) {
+        if(BlockUtils.isWithinWorldBounds(movedBlock)) {
             mcMMO.getPlaceStore().setTrue(movedBlock);
         }
 
         for (Block block : event.getBlocks()) {
-            if(BlockUtils.isWithinWorldBounds(worldCompatibilityLayer, block)) {
+            if(BlockUtils.isWithinWorldBounds(block)) {
                 mcMMO.getPlaceStore().setTrue(block.getRelative(direction));
             }
         }
@@ -192,10 +187,9 @@ public class BlockListener implements Listener {
         BlockState blockState = event.getNewState();
 
         if(ExperienceConfig.getInstance().isSnowExploitPrevented() && BlockUtils.shouldBeWatched(blockState)) {
-            WorldCompatibilityLayer worldCompatibilityLayer = mcMMO.getCompatibilityManager().getWorldCompatibilityLayer();
             Block block = blockState.getBlock();
 
-            if(BlockUtils.isWithinWorldBounds(worldCompatibilityLayer, block)) {
+            if(BlockUtils.isWithinWorldBounds(block)) {
                 mcMMO.getPlaceStore().setTrue(block);
             }
         }
@@ -215,10 +209,9 @@ public class BlockListener implements Listener {
 
         if(ExperienceConfig.getInstance().preventStoneLavaFarming()) {
             BlockState newState = event.getNewState();
-            WorldCompatibilityLayer worldCompatibilityLayer = mcMMO.getCompatibilityManager().getWorldCompatibilityLayer();
 
             if(newState.getType() != Material.OBSIDIAN && ExperienceConfig.getInstance().doesBlockGiveSkillXP(PrimarySkillType.MINING, newState.getBlockData())) {
-                if(BlockUtils.isWithinWorldBounds(worldCompatibilityLayer, newState.getBlock())) {
+                if(BlockUtils.isWithinWorldBounds(newState.getBlock())) {
                     mcMMO.getPlaceStore().setTrue(newState);
                 }
             }
@@ -243,9 +236,7 @@ public class BlockListener implements Listener {
             return;
         }
 
-        WorldCompatibilityLayer worldCompatibilityLayer = mcMMO.getCompatibilityManager().getWorldCompatibilityLayer();
-
-        if(BlockUtils.isWithinWorldBounds(worldCompatibilityLayer, block)) {
+        if(BlockUtils.isWithinWorldBounds(block)) {
             //NOTE: BlockMultiPlace has its own logic so don't handle anything that would overlap
             if (!(event instanceof BlockMultiPlaceEvent)) {
                 mcMMO.getPlaceStore().setTrue(blockState);
@@ -283,10 +274,8 @@ public class BlockListener implements Listener {
             BlockState blockState = replacedBlockState.getBlock().getState();
             Block block = blockState.getBlock();
 
-            WorldCompatibilityLayer worldCompatibilityLayer = mcMMO.getCompatibilityManager().getWorldCompatibilityLayer();
-
             /* Check if the blocks placed should be monitored so they do not give out XP in the future */
-            if(BlockUtils.isWithinWorldBounds(worldCompatibilityLayer, block)) {
+            if(BlockUtils.isWithinWorldBounds(block)) {
                 //Updated: 10/5/2021
                 //Note: For some reason Azalea trees trigger this event but no other tree does (as of 10/5/2021) but if this changes in the future we may need to update this
                 if(BlockUtils.isPartOfTree(event.getBlockPlaced())) {
@@ -311,9 +300,7 @@ public class BlockListener implements Listener {
             return;
 
         // Minecraft is dumb, the events still throw when a plant "grows" higher than the max block height.  Even though no new block is created
-        WorldCompatibilityLayer worldCompatibilityLayer = mcMMO.getCompatibilityManager().getWorldCompatibilityLayer();
-
-        if(BlockUtils.isWithinWorldBounds(worldCompatibilityLayer, block)) {
+        if(BlockUtils.isWithinWorldBounds(block)) {
             mcMMO.getPlaceStore().setFalse(block);
         }
     }

+ 8 - 3
src/main/java/com/gmail/nossr50/util/BlockUtils.java

@@ -7,7 +7,6 @@ import com.gmail.nossr50.datatypes.skills.SubSkillType;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.skills.repair.Repair;
 import com.gmail.nossr50.skills.salvage.Salvage;
-import com.gmail.nossr50.util.compat.layers.world.WorldCompatibilityLayer;
 import com.gmail.nossr50.util.random.RandomChanceSkill;
 import com.gmail.nossr50.util.random.RandomChanceUtil;
 import org.bukkit.Material;
@@ -302,11 +301,17 @@ public final class BlockUtils {
         return hasWoodcuttingXP(block.getState()) || isNonWoodPartOfTree(block.getType());
     }
 
-    public static boolean isWithinWorldBounds(@NotNull WorldCompatibilityLayer worldCompatibilityLayer, @NotNull Block block) {
+    /**
+     * Checks to see if a Block is within the world bounds
+     * Prevent processing blocks from other plugins (or perhaps odd spigot anomalies) from sending blocks that can't exist within the world
+     * @param block
+     * @return
+     */
+    public static boolean isWithinWorldBounds(@NotNull Block block) {
         World world = block.getWorld();
 
         //World min height = inclusive | World max height = exclusive
-        return block.getY() >= worldCompatibilityLayer.getMinWorldHeight(world) && block.getY() < worldCompatibilityLayer.getMaxWorldHeight(world);
+        return block.getY() >= world.getMinHeight() && block.getY() < world.getMaxHeight();
     }
 
 }

+ 10 - 11
src/main/java/com/gmail/nossr50/util/blockmeta/BitSetChunkStore.java

@@ -1,6 +1,5 @@
 package com.gmail.nossr50.util.blockmeta;
 
-import com.gmail.nossr50.mcMMO;
 import org.bukkit.Bukkit;
 import org.bukkit.World;
 import org.jetbrains.annotations.NotNull;
@@ -25,7 +24,7 @@ public class BitSetChunkStore implements ChunkStore {
     private transient boolean dirty = false;
 
     public BitSetChunkStore(@NotNull World world, int cx, int cz) {
-        this(world.getUID(), mcMMO.getCompatibilityManager().getWorldCompatibilityLayer().getMinWorldHeight(world), world.getMaxHeight(), cx, cz);
+        this(world.getUID(), world.getMinHeight(), world.getMaxHeight(), cx, cz);
     }
 
     private BitSetChunkStore(@NotNull UUID worldUid, int worldMin, int worldMax, int cx, int cz) {
@@ -109,23 +108,23 @@ public class BitSetChunkStore implements ChunkStore {
         return (z * 16 + x) + (256 * (y + yOffset));
     }
 
-    private static int getWorldMin(@NotNull UUID worldUid, int storedWorldMin) {
+    private static int getWorldMin(@NotNull UUID worldUid) {
         World world = Bukkit.getWorld(worldUid);
 
         // Not sure how this case could come up, but might as well handle it gracefully.  Loading a chunkstore for an unloaded world?
         if (world == null)
-            return storedWorldMin;
+            throw new RuntimeException("Cannot grab a minimum world height for an unloaded world");
 
-        return mcMMO.getCompatibilityManager().getWorldCompatibilityLayer().getMinWorldHeight(world);
+        return world.getMinHeight();
     }
 
-    private static int getWorldMax(@NotNull UUID worldUid, int storedWorldMax)
+    private static int getWorldMax(@NotNull UUID worldUid)
     {
         World world = Bukkit.getWorld(worldUid);
 
         // Not sure how this case could come up, but might as well handle it gracefully.  Loading a chunkstore for an unloaded world?
         if (world == null)
-            return storedWorldMax;
+            throw new RuntimeException("Cannot grab a maximum world height for an unloaded world");
 
         return world.getMaxHeight();
     }
@@ -171,8 +170,8 @@ public class BitSetChunkStore implements ChunkStore {
         in.readFully(temp);
         BitSet stored = BitSet.valueOf(temp);
 
-        int currentWorldMin = getWorldMin(worldUid, worldMin);
-        int currentWorldMax = getWorldMax(worldUid, worldMax);
+        int currentWorldMin = getWorldMin(worldUid);
+        int currentWorldMax = getWorldMax(worldUid);
 
         // The order in which the world height update code occurs here is important, the world max truncate math only holds up if done before adjusting for min changes
         // Lop off extra data if world max has shrunk
@@ -273,8 +272,8 @@ public class BitSetChunkStore implements ChunkStore {
 
                 public @NotNull BitSetChunkStore convert()
                 {
-                    int currentWorldMin = getWorldMin(worldUid, 0);
-                    int currentWorldMax = getWorldMax(worldUid, worldMax);
+                    int currentWorldMin = getWorldMin(worldUid);
+                    int currentWorldMax = getWorldMax(worldUid);
 
                     BitSetChunkStore converted = new BitSetChunkStore(worldUid, currentWorldMin, currentWorldMax, cx, cz);
 

+ 0 - 27
src/main/java/com/gmail/nossr50/util/compat/CompatibilityManager.java

@@ -10,12 +10,9 @@ import com.gmail.nossr50.util.compat.layers.persistentdata.SpigotPersistentDataL
 import com.gmail.nossr50.util.compat.layers.persistentdata.SpigotPersistentDataLayer_1_14;
 import com.gmail.nossr50.util.compat.layers.skills.AbstractMasterAnglerCompatibility;
 import com.gmail.nossr50.util.compat.layers.skills.MasterAnglerCompatibilityLayer;
-import com.gmail.nossr50.util.compat.layers.world.WorldCompatibilityLayer;
-import com.gmail.nossr50.util.compat.layers.world.WorldCompatibilityLayer_1_16_4;
 import com.gmail.nossr50.util.nms.NMSVersion;
 import com.gmail.nossr50.util.platform.MinecraftGameVersion;
 import com.gmail.nossr50.util.text.StringUtils;
-import org.bukkit.World;
 import org.bukkit.command.CommandSender;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -40,7 +37,6 @@ public class CompatibilityManager {
     private AbstractPersistentDataLayer persistentDataLayer;
     private AbstractBungeeSerializerCompatibilityLayer bungeeSerializerCompatibilityLayer;
     private AbstractMasterAnglerCompatibility masterAnglerCompatibility;
-    private WorldCompatibilityLayer worldCompatibilityLayer;
 
     public CompatibilityManager(@NotNull MinecraftGameVersion minecraftGameVersion) {
         mcMMO.p.getLogger().info("Loading compatibility layers...");
@@ -71,29 +67,10 @@ public class CompatibilityManager {
         initPersistentDataLayer();
         initBungeeSerializerLayer();
         initMasterAnglerLayer();
-        initWorldCompatibilityLayer();
 
         isFullyCompatibleServerSoftware = true;
     }
 
-    private void initWorldCompatibilityLayer() {
-        if(minecraftGameVersion.isAtLeast(1, 17, 0)) {
-            worldCompatibilityLayer = new WorldCompatibilityLayer_1_16_4();
-        } else {
-            worldCompatibilityLayer = new WorldCompatibilityLayer() {
-                @Override
-                public int getMinWorldHeight(@NotNull World world) {
-                    return WorldCompatibilityLayer.super.getMinWorldHeight(world);
-                }
-
-                @Override
-                public int getMaxWorldHeight(@NotNull World world) {
-                    return WorldCompatibilityLayer.super.getMaxWorldHeight(world);
-                }
-            };
-        }
-    }
-
     private void initMasterAnglerLayer() {
         if(minecraftGameVersion.isAtLeast(1, 16, 3)) {
             masterAnglerCompatibility = new MasterAnglerCompatibilityLayer();
@@ -202,10 +179,6 @@ public class CompatibilityManager {
         return masterAnglerCompatibility;
     }
 
-    public @NotNull WorldCompatibilityLayer getWorldCompatibilityLayer() {
-        return worldCompatibilityLayer;
-    }
-
     public @Nullable MinecraftGameVersion getMinecraftGameVersion() {
         return minecraftGameVersion;
     }

+ 0 - 11
src/main/java/com/gmail/nossr50/util/compat/layers/world/WorldCompatibilityLayer.java

@@ -1,11 +0,0 @@
-package com.gmail.nossr50.util.compat.layers.world;
-
-import com.gmail.nossr50.util.compat.CompatibilityLayer;
-import org.bukkit.World;
-import org.jetbrains.annotations.NotNull;
-
-public interface WorldCompatibilityLayer extends CompatibilityLayer {
-    default int getMinWorldHeight(@NotNull World world) { return 0; }
-
-    default int getMaxWorldHeight(@NotNull World world) { return 256; }
-}

+ 0 - 16
src/main/java/com/gmail/nossr50/util/compat/layers/world/WorldCompatibilityLayer_1_16_4.java

@@ -1,16 +0,0 @@
-package com.gmail.nossr50.util.compat.layers.world;
-
-import org.bukkit.World;
-import org.jetbrains.annotations.NotNull;
-
-public class WorldCompatibilityLayer_1_16_4 implements WorldCompatibilityLayer {
-    @Override
-    public int getMinWorldHeight(@NotNull World world) {
-        return world.getMinHeight();
-    }
-
-    @Override
-    public int getMaxWorldHeight(@NotNull World world) {
-        return world.getMaxHeight();
-    }
-}

+ 12 - 28
src/test/java/com/gmail/nossr50/util/blockmeta/ChunkStoreTest.java

@@ -4,7 +4,6 @@ package com.gmail.nossr50.util.blockmeta;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.util.BlockUtils;
 import com.gmail.nossr50.util.compat.CompatibilityManager;
-import com.gmail.nossr50.util.compat.layers.world.WorldCompatibilityLayer;
 import com.gmail.nossr50.util.platform.PlatformManager;
 import com.google.common.io.Files;
 import org.bukkit.Bukkit;
@@ -39,10 +38,7 @@ class ChunkStoreTest {
     }
 
     private World mockWorld;
-    private CompatibilityManager compatibilityManager;
-    private WorldCompatibilityLayer worldCompatibilityLayer;
-    private PlatformManager platformManager;
-    
+
     private MockedStatic<Bukkit> bukkitMock;
     private MockedStatic<mcMMO> mcMMOMock;
 
@@ -57,24 +53,10 @@ class ChunkStoreTest {
         bukkitMock = Mockito.mockStatic(Bukkit.class);
         bukkitMock.when(() -> Bukkit.getWorld(worldUUID)).thenReturn(mockWorld);
 
-        platformManager = Mockito.mock(PlatformManager.class);
-        compatibilityManager = Mockito.mock(CompatibilityManager.class);
-        worldCompatibilityLayer = Mockito.mock(WorldCompatibilityLayer.class);
-
         mcMMOMock = Mockito.mockStatic(mcMMO.class);
 
-        mcMMOMock.when(() -> mcMMO.getPlatformManager()).thenReturn(platformManager);
-        Assertions.assertNotNull(mcMMO.getPlatformManager());
-
-        mcMMOMock.when(() -> mcMMO.getCompatibilityManager()).thenReturn(compatibilityManager);
-        Assertions.assertNotNull(mcMMO.getCompatibilityManager());
-
-        Mockito.when(platformManager.getCompatibilityManager()).thenReturn(compatibilityManager);
-        Mockito.when(platformManager.getCompatibilityManager().getWorldCompatibilityLayer()).thenReturn(worldCompatibilityLayer);
-        Assertions.assertNotNull(mcMMO.getCompatibilityManager().getWorldCompatibilityLayer());
-        Mockito.when(worldCompatibilityLayer.getMinWorldHeight(mockWorld)).thenReturn(LEGACY_WORLD_HEIGHT_MIN);
-        Mockito.when(worldCompatibilityLayer.getMaxWorldHeight(mockWorld)).thenReturn(LEGACY_WORLD_HEIGHT_MAX);
-
+        Mockito.when(mockWorld.getMinHeight()).thenReturn(LEGACY_WORLD_HEIGHT_MIN);
+        Mockito.when(mockWorld.getMaxHeight()).thenReturn(LEGACY_WORLD_HEIGHT_MAX);
     }
     
     @AfterEach
@@ -85,7 +67,7 @@ class ChunkStoreTest {
 
     @Test
     void testIndexOutOfBounds() {
-        Mockito.when(mcMMO.getCompatibilityManager().getWorldCompatibilityLayer().getMinWorldHeight(mockWorld)).thenReturn(-64);
+        Mockito.when(mockWorld.getMinHeight()).thenReturn(-64);
         HashChunkManager hashChunkManager = new HashChunkManager();
 
         // Top Block
@@ -96,7 +78,7 @@ class ChunkStoreTest {
 
     @Test
     void testSetTrue() {
-        Mockito.when(mcMMO.getCompatibilityManager().getWorldCompatibilityLayer().getMinWorldHeight(mockWorld)).thenReturn(-64);
+        Mockito.when(mockWorld.getMinHeight()).thenReturn(-64);
         HashChunkManager hashChunkManager = new HashChunkManager();
         int radius = 2; // Could be anything but drastically changes test time
 
@@ -117,7 +99,7 @@ class ChunkStoreTest {
         Block bottomBlock = initMockBlock(1337, 0, -1337);
         Assertions.assertFalse(hashChunkManager.isTrue(bottomBlock));
 
-        Assertions.assertTrue(BlockUtils.isWithinWorldBounds(worldCompatibilityLayer, bottomBlock));
+        Assertions.assertTrue(BlockUtils.isWithinWorldBounds(bottomBlock));
         hashChunkManager.setTrue(bottomBlock);
         Assertions.assertTrue(hashChunkManager.isTrue(bottomBlock));
 
@@ -125,7 +107,7 @@ class ChunkStoreTest {
         Block topBlock = initMockBlock(1337, 255, -1337);
         Assertions.assertFalse(hashChunkManager.isTrue(topBlock));
 
-        Assertions.assertTrue(BlockUtils.isWithinWorldBounds(worldCompatibilityLayer, topBlock));
+        Assertions.assertTrue(BlockUtils.isWithinWorldBounds(topBlock));
         hashChunkManager.setTrue(topBlock);
         Assertions.assertTrue(hashChunkManager.isTrue(topBlock));
     }
@@ -161,7 +143,7 @@ class ChunkStoreTest {
 
     @Test
     void testNegativeWorldMin() throws IOException {
-        Mockito.when(mcMMO.getCompatibilityManager().getWorldCompatibilityLayer().getMinWorldHeight(mockWorld)).thenReturn(-64);
+        Mockito.when(mockWorld.getMinHeight()).thenReturn(-64);
 
         BitSetChunkStore original = new BitSetChunkStore(mockWorld, 1, 2);
         original.setTrue(14, -32, 12);
@@ -180,8 +162,9 @@ class ChunkStoreTest {
         original.setTrue(13, 3, 12);
         byte[] serializedBytes = serializeChunkstore(original);
 
-        Mockito.when(mcMMO.getCompatibilityManager().getWorldCompatibilityLayer().getMinWorldHeight(mockWorld)).thenReturn(-64);
+        Mockito.when(mockWorld.getMinHeight()).thenReturn(-64);
         ChunkStore deserialized = BitSetChunkStore.Serialization.readChunkStore(new DataInputStream(new ByteArrayInputStream(serializedBytes)));
+        assert deserialized != null;
         assertEqualIgnoreMinMax(original, deserialized);
     }
 
@@ -202,6 +185,7 @@ class ChunkStoreTest {
         original.setTrue(13, 89, 12);
         byte[] serializedBytes = serializeChunkstore(original);
         ChunkStore deserialized = BitSetChunkStore.Serialization.readChunkStore(new DataInputStream(new ByteArrayInputStream(serializedBytes)));
+        assert deserialized != null;
         assertEqual(original, deserialized);
     }
 
@@ -221,6 +205,7 @@ class ChunkStoreTest {
         try (DataInputStream is = region.getInputStream(original.getChunkX(), original.getChunkZ())) {
             Assertions.assertNotNull(is);
             ChunkStore deserialized = BitSetChunkStore.Serialization.readChunkStore(is);
+            assert deserialized != null;
             assertEqual(original, deserialized);
         }
         region.close();
@@ -299,7 +284,6 @@ class ChunkStoreTest {
     }
 
     public static class LegacyChunkStore implements ChunkStore, Serializable {
-
         private static final long serialVersionUID = -1L;
         transient private boolean dirty = false;
         public boolean[][][] store;