Merge pull request #76 from Arim-Minecraft/master

Allow Omitting PlayerMoveEvent
This commit is contained in:
Jitse Boonstra 2020-04-23 07:56:44 +02:00 committed by GitHub
commit 3a997924b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 195 additions and 43 deletions

View File

@ -4,11 +4,14 @@
package net.jitse.npclib;
import net.jitse.npclib.NPCLibOptions.MovementHandling;
import net.jitse.npclib.api.NPC;
import net.jitse.npclib.api.utilities.Logger;
import net.jitse.npclib.listeners.ChunkListener;
import net.jitse.npclib.listeners.PacketListener;
import net.jitse.npclib.listeners.PeriodicMoveListener;
import net.jitse.npclib.listeners.PlayerListener;
import net.jitse.npclib.listeners.PlayerMoveEventListener;
import net.jitse.npclib.metrics.NPCLibMetrics;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
@ -23,7 +26,7 @@ public final class NPCLib {
private double autoHideDistance = 50.0;
public NPCLib(JavaPlugin plugin) {
private NPCLib(JavaPlugin plugin, MovementHandling moveHandling) {
this.plugin = plugin;
this.logger = new Logger("NPCLib");
@ -49,6 +52,12 @@ public final class NPCLib {
pluginManager.registerEvents(new PlayerListener(this), plugin);
pluginManager.registerEvents(new ChunkListener(this), plugin);
if (moveHandling.usePme) {
pluginManager.registerEvents(new PlayerMoveEventListener(), plugin);
} else {
pluginManager.registerEvents(new PeriodicMoveListener(this, moveHandling.updateInterval), plugin);
}
// Boot the according packet listener.
new PacketListener().start(this);
@ -59,6 +68,14 @@ public final class NPCLib {
logger.info("Enabled for Minecraft " + versionName);
}
public NPCLib(JavaPlugin plugin) {
this(plugin, MovementHandling.playerMoveEvent());
}
public NPCLib(JavaPlugin plugin, NPCLibOptions options) {
this(plugin, options.moveHandling);
}
/**
* @return The JavaPlugin instance.
*/

View File

@ -0,0 +1,77 @@
package net.jitse.npclib;
/**
* Mutable preferences for library usage
*
* @author A248
*
*/
public class NPCLibOptions {
MovementHandling moveHandling;
/**
* Creates the default options
*
*/
public NPCLibOptions() {
moveHandling = MovementHandling.playerMoveEvent();
}
/**
* Specifies the motion handling which will be used for the library. <br>
* Programmers may choose between using the PlayerMoveEvent or
* a periodic task. <br>
* <br>
* Note that NPCLib will always use events such as the PlayerTeleportEvent
* and PlayerChangedWorldEvent in addition to the specified option.
*
* @param moveHandling the movement handling
* @return the same NPCLibOptions
*/
public NPCLibOptions setMovementHandling(MovementHandling moveHandling) {
this.moveHandling = moveHandling;
return this;
}
/**
* Options relating to movement handling
*
* @author A248
*
*/
public static class MovementHandling {
final boolean usePme;
final long updateInterval;
private MovementHandling(boolean usePme, long updateInterval) {
this.usePme = usePme;
this.updateInterval = updateInterval;
}
/**
* Gets movement handling using the PlayerMoveEvent
*
* @return movement handling
*/
public static MovementHandling playerMoveEvent() {
return new MovementHandling(false, 0);
}
/**
* Gets movement handling using a periodic update interval in ticks.
*
* @param updateInterval the update interval in ticks
* @return movement handling
*/
public static MovementHandling repeatingTask(long updateInterval) {
if (updateInterval <= 0) {
throw new IllegalArgumentException("Negative update interval");
}
return new MovementHandling(true, updateInterval);
}
}
}

View File

@ -0,0 +1,26 @@
package net.jitse.npclib.listeners;
import org.bukkit.entity.Player;
import net.jitse.npclib.internal.NPCBase;
import net.jitse.npclib.internal.NPCManager;
public class HandleMoveBase {
void handleMove(Player player) {
for (NPCBase npc : NPCManager.getAllNPCs()) {
if (!npc.getShown().contains(player.getUniqueId())) {
continue; // NPC was never supposed to be shown to the player.
}
if (!npc.isShown(player) && npc.inRangeOf(player) && npc.inViewOf(player)) {
// The player is in range and can see the NPC, auto-show it.
npc.show(player, true);
} else if (npc.isShown(player) && !npc.inRangeOf(player)) {
// The player is not in range of the NPC anymore, auto-hide it.
npc.hide(player, true);
}
}
}
}

View File

@ -0,0 +1,48 @@
package net.jitse.npclib.listeners;
import java.util.HashMap;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.scheduler.BukkitTask;
import net.jitse.npclib.NPCLib;
public class PeriodicMoveListener extends HandleMoveBase implements Listener {
private final NPCLib instance;
private final long updateInterval;
private final HashMap<UUID, BukkitTask> tasks = new HashMap<>();
public PeriodicMoveListener(NPCLib instance, long updateInterval) {
this.instance = instance;
this.updateInterval = updateInterval;
}
private void startTask(UUID uuid) {
// purposefully using UUIDs and not holding player references
tasks.put(uuid, Bukkit.getScheduler().runTaskTimer(instance.getPlugin(), () -> {
Player player = Bukkit.getPlayer(uuid);
if (player != null) { // safety check
handleMove(player);
}
}, 1L, updateInterval));
}
@EventHandler
public void onPlayerJoin(PlayerJoinEvent evt) {
startTask(evt.getPlayer().getUniqueId());
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent evt) {
tasks.remove(evt.getPlayer().getUniqueId()).cancel();
}
}

View File

@ -11,7 +11,6 @@ import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.player.*;
@ -20,7 +19,7 @@ import org.bukkit.scheduler.BukkitRunnable;
/**
* @author Jitse Boonstra
*/
public class PlayerListener implements Listener {
public class PlayerListener extends HandleMoveBase implements Listener {
private final NPCLib instance;
@ -30,17 +29,8 @@ public class PlayerListener implements Listener {
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
onPlayerLeave(event.getPlayer());
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
public void onPlayerKick(PlayerKickEvent event) {
onPlayerLeave(event.getPlayer());
}
private void onPlayerLeave(Player player) {
for (NPCBase npc : NPCManager.getAllNPCs())
npc.onLogout(player);
for (NPCBase npc : NPCManager.getAllNPCs())
npc.onLogout(event.getPlayer());
}
@EventHandler
@ -74,7 +64,7 @@ public class PlayerListener implements Listener {
this.cancel();
}
}
}.runTaskTimerAsynchronously(instance.getPlugin(), 0, 1);
}.runTaskTimer(instance.getPlugin(), 0L, 1L);
}
}
@ -91,36 +81,8 @@ public class PlayerListener implements Listener {
}
}
@EventHandler
public void onPlayerMove(PlayerMoveEvent event) {
Location from = event.getFrom();
Location to = event.getTo();
// Only check movement when the player moves from one block to another. The event is called often
// as it is also called when the pitch or yaw change. This is worth it from a performance view.
if (to == null || from.getBlockX() != to.getBlockX()
|| from.getBlockY() != to.getBlockY()
|| from.getBlockZ() != to.getBlockZ())
handleMove(event.getPlayer());
}
@EventHandler
public void onPlayerTeleport(PlayerTeleportEvent event) {
handleMove(event.getPlayer());
}
private void handleMove(Player player) {
for (NPCBase npc : NPCManager.getAllNPCs()) {
if (!npc.getShown().contains(player.getUniqueId())) {
continue; // NPC was never supposed to be shown to the player.
}
if (!npc.isShown(player) && npc.inRangeOf(player) && npc.inViewOf(player)) {
// The player is in range and can see the NPC, auto-show it.
npc.show(player, true);
} else if (npc.isShown(player) && !npc.inRangeOf(player)) {
// The player is not in range of the NPC anymore, auto-hide it.
npc.hide(player, true);
}
}
}
}

View File

@ -0,0 +1,22 @@
package net.jitse.npclib.listeners;
import org.bukkit.Location;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerMoveEvent;
public class PlayerMoveEventListener extends HandleMoveBase implements Listener {
@EventHandler
public void onPlayerMove(PlayerMoveEvent event) {
Location from = event.getFrom();
Location to = event.getTo();
// Only check movement when the player moves from one block to another. The event is called often
// as it is also called when the pitch or yaw change. This is worth it from a performance view.
if (to == null || from.getBlockX() != to.getBlockX()
|| from.getBlockY() != to.getBlockY()
|| from.getBlockZ() != to.getBlockZ())
handleMove(event.getPlayer());
}
}