Improve portal search radius.

* Fix portal search radius not respected after travel agent removed.
* Set portal search radius for entity entering portals.
This commit is contained in:
Ben Woo 2021-04-26 22:52:24 +08:00
parent 29617059b3
commit 3bb8de6d33
3 changed files with 97 additions and 31 deletions

View File

@ -11,6 +11,7 @@ import com.dumptruckman.minecraft.util.Logging;
import com.onarandombox.MultiverseCore.MultiverseCore; import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVWorldManager; import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.api.MultiverseWorld; import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import com.onarandombox.MultiverseCore.utils.CompatibilityLayer;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -18,6 +19,7 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; 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;
import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason; import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason;
import org.bukkit.event.entity.FoodLevelChangeEvent; 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())); 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());
}
}
} }

View File

@ -7,10 +7,6 @@
package com.onarandombox.MultiverseCore.listeners; 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.dumptruckman.minecraft.util.Logging;
import com.onarandombox.MultiverseCore.MultiverseCore; import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVWorldManager; 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.PlayerRespawnEvent;
import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.event.player.PlayerTeleportEvent;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/** /**
* Multiverse's {@link Listener} for players. * Multiverse's {@link Listener} for players.
*/ */
@ -313,16 +312,8 @@ public class MVPlayerListener implements Listener {
+ "' was allowed to go to '" + event.getTo().getWorld().getName() + "' was allowed to go to '" + event.getTo().getWorld().getName()
+ "' because enforceaccess is off."); + "' because enforceaccess is off.");
} }
if (!plugin.getMVConfig().isUsingDefaultPortalSearch()) { if (!this.plugin.getMVConfig().isUsingDefaultPortalSearch()) {
try { CompatibilityLayer.setPortalSearchRadius(event, this.plugin.getMVConfig().getPortalSearchRadius());
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());
}
} }
} }

View File

@ -1,32 +1,35 @@
package com.onarandombox.MultiverseCore.utils; package com.onarandombox.MultiverseCore.utils;
import com.dumptruckman.minecraft.util.Logging; 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 org.bukkit.event.player.PlayerRespawnEvent;
import java.lang.reflect.Method; 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 { public class CompatibilityLayer {
private static Method checkAnchorSpawn; 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() { public static void init() {
try { checkAnchorSpawn = ReflectHelper.getMethod(PlayerRespawnEvent.class, "isAnchorSpawn");
checkAnchorSpawn = PlayerRespawnEvent.class.getDeclaredMethod("isAnchorSpawn"); useTravelAgent = ReflectHelper.hasClass("org.bukkit.TravelAgent");
} catch (NoSuchMethodException e) { playerPortalSearchRadius = ReflectHelper.getMethod(PlayerPortalEvent.class, "setSearchRadius", int.class);
Logging.fine("%s does not support respawn anchors.", Bukkit.getVersion()); entityPortalSearchRadius = ReflectHelper.getMethod(EntityPortalEvent.class, "setSearchRadius", int.class);
}
} }
/** /**
* Check if the respawn point is of respawn anchor type. * <p>Check if the respawn point is of respawn anchor type.</p>
* Introduced in minecraft 1.16 * <p>Introduced in minecraft 1.16</p>
* *
* @param event A player respawn event. * @param event A player respawn event.
* @return If the respawn location is an anchor point. * @return If the respawn location is an anchor point.
@ -35,12 +38,69 @@ public class CompatibilityLayer {
if (checkAnchorSpawn == null) { if (checkAnchorSpawn == null) {
return false; return false;
} }
try { Boolean result = ReflectHelper.invokeMethod(event, checkAnchorSpawn);
return (boolean) checkAnchorSpawn.invoke(event); if (result == null) {
} catch (Exception e) { Logging.warning("Unable to check if spawning at respawn anchor!");
Logging.warning("Error checking for: %s", checkAnchorSpawn); return false;
e.printStackTrace();
} }
return false; return result;
} }
}
/**
* <p>Gets if Travel Agent is supported on the server's minecraft version.</p>
* <p>Removed in minecraft 1.14</p>
*
* @return True if Travel Agent is supported, else false.
*/
public static boolean isUseTravelAgent() {
return useTravelAgent;
}
/**
* <p>Sets search radius for a PlayerPortalEvent.</p>
*
* <p>Use travel agent if available, else using new PlayerPortalEvent.setSearchRadius(int) method
* introduced in minecraft 1.15</p>
*
* @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.");
}
/**
* <p>Sets search radius for a EntityPortalEvent.</p>
*
* <p>Use travel agent if available, else using new EntityPortalEvent.setSearchRadius(int) method
* introduced in minecraft 1.15</p>
*
* @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.");
}
}