From 7b155d0b3eaac0f234e0512b28c3b8d254b2a3d9 Mon Sep 17 00:00:00 2001 From: YouHaveTrouble Date: Sat, 2 Mar 2024 00:40:35 +0100 Subject: [PATCH] Add UtilListener to track player interactions with entities The UtilListener class has been added to the project. It provides various event handlers which tag entities (such as ExplosiveMinecart, TNTPrimed, EnderCrystal) with the UUID of the player who either placed, nudged, primed or hit the entity. Changes have also been made to the Target class, adding methods for getting and assigning a player source ID for entities. --- .../preventstabby/PreventStabby.java | 2 + .../preventstabby/data/Target.java | 28 ++++++- .../preventstabby/listeners/UtilListener.java | 76 +++++++++++++++++++ 3 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 src/main/java/me/youhavetrouble/preventstabby/listeners/UtilListener.java diff --git a/src/main/java/me/youhavetrouble/preventstabby/PreventStabby.java b/src/main/java/me/youhavetrouble/preventstabby/PreventStabby.java index f27a037..3aa6acc 100644 --- a/src/main/java/me/youhavetrouble/preventstabby/PreventStabby.java +++ b/src/main/java/me/youhavetrouble/preventstabby/PreventStabby.java @@ -7,6 +7,7 @@ import me.youhavetrouble.preventstabby.hooks.WorldGuardHook; import me.youhavetrouble.preventstabby.data.PlayerListener; import me.youhavetrouble.preventstabby.data.PlayerManager; import me.youhavetrouble.preventstabby.listeners.PlayerDamageListener; +import me.youhavetrouble.preventstabby.listeners.UtilListener; import me.youhavetrouble.preventstabby.util.*; import org.bstats.bukkit.Metrics; import org.bukkit.command.CommandSender; @@ -32,6 +33,7 @@ public final class PreventStabby extends JavaPlugin { playerManager = new PlayerManager(this); // Register listeners TODO + getServer().getPluginManager().registerEvents(new UtilListener(), this); getServer().getPluginManager().registerEvents(new PlayerListener(), this); getServer().getPluginManager().registerEvents(new PlayerDamageListener(this), this); diff --git a/src/main/java/me/youhavetrouble/preventstabby/data/Target.java b/src/main/java/me/youhavetrouble/preventstabby/data/Target.java index 3fedecd..69abaa7 100644 --- a/src/main/java/me/youhavetrouble/preventstabby/data/Target.java +++ b/src/main/java/me/youhavetrouble/preventstabby/data/Target.java @@ -1,9 +1,13 @@ package me.youhavetrouble.preventstabby.data; +import org.bukkit.NamespacedKey; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.entity.Projectile; import org.bukkit.entity.Tameable; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataHolder; +import org.bukkit.persistence.PersistentDataType; import org.jetbrains.annotations.NotNull; import javax.annotation.Nullable; @@ -11,6 +15,8 @@ import java.util.UUID; public class Target { + public static final NamespacedKey playerSourceIdKey = new NamespacedKey("preventstabby", "playerSource"); + /** * The unique identifier for a player. */ @@ -59,7 +65,27 @@ public class Target { } } - return null; + // Try to get player's id from other various entities + PersistentDataContainer pdc = entity.getPersistentDataContainer(); + if (!pdc.has(playerSourceIdKey)) return null; + String id = pdc.get(playerSourceIdKey, PersistentDataType.STRING); + if (id == null) return null; + try { + UUID uuid = UUID.fromString(id); + return new Target(uuid, EntityClassifier.OTHER); + } catch (Exception e) { + return null; + } + + } + + /** + * Assigns the player source ID to the given data holder. + * @param dataHolder The persistent data holder to assign the player source ID to. + * @param id The UUID of the player source ID to assign. + */ + public static void assignPlayerSourceId(@NotNull PersistentDataHolder dataHolder, @NotNull UUID id) { + dataHolder.getPersistentDataContainer().set(playerSourceIdKey, PersistentDataType.STRING, id.toString()); } public enum EntityClassifier { diff --git a/src/main/java/me/youhavetrouble/preventstabby/listeners/UtilListener.java b/src/main/java/me/youhavetrouble/preventstabby/listeners/UtilListener.java new file mode 100644 index 0000000..a23fb46 --- /dev/null +++ b/src/main/java/me/youhavetrouble/preventstabby/listeners/UtilListener.java @@ -0,0 +1,76 @@ +package me.youhavetrouble.preventstabby.listeners; + +import me.youhavetrouble.preventstabby.data.Target; +import org.bukkit.entity.EnderCrystal; +import org.bukkit.entity.Player; +import org.bukkit.entity.Projectile; +import org.bukkit.entity.TNTPrimed; +import org.bukkit.entity.minecart.ExplosiveMinecart; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityPlaceEvent; +import org.bukkit.event.entity.ExplosionPrimeEvent; +import org.bukkit.event.vehicle.VehicleEntityCollisionEvent; + +/** + * This class is a listener that performs various operations related to tagging entities with player UUIDs. + */ +public class UtilListener implements Listener { + + /** + * Tag TNT minecart with uuid of player who placed it + */ + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onPlayerPlacedTntMinecart(EntityPlaceEvent event) { + if (!(event.getEntity() instanceof ExplosiveMinecart minecart)) return; + if (event.getPlayer() == null) return; + Target.assignPlayerSourceId(minecart, event.getPlayer().getUniqueId()); + } + + /** + * Tag TNT minecart with uuid of player who last nudged it + */ + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onPlayerNudgedTntMinecart(VehicleEntityCollisionEvent event) { + if (!(event.getVehicle() instanceof ExplosiveMinecart minecart)) return; + if (!(event.getEntity() instanceof Player player)) return; + Target.assignPlayerSourceId(minecart, player.getUniqueId()); + } + + /** + * Tag primed TNT with players uuid + */ + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onPlayerPrimedTnt(ExplosionPrimeEvent event) { + if (!(event.getEntity() instanceof TNTPrimed tntPrimed)) return; + if (tntPrimed.getSource() instanceof TNTPrimed primingTnt) { + Target primingTntTarget = Target.getTarget(primingTnt); + if (primingTntTarget == null) return; + Target.assignPlayerSourceId(tntPrimed, primingTntTarget.playerUuid); + return; + } + if (tntPrimed.getSource() instanceof Player primingPlayer) { + Target.assignPlayerSourceId(tntPrimed, primingPlayer.getUniqueId()); + return; + } + } + + /** + * Tags ender crystal with exploding players uuid + */ + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onPlayerHitEnderCrystal(EntityDamageByEntityEvent event) { + if (!(event.getEntity() instanceof EnderCrystal enderCrystal)) return; + if (event.getDamager() instanceof Player player) { + Target.assignPlayerSourceId(enderCrystal, player.getUniqueId()); + return; + } + if (event.getDamager() instanceof Projectile projectile && projectile.getShooter() instanceof Player player) { + Target.assignPlayerSourceId(enderCrystal, player.getUniqueId()); + return; + } + } + +}