From 00d0735079477e62dbc88ea6d7fd9ef06d994642 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 29 Dec 2024 09:29:59 -0800 Subject: [PATCH 1/3] Abstract out all PaperLib so that it only exists in Util class. --- .../listeners/flags/protection/LockAndBanListener.java | 4 ++-- .../world/bentobox/bentobox/managers/IslandsManager.java | 5 ++--- .../world/bentobox/bentobox/nms/CopyWorldRegenerator.java | 7 ++++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/LockAndBanListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/LockAndBanListener.java index 6a41cb2ca..9295eb8a7 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/LockAndBanListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/LockAndBanListener.java @@ -13,11 +13,11 @@ import org.bukkit.util.Vector; import org.eclipse.jdt.annotation.NonNull; -import io.papermc.lib.PaperLib; import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.flags.FlagListener; import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.lists.Flags; +import world.bentobox.bentobox.util.Util; /** * Listener for the lock flag @@ -164,7 +164,7 @@ private void eject(Player player) { // We'll try to teleport him to the spawn... Location l = player.getWorld().getSpawnLocation(); if (l != null) { - PaperLib.teleportAsync(player, l); + Util.teleportAsync(player, l); } // Switch him back to the default gamemode. He may die, sorry :( diff --git a/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java b/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java index 53c25b4ba..0e63adaa9 100644 --- a/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java @@ -40,7 +40,6 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; -import io.papermc.lib.PaperLib; import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.events.IslandBaseEvent; import world.bentobox.bentobox.api.events.island.IslandEvent; @@ -1080,7 +1079,7 @@ private CompletableFuture homeTeleportAsync(@NonNull World world, @NonN .ifFail(() -> goingHome.remove(user.getUniqueId())).buildFuture().thenAccept(result::complete); return; } - PaperLib.teleportAsync(Objects.requireNonNull(player), home).thenAccept(b -> { + Util.teleportAsync(Objects.requireNonNull(player), home).thenAccept(b -> { // Only run the commands if the player is successfully teleported if (Boolean.TRUE.equals(b)) { teleported(world, user, name, newIsland, island); @@ -1469,7 +1468,7 @@ public void removePlayersFromIsland(Island island) { } else { // Move player to spawn getSpawn(w).map(i -> i.getSpawnPoint(w.getEnvironment())).filter(Objects::nonNull) - .ifPresentOrElse(sp -> PaperLib.teleportAsync(p, sp), + .ifPresentOrElse(sp -> Util.teleportAsync(p, sp), () -> plugin.logWarning("Spawn exists but its location is null!")); } diff --git a/src/main/java/world/bentobox/bentobox/nms/CopyWorldRegenerator.java b/src/main/java/world/bentobox/bentobox/nms/CopyWorldRegenerator.java index 4be154439..5affe938b 100644 --- a/src/main/java/world/bentobox/bentobox/nms/CopyWorldRegenerator.java +++ b/src/main/java/world/bentobox/bentobox/nms/CopyWorldRegenerator.java @@ -48,6 +48,7 @@ import world.bentobox.bentobox.hooks.SlimefunHook; import world.bentobox.bentobox.hooks.ZNPCsPlusHook; import world.bentobox.bentobox.util.MyBiomeGrid; +import world.bentobox.bentobox.util.Util; /** * Regenerates by using a seed world. The seed world is created using the same generator as the game @@ -148,7 +149,7 @@ private CompletableFuture regenerateChunk(@Nullable IslandDeletion di, @No CompletableFuture seedWorldFuture = getSeedWorldChunk(world, chunkX, chunkZ); // Set up a future to get the chunk requests using Paper's Lib. If Paper is used, this should be done async - CompletableFuture chunkFuture = PaperLib.getChunkAtAsync(world, chunkX, chunkZ); + CompletableFuture chunkFuture = Util.getChunkAtAsync(world, chunkX, chunkZ); // If there is no island, do not clean chunk CompletableFuture cleanFuture = di != null ? cleanChunk(chunkFuture, di) : CompletableFuture.completedFuture(null); @@ -172,7 +173,7 @@ private CompletableFuture regenerateChunk(@Nullable IslandDeletion di, @No private CompletableFuture getSeedWorldChunk(World world, int chunkX, int chunkZ) { World seed = Bukkit.getWorld(world.getName() + "/bentobox"); if (seed == null) return CompletableFuture.completedFuture(null); - return PaperLib.getChunkAtAsync(seed, chunkX, chunkZ); + return Util.getChunkAtAsync(seed, chunkX, chunkZ); } /** @@ -374,7 +375,7 @@ private boolean isEnded(int chunkX) { @SuppressWarnings("deprecation") private CompletableFuture regenerateChunk(GameModeAddon gm, IslandDeletion di, @Nonnull World world, int chunkX, int chunkZ) { - CompletableFuture chunkFuture = PaperLib.getChunkAtAsync(world, chunkX, chunkZ); + CompletableFuture chunkFuture = Util.getChunkAtAsync(world, chunkX, chunkZ); CompletableFuture invFuture = chunkFuture.thenAccept(chunk -> Arrays.stream(chunk.getTileEntities()).filter(InventoryHolder.class::isInstance) .filter(te -> di.inBounds(te.getLocation().getBlockX(), te.getLocation().getBlockZ())) From 1fa2849053055424fe3e3a7c71a89f258b7cf514 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 29 Dec 2024 09:36:09 -0800 Subject: [PATCH 2/3] Adjust POM --- pom.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index e580a33b8..1e46541fd 100644 --- a/pom.xml +++ b/pom.xml @@ -233,6 +233,13 @@ 4.2.2 test + + + io.papermc.paper + paper-api + ${paper.version} + provided + org.spigotmc @@ -357,13 +364,6 @@ org.eclipse.jdt.annotation 2.2.600 - - - io.papermc - paperlib - 1.0.6 - compile - com.github.apachezy From 4a55ea790eddb96f8f59e6a47c113a3d06e4df49 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 29 Dec 2024 13:40:10 -0800 Subject: [PATCH 3/3] Works on Paper and Spigot. Tests are a mess and won't compile or run TODO: Get test working in Paper-land. Relates to ##2577 --- .../bentobox/bentobox/api/hooks/NPCHook.java | 2 - .../bentobox/hooks/FancyNpcsHook.java | 1 - .../bentobox/managers/IslandsManager.java | 1 - .../bentobox/managers/island/NewIsland.java | 2 +- .../bentobox/nms/CopyWorldRegenerator.java | 2 +- .../world/bentobox/bentobox/util/Util.java | 131 +++++++----------- .../team/IslandTeamInviteCommandTest.java | 3 +- .../adapters/ItemStackTypeAdapterTest.java | 3 +- .../protection/BreakBlocksListenerTest.java | 2 +- .../InvincibleVisitorsListenerTest.java | 2 +- .../bentobox/managers/IslandsManagerTest.java | 12 +- .../bentobox/managers/PlayersManagerTest.java | 2 +- .../bentobox/bentobox/mocks/ServerMocks.java | 19 ++- .../panels/BlueprintManagementPanelTest.java | 2 +- .../customizable/IslandCreationPanelTest.java | 10 +- .../customizable/LanguagePanelTest.java | 2 +- 16 files changed, 88 insertions(+), 108 deletions(-) diff --git a/src/main/java/world/bentobox/bentobox/api/hooks/NPCHook.java b/src/main/java/world/bentobox/bentobox/api/hooks/NPCHook.java index 6a848215f..fdcbca181 100644 --- a/src/main/java/world/bentobox/bentobox/api/hooks/NPCHook.java +++ b/src/main/java/world/bentobox/bentobox/api/hooks/NPCHook.java @@ -12,8 +12,6 @@ import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; -import de.oliver.fancynpcs.api.Npc; -import lol.pyr.znpcsplus.api.npc.NpcEntry; import world.bentobox.bentobox.blueprints.dataobjects.BlueprintEntity; /** diff --git a/src/main/java/world/bentobox/bentobox/hooks/FancyNpcsHook.java b/src/main/java/world/bentobox/bentobox/hooks/FancyNpcsHook.java index c8c375f12..528289e24 100644 --- a/src/main/java/world/bentobox/bentobox/hooks/FancyNpcsHook.java +++ b/src/main/java/world/bentobox/bentobox/hooks/FancyNpcsHook.java @@ -30,7 +30,6 @@ import de.oliver.fancynpcs.api.actions.NpcAction; import de.oliver.fancynpcs.api.utils.NpcEquipmentSlot; import de.oliver.fancynpcs.api.utils.SkinFetcher; -import lol.pyr.znpcsplus.api.npc.NpcEntry; import net.kyori.adventure.text.format.NamedTextColor; import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.hooks.NPCHook; diff --git a/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java b/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java index 0e63adaa9..30037e739 100644 --- a/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java @@ -1191,7 +1191,6 @@ public void spawnTeleport(@NonNull World world, @NonNull Player player) { * * @param player player */ - @SuppressWarnings("deprecation") private void readyPlayer(@NonNull Player player) { // Stop any gliding player.setGliding(false); diff --git a/src/main/java/world/bentobox/bentobox/managers/island/NewIsland.java b/src/main/java/world/bentobox/bentobox/managers/island/NewIsland.java index 198e8950c..59aec708d 100644 --- a/src/main/java/world/bentobox/bentobox/managers/island/NewIsland.java +++ b/src/main/java/world/bentobox/bentobox/managers/island/NewIsland.java @@ -15,9 +15,9 @@ import world.bentobox.bentobox.api.events.island.IslandCreateEvent; import world.bentobox.bentobox.api.events.island.IslandEvent; import world.bentobox.bentobox.api.events.island.IslandEvent.Reason; +import world.bentobox.bentobox.api.events.island.IslandResetEvent; import world.bentobox.bentobox.api.logs.LogEntry; import world.bentobox.bentobox.api.logs.LogEntry.LogType; -import world.bentobox.bentobox.api.events.island.IslandResetEvent; import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.managers.BlueprintsManager; diff --git a/src/main/java/world/bentobox/bentobox/nms/CopyWorldRegenerator.java b/src/main/java/world/bentobox/bentobox/nms/CopyWorldRegenerator.java index 5affe938b..dec80a8e3 100644 --- a/src/main/java/world/bentobox/bentobox/nms/CopyWorldRegenerator.java +++ b/src/main/java/world/bentobox/bentobox/nms/CopyWorldRegenerator.java @@ -38,7 +38,6 @@ import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; -import io.papermc.lib.PaperLib; import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.addons.GameModeAddon; import world.bentobox.bentobox.api.hooks.Hook; @@ -248,6 +247,7 @@ private void copyChunkDataToChunk(Chunk toChunk, Chunk fromChunk, BoundingBox li Arrays.stream(fromChunk.getTileEntities()).forEach(bs -> processTileEntity(bs.getBlock(), bs.getLocation().toVector().toLocation(toChunk.getWorld()).getBlock())); } + @SuppressWarnings("deprecation") private void processEntity(Entity entity, Location location) { Entity bpe = location.getWorld().spawnEntity(location, entity.getType()); bpe.setCustomName(entity.getCustomName()); diff --git a/src/main/java/world/bentobox/bentobox/util/Util.java b/src/main/java/world/bentobox/bentobox/util/Util.java index 3cf2fac55..4aa1ccc1f 100644 --- a/src/main/java/world/bentobox/bentobox/util/Util.java +++ b/src/main/java/world/bentobox/bentobox/util/Util.java @@ -1,6 +1,7 @@ package world.bentobox.bentobox.util; import java.io.IOException; +import java.lang.reflect.Method; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -26,7 +27,6 @@ import org.bukkit.World; import org.bukkit.World.Environment; import org.bukkit.attribute.Attribute; -import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.entity.Allay; import org.bukkit.entity.Animals; @@ -51,8 +51,6 @@ import com.google.common.base.Enums; import com.google.common.base.Optional; -import io.papermc.lib.PaperLib; -import io.papermc.lib.features.blockstatesnapshot.BlockStateSnapshotResult; import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.nms.PasteHandler; @@ -382,7 +380,7 @@ public static boolean isTamableEntity(Entity entity) { */ @NonNull public static CompletableFuture teleportAsync(@Nonnull Entity entity, @Nonnull Location location) { - return PaperLib.teleportAsync(entity, location); + return teleportAsync(entity, location, TeleportCause.UNKNOWN); } /** @@ -392,12 +390,26 @@ public static CompletableFuture teleportAsync(@Nonnull Entity entity, @ * @param cause The cause for the teleportation * @return Future that completes with the result of the teleport */ + @SuppressWarnings("unchecked") @NonNull public static CompletableFuture teleportAsync(@Nonnull Entity entity, @Nonnull Location location, TeleportCause cause) { - return PaperLib.teleportAsync(entity, location, cause); + try { + // Use reflection to check if the method exists + Method method = Entity.class.getMethod("teleportAsync", Location.class, TeleportCause.class); + if (method != null) { + // Invoke the method using reflection on the entity instance + return (CompletableFuture) method.invoke(entity, location, cause); + } + } catch (NoSuchMethodException e) { + // Method does not exist, fallback to Spigot behavior + } catch (Exception e) { + plugin.logStacktrace(e); // Report other exceptions + } + // Fallback for Spigot servers + entity.teleport(location, cause); + return CompletableFuture.completedFuture(true); } - /** * Gets the chunk at the target location, loading it asynchronously if needed. * @param loc Location to get chunk for @@ -440,9 +452,24 @@ public static CompletableFuture getChunkAtAsync(@Nonnull World world, int * @param gen Should the chunk generate or not. Only respected on some MC versions, 1.13 for CB, 1.12 for Paper * @return Future that completes with the chunk, or null if the chunk did not exists and generation was not requested. */ + @SuppressWarnings("unchecked") @NonNull public static CompletableFuture getChunkAtAsync(@Nonnull World world, int x, int z, boolean gen) { - return PaperLib.getChunkAtAsync(world, x, z, gen); + try { + // Use reflection to check if the method exists + Method method = World.class.getMethod("getChunkAtAsync", int.class, int.class, boolean.class); + if (method != null) { + // Invoke the method using reflection + return (CompletableFuture) method.invoke(world, x, z, gen); + } + } catch (NoSuchMethodException e) { + // Method does not exist, fallback to Spigot behavior + } catch (Exception e) { + e.printStackTrace(); // Handle other exceptions (optional) + } + // Fallback for Spigot servers + return CompletableFuture.completedFuture(world.getChunkAt(x, z, gen)); + } /** @@ -462,56 +489,7 @@ public static boolean isChunkGenerated(@NonNull Location loc) { * @return If the chunk is generated or not */ public static boolean isChunkGenerated(@Nonnull World world, int x, int z) { - return PaperLib.isChunkGenerated(world, x, z); - } - - /** - * Get's a BlockState, optionally not using a snapshot - * @param block The block to get a State of - * @param useSnapshot Whether or not to use a snapshot when supported - * @return The BlockState - */ - @NonNull - public static BlockStateSnapshotResult getBlockState(@Nonnull Block block, boolean useSnapshot) { - return PaperLib.getBlockState(block, useSnapshot); - } - - /** - * Detects if the current MC version is at least the following version. - *

- * Assumes 0 patch version. - * - * @param minor Min Minor Version - * @return Meets the version requested - */ - public static boolean isVersion(int minor) { - return PaperLib.isVersion(minor); - } - - /** - * Detects if the current MC version is at least the following version. - * @param minor Min Minor Version - * @param patch Min Patch Version - * @return Meets the version requested - */ - public static boolean isVersion(int minor, int patch) { - return PaperLib.isVersion(minor, patch); - } - - /** - * Gets the current Minecraft Minor version. IE: 1.13.1 returns 13 - * @return The Minor Version - */ - public static int getMinecraftVersion() { - return PaperLib.getMinecraftVersion(); - } - - /** - * Gets the current Minecraft Patch version. IE: 1.13.1 returns 1 - * @return The Patch Version - */ - public static int getMinecraftPatchVersion() { - return PaperLib.getMinecraftPatchVersion(); + return world.isChunkGenerated(x, z); } /** @@ -562,42 +540,26 @@ public static boolean isVersionCompatible(String version, String requiredVersion return !(!isRequiredSnapshot && isVersionSnapshot); } - /** - * Check if the server has access to the Spigot API - * @return True for Spigot and Paper environments - */ - public static boolean isSpigot() { - return PaperLib.isSpigot(); - } - /** * Check if the server has access to the Paper API * @return True for Paper environments */ public static boolean isPaper() { - return !isJUnitTest() && PaperLib.isPaper(); - } - - /** - * I don't like doing this, but otherwise we need to set a flag in every test - */ - private static boolean isJUnitTest() { - StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); - for (StackTraceElement element : stackTrace) { - if (element.getClassName().startsWith("org.junit.")) { - return true; - } + try { + Class.forName("com.destroystokyo.paper.PaperConfig"); + return true; // Paper-specific class exists + } catch (ClassNotFoundException e) { + return false; // Not a Paper server } - return false; } - /** * This method translates color codes in given string and strips whitespace after them. * This code parses both: hex and old color codes. * @param textToColor Text which color codes must be parsed. * @return String text with parsed colors and stripped whitespaces after them. */ + @SuppressWarnings("deprecation") @NonNull public static String translateColorCodes(@NonNull String textToColor) { // Use matcher to find hex patterns in given text. @@ -760,8 +722,14 @@ public static void runCommands(User user, String ownerName, @NonNull List