From 3bb8de6d33f72377453cf85e513ffc1f439397ae Mon Sep 17 00:00:00 2001 From: Ben Woo <30431861+benwoo1110@users.noreply.github.com> Date: Mon, 26 Apr 2021 22:52:24 +0800 Subject: [PATCH] Improve portal search radius. * Fix portal search radius not respected after travel agent removed. * Set portal search radius for entity entering portals. --- .../listeners/MVEntityListener.java | 15 +++ .../listeners/MVPlayerListener.java | 19 +--- .../utils/CompatibilityLayer.java | 94 +++++++++++++++---- 3 files changed, 97 insertions(+), 31 deletions(-) diff --git a/src/main/java/com/onarandombox/MultiverseCore/listeners/MVEntityListener.java b/src/main/java/com/onarandombox/MultiverseCore/listeners/MVEntityListener.java index f99788c1..fd81e694 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/listeners/MVEntityListener.java +++ b/src/main/java/com/onarandombox/MultiverseCore/listeners/MVEntityListener.java @@ -11,6 +11,7 @@ import com.dumptruckman.minecraft.util.Logging; import com.onarandombox.MultiverseCore.MultiverseCore; import com.onarandombox.MultiverseCore.api.MVWorldManager; import com.onarandombox.MultiverseCore.api.MultiverseWorld; +import com.onarandombox.MultiverseCore.utils.CompatibilityLayer; import org.bukkit.World; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; @@ -18,6 +19,7 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; +import org.bukkit.event.entity.EntityPortalEvent; import org.bukkit.event.entity.EntityRegainHealthEvent; import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason; import org.bukkit.event.entity.FoodLevelChangeEvent; @@ -107,4 +109,17 @@ public class MVEntityListener implements Listener { event.setCancelled(this.plugin.getMVWorldManager().getTheWorldPurger().shouldWeKillThisCreature(mvworld, event.getEntity())); } + /** + * Handles portal search radius adjustment. + * @param event The Event that was fired. + */ + @EventHandler + public void entityPortal(EntityPortalEvent event) { + if (event.isCancelled() || event.getTo() == null) { + return; + } + if (!this.plugin.getMVConfig().isUsingDefaultPortalSearch()) { + CompatibilityLayer.setPortalSearchRadius(event, this.plugin.getMVConfig().getPortalSearchRadius()); + } + } } diff --git a/src/main/java/com/onarandombox/MultiverseCore/listeners/MVPlayerListener.java b/src/main/java/com/onarandombox/MultiverseCore/listeners/MVPlayerListener.java index fc92292f..2921f9c5 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/listeners/MVPlayerListener.java +++ b/src/main/java/com/onarandombox/MultiverseCore/listeners/MVPlayerListener.java @@ -7,10 +7,6 @@ package com.onarandombox.MultiverseCore.listeners; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.logging.Level; - import com.dumptruckman.minecraft.util.Logging; import com.onarandombox.MultiverseCore.MultiverseCore; import com.onarandombox.MultiverseCore.api.MVWorldManager; @@ -35,6 +31,9 @@ import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerRespawnEvent; import org.bukkit.event.player.PlayerTeleportEvent; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + /** * Multiverse's {@link Listener} for players. */ @@ -313,16 +312,8 @@ public class MVPlayerListener implements Listener { + "' was allowed to go to '" + event.getTo().getWorld().getName() + "' because enforceaccess is off."); } - if (!plugin.getMVConfig().isUsingDefaultPortalSearch()) { - try { - Class.forName("org.bukkit.TravelAgent"); - if (event.getPortalTravelAgent() != null) { - event.getPortalTravelAgent().setSearchRadius(plugin.getMVConfig().getPortalSearchRadius()); - } - } catch (ClassNotFoundException ignore) { - Logging.fine("TravelAgent not available for PlayerPortalEvent for " + event.getPlayer().getName()); - } - + if (!this.plugin.getMVConfig().isUsingDefaultPortalSearch()) { + CompatibilityLayer.setPortalSearchRadius(event, this.plugin.getMVConfig().getPortalSearchRadius()); } } diff --git a/src/main/java/com/onarandombox/MultiverseCore/utils/CompatibilityLayer.java b/src/main/java/com/onarandombox/MultiverseCore/utils/CompatibilityLayer.java index 4d223cce..2a83a7e2 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/utils/CompatibilityLayer.java +++ b/src/main/java/com/onarandombox/MultiverseCore/utils/CompatibilityLayer.java @@ -1,32 +1,35 @@ package com.onarandombox.MultiverseCore.utils; import com.dumptruckman.minecraft.util.Logging; -import org.bukkit.Bukkit; +import org.bukkit.event.entity.EntityPortalEvent; +import org.bukkit.event.player.PlayerPortalEvent; import org.bukkit.event.player.PlayerRespawnEvent; import java.lang.reflect.Method; /** - * A utility class to enable version specific minecraft features. + * Utility class to enable version specific minecraft features. */ public class CompatibilityLayer { private static Method checkAnchorSpawn; + private static boolean useTravelAgent; + private static Method playerPortalSearchRadius; + private static Method entityPortalSearchRadius; /** - * Initialise the reflection methods. + * Initialise the reflection class, methods and fields. */ public static void init() { - try { - checkAnchorSpawn = PlayerRespawnEvent.class.getDeclaredMethod("isAnchorSpawn"); - } catch (NoSuchMethodException e) { - Logging.fine("%s does not support respawn anchors.", Bukkit.getVersion()); - } + checkAnchorSpawn = ReflectHelper.getMethod(PlayerRespawnEvent.class, "isAnchorSpawn"); + useTravelAgent = ReflectHelper.hasClass("org.bukkit.TravelAgent"); + playerPortalSearchRadius = ReflectHelper.getMethod(PlayerPortalEvent.class, "setSearchRadius", int.class); + entityPortalSearchRadius = ReflectHelper.getMethod(EntityPortalEvent.class, "setSearchRadius", int.class); } /** - * Check if the respawn point is of respawn anchor type. - * Introduced in minecraft 1.16 + *

Check if the respawn point is of respawn anchor type.

+ *

Introduced in minecraft 1.16

* * @param event A player respawn event. * @return If the respawn location is an anchor point. @@ -35,12 +38,69 @@ public class CompatibilityLayer { if (checkAnchorSpawn == null) { return false; } - try { - return (boolean) checkAnchorSpawn.invoke(event); - } catch (Exception e) { - Logging.warning("Error checking for: %s", checkAnchorSpawn); - e.printStackTrace(); + Boolean result = ReflectHelper.invokeMethod(event, checkAnchorSpawn); + if (result == null) { + Logging.warning("Unable to check if spawning at respawn anchor!"); + return false; } - return false; + return result; } -} \ No newline at end of file + + /** + *

Gets if Travel Agent is supported on the server's minecraft version.

+ *

Removed in minecraft 1.14

+ * + * @return True if Travel Agent is supported, else false. + */ + public static boolean isUseTravelAgent() { + return useTravelAgent; + } + + /** + *

Sets search radius for a PlayerPortalEvent.

+ * + *

Use travel agent if available, else using new PlayerPortalEvent.setSearchRadius(int) method + * introduced in minecraft 1.15

+ * + * @param event A Player Portal Event. + * @param searchRadius Target search radius to set to. + */ + public static void setPortalSearchRadius(PlayerPortalEvent event, int searchRadius) { + if (useTravelAgent) { + event.getPortalTravelAgent().setSearchRadius(searchRadius); + event.useTravelAgent(true); + Logging.finer("Used travel agent to set player portal search radius."); + return; + } + if (playerPortalSearchRadius == null) { + Logging.warning("Unable to set player portal search radius!"); + return; + } + ReflectHelper.invokeMethod(event, playerPortalSearchRadius, searchRadius); + Logging.finer("Used new method to set player portal search radius."); + } + + /** + *

Sets search radius for a EntityPortalEvent.

+ * + *

Use travel agent if available, else using new EntityPortalEvent.setSearchRadius(int) method + * introduced in minecraft 1.15

+ * + * @param event A Entity Portal Event. + * @param searchRadius Target search radius to set to. + */ + public static void setPortalSearchRadius(EntityPortalEvent event, int searchRadius) { + if (useTravelAgent) { + event.getPortalTravelAgent().setSearchRadius(searchRadius); + event.useTravelAgent(true); + Logging.finer("Used travel agent to set entity portal search radius."); + return; + } + if (entityPortalSearchRadius == null) { + Logging.warning("Unable to set entity portal search radius!"); + return; + } + ReflectHelper.invokeMethod(event, entityPortalSearchRadius, searchRadius); + Logging.finer("Used new method to set entity portal search radius."); + } +}