diff --git a/CHANGELOG.md b/CHANGELOG.md index ff7f9ab..cd258cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.1.0 +- Tridents will not be instantly returned when hitting Y=0 +- Fixed players without "bettertridents.savevoid" permissions being able to use the "void-saving" feature anyway + ## 2.0.2 - Fixed tridents disappearing when throwing similar tridents (same durability, etc.) from the offhand diff --git a/pom.xml b/pom.xml index 9626191..0c3d353 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ de.jeff_media BetterTridents BetterTridents - 2.0.2 + 2.1.0 ${project.name} @@ -67,6 +67,10 @@ org.jetbrains de.jeff_media.bettertridents.lib.org.jetbrains + + de.jeff_media.jefflib + de.jeff_media.bettertridents.jefflib + @@ -134,10 +138,16 @@ 1.16.5-R0.1-SNAPSHOT provided + + de.jeff_media + JeffLib + 1.0-SNAPSHOT + compile + de.jeff_media SpigotUpdateChecker - 1.2.1 + 1.2.4 org.bstats diff --git a/src/main/java/de/jeff_media/bettertridents/Main.java b/src/main/java/de/jeff_media/bettertridents/Main.java index df64c5b..d1068a4 100644 --- a/src/main/java/de/jeff_media/bettertridents/Main.java +++ b/src/main/java/de/jeff_media/bettertridents/Main.java @@ -8,7 +8,6 @@ import de.jeff_media.updatechecker.UpdateChecker; import de.jeff_media.updatechecker.UserAgentBuilder; import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; -import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.entity.Trident; import org.bukkit.plugin.java.JavaPlugin; @@ -21,7 +20,6 @@ public class Main extends JavaPlugin { private static Main instance; private final ArrayList tridents = new ArrayList<>(); - public static final Material SAFETY_MATERIAL = Material.BARRIER; public static NamespacedKey LOYALTY_TAG; public static NamespacedKey IMPALING_TAG; public static NamespacedKey OFFHAND_TAG; @@ -42,7 +40,6 @@ public class Main extends JavaPlugin { IMPALING_TAG = new NamespacedKey(this, "impaling"); OFFHAND_TAG = new NamespacedKey(this, "offhand"); reload(); - Bukkit.getPluginManager().registerEvents(new VoidListener(), this); Bukkit.getPluginManager().registerEvents(new DropListener(), this); Bukkit.getPluginManager().registerEvents(new ImpalingListener(), this); Bukkit.getPluginManager().registerEvents(new OffhandListener(), this); @@ -79,10 +76,6 @@ public class Main extends JavaPlugin { tridents.add(trident.getUniqueId()); } - public boolean isLoyal(Trident trident) { - return tridents.contains(trident.getUniqueId()); - } - public void removeLoyal(Trident trident) { tridents.remove(trident.getUniqueId()); } diff --git a/src/main/java/de/jeff_media/bettertridents/commands/ReloadCommand.java b/src/main/java/de/jeff_media/bettertridents/commands/ReloadCommand.java index 68054cc..5ed096f 100644 --- a/src/main/java/de/jeff_media/bettertridents/commands/ReloadCommand.java +++ b/src/main/java/de/jeff_media/bettertridents/commands/ReloadCommand.java @@ -2,11 +2,11 @@ package de.jeff_media.bettertridents.commands; import de.jeff_media.bettertridents.Main; import de.jeff_media.bettertridents.config.Permissions; +import de.jeff_media.jefflib.thirdparty.org.jetbrains.annotations.NotNull; import org.bukkit.ChatColor; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; -import org.jetbrains.annotations.NotNull; public class ReloadCommand implements CommandExecutor { diff --git a/src/main/java/de/jeff_media/bettertridents/listeners/TridentThrowListener.java b/src/main/java/de/jeff_media/bettertridents/listeners/TridentThrowListener.java index 0ae2e58..bdd3a22 100644 --- a/src/main/java/de/jeff_media/bettertridents/listeners/TridentThrowListener.java +++ b/src/main/java/de/jeff_media/bettertridents/listeners/TridentThrowListener.java @@ -1,7 +1,11 @@ package de.jeff_media.bettertridents.listeners; import de.jeff_media.bettertridents.Main; +import de.jeff_media.bettertridents.config.Config; +import de.jeff_media.bettertridents.config.Permissions; +import de.jeff_media.bettertridents.tasks.WatchTrident; import de.jeff_media.bettertridents.utils.EnchantmentUtils; +import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.EntityType; @@ -11,6 +15,7 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.entity.ProjectileLaunchEvent; +import org.bukkit.inventory.ItemStack; import org.bukkit.persistence.PersistentDataType; public class TridentThrowListener implements Listener { @@ -34,11 +39,6 @@ public class TridentThrowListener implements Listener { main.debug("Applying impaling level " + impaling); EnchantmentUtils.registerImpaling((Trident) event.getEntity(), impaling); - // Loyalty - int loyalty = EnchantmentUtils.getLevelFromTrident(player, Enchantment.LOYALTY); - main.debug("Applying loyalty level " + loyalty); - EnchantmentUtils.registerLoyalty((Trident) event.getEntity(), loyalty); - // Offhand if (player.getInventory().getItemInMainHand().getType() == Material.TRIDENT) return; if (player.getInventory().getItemInOffHand().getType() != Material.TRIDENT) return; @@ -46,4 +46,47 @@ public class TridentThrowListener implements Listener { main.debug("This trident was thrown by the offhand."); } + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void applyLoyalty(ProjectileLaunchEvent event) { + main.debug("VoidListener"); + if (event.getEntityType() != EntityType.TRIDENT) { + main.debug("Not a trident"); + return; + } + Trident trident = (Trident) event.getEntity(); + if (!(trident.getShooter() instanceof Player)) { + main.debug("Not shot by player"); + return; + } + Player player = (Player) trident.getShooter(); + if(!player.hasPermission(Permissions.SAVE_VOID)) return; + ItemStack tridentItem = null; + if (player.getInventory().getItemInOffHand() != null) { + if (player.getInventory().getItemInOffHand().getType() == Material.TRIDENT) { + tridentItem = player.getInventory().getItemInOffHand(); + } + } + if (player.getInventory().getItemInMainHand() != null) { + if (player.getInventory().getItemInMainHand().getType() == Material.TRIDENT) { + tridentItem = player.getInventory().getItemInMainHand(); + } + } + if (tridentItem == null) { + main.debug("tridentItem not found"); + return; + } + if (!EnchantmentUtils.hasLoyalty(tridentItem)) { + main.debug("No loyalty"); + return; + } + if(!main.getConfig().getBoolean(Config.VOID_SAVING)) { + main.debug("Void Saving disabled"); + return; + } + main.setLoyal(trident); + main.debug("New task: WatchTrident"); + new WatchTrident(trident).runTaskTimer(main,1,1); + Bukkit.getScheduler().runTaskLater(main,() ->main.removeLoyal(trident),1200); + } + } diff --git a/src/main/java/de/jeff_media/bettertridents/listeners/VoidListener.java b/src/main/java/de/jeff_media/bettertridents/listeners/VoidListener.java index b07730d..e69de29 100644 --- a/src/main/java/de/jeff_media/bettertridents/listeners/VoidListener.java +++ b/src/main/java/de/jeff_media/bettertridents/listeners/VoidListener.java @@ -1,64 +0,0 @@ -package de.jeff_media.bettertridents.listeners; - -import de.jeff_media.bettertridents.Main; -import de.jeff_media.bettertridents.config.Config; -import de.jeff_media.bettertridents.tasks.WatchTrident; -import de.jeff_media.bettertridents.utils.EnchantmentUtils; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.Player; -import org.bukkit.entity.Trident; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.entity.ProjectileLaunchEvent; -import org.bukkit.inventory.ItemStack; - -public class VoidListener implements Listener { - - private final Main main = Main.getInstance(); - - @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) - public void onThrowTrident(ProjectileLaunchEvent event) { - main.debug("VoidListener"); - if (event.getEntityType() != EntityType.TRIDENT) { - main.debug("Not a trident"); - return; - } - Trident trident = (Trident) event.getEntity(); - //if (main.isLoyal(trident)) return; - if (!(trident.getShooter() instanceof Player)) { - main.debug("Not shot by player"); - return; - } - Player player = (Player) trident.getShooter(); - ItemStack tridentItem = null; - if (player.getInventory().getItemInOffHand() != null) { - if (player.getInventory().getItemInOffHand().getType() == Material.TRIDENT) { - tridentItem = player.getInventory().getItemInOffHand(); - } - } - if (player.getInventory().getItemInMainHand() != null) { - if (player.getInventory().getItemInMainHand().getType() == Material.TRIDENT) { - tridentItem = player.getInventory().getItemInMainHand(); - } - } - if (tridentItem == null) { - main.debug("tridentItem not found"); - return; - } - if (!EnchantmentUtils.hasLoyalty(tridentItem)) { - main.debug("No loyalty"); - return; - } - if(!main.getConfig().getBoolean(Config.VOID_SAVING)) { - main.debug("Void Saving disabled"); - return; - } - main.setLoyal(trident); - main.debug("New task: WatchTrident"); - new WatchTrident(trident).runTaskTimer(main,1,1); - Bukkit.getScheduler().runTaskLater(main,() ->main.removeLoyal(trident),1200); - } -} diff --git a/src/main/java/de/jeff_media/bettertridents/tasks/MoveToOffhand.java b/src/main/java/de/jeff_media/bettertridents/tasks/MoveToOffhand.java index beb66d8..69431ca 100644 --- a/src/main/java/de/jeff_media/bettertridents/tasks/MoveToOffhand.java +++ b/src/main/java/de/jeff_media/bettertridents/tasks/MoveToOffhand.java @@ -5,7 +5,6 @@ import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.persistence.PersistentDataType; import org.bukkit.scheduler.BukkitRunnable; public class MoveToOffhand extends BukkitRunnable { diff --git a/src/main/java/de/jeff_media/bettertridents/tasks/RemoveBarrier.java b/src/main/java/de/jeff_media/bettertridents/tasks/RemoveBarrier.java index c29146e..acbba23 100644 --- a/src/main/java/de/jeff_media/bettertridents/tasks/RemoveBarrier.java +++ b/src/main/java/de/jeff_media/bettertridents/tasks/RemoveBarrier.java @@ -24,11 +24,11 @@ public class RemoveBarrier extends BukkitRunnable { ticks++; if(ticks >= MAX_TICKS || (trident.getVelocity().length() > 0 && trident.getLocation().distanceSquared(block.getLocation())>2)) { Bukkit.getScheduler().runTaskLater(Main.getInstance(), () ->{ - if (block.getType() == Main.SAFETY_MATERIAL) { + if (block.getType() == Material.BARRIER) { block.setType(Material.AIR); } cancel(); },20); } } -} +} \ No newline at end of file diff --git a/src/main/java/de/jeff_media/bettertridents/tasks/WatchTrident.java b/src/main/java/de/jeff_media/bettertridents/tasks/WatchTrident.java index 5ddd7b6..2a77677 100644 --- a/src/main/java/de/jeff_media/bettertridents/tasks/WatchTrident.java +++ b/src/main/java/de/jeff_media/bettertridents/tasks/WatchTrident.java @@ -1,14 +1,47 @@ package de.jeff_media.bettertridents.tasks; import de.jeff_media.bettertridents.Main; +import de.jeff_media.jefflib.ReflUtil; import org.bukkit.Location; +import org.bukkit.Material; import org.bukkit.entity.Trident; import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.util.Vector; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + public class WatchTrident extends BukkitRunnable { private static final int MAX_TICKS = 1200; + private static Field damageDealtField; + private static Method getHandleMethod; + + static { + int fieldCount = 0; + try { + final Class entityThrownTridentClass = ReflUtil.getNMSClass("EntityThrownTrident"); + getHandleMethod = ReflUtil.getOBCClass("entity.CraftTrident").getMethod("getHandle"); + for (Field field : entityThrownTridentClass.getDeclaredFields()) { + if (field.getType() == Boolean.TYPE) { + damageDealtField = field; + damageDealtField.setAccessible(true); + fieldCount++; + } + } + } catch (Exception e) { + damageDealtField = null; + getHandleMethod = null; + } + + if (fieldCount == 1) { + Main.getInstance().debug("Tridents will be rescued using reflection (Field: " + damageDealtField.getName() + ")"); + } else { + damageDealtField = null; + Main.getInstance().debug("Tridents will be rescued using the legacy setBlock method"); + } + } + private final Trident trident; private int ticks = 0; @@ -16,29 +49,47 @@ public class WatchTrident extends BukkitRunnable { this.trident = trident; } + private void legacyRescue() { + Location nextLocation = trident.getLocation().add(trident.getVelocity()); + + if (nextLocation.getBlockY() > 1) return; + if (!nextLocation.getBlock().getType().isAir()) return; + + if (nextLocation.getBlockY() < 0) { + nextLocation.setY(0); + trident.teleport(nextLocation.clone().add(0, 1, 0)); + trident.setVelocity(new Vector(0, -1, 0)); + } + + nextLocation.getBlock().setType(Material.BARRIER); + new RemoveBarrier(trident, nextLocation.getBlock()).runTaskTimer(Main.getInstance(), 1, 1); + cancel(); + } + + private void rescue() { + if (trident.getLocation().getY() >= -60) return; + try { + damageDealtField.set(getHandleMethod.invoke(trident), true); + } catch (Exception e) { + e.printStackTrace(); + cancel(); + } + } + @Override public void run() { ticks++; - if(ticks >= MAX_TICKS || trident == null || trident.isDead() || !trident.isValid() || trident.getVelocity().length() == 0) { + if (ticks >= MAX_TICKS || trident == null || trident.isDead() || !trident.isValid() || trident.getVelocity().length() == 0) { cancel(); return; } - Location nextLocation = trident.getLocation().add(trident.getVelocity()); - - if(nextLocation.getBlockY() > 1) return; - if(!nextLocation.getBlock().getType().isAir()) return; - - if(nextLocation.getBlockY() < 0) { - nextLocation.setY(0); - trident.teleport(nextLocation.clone().add(0,1,0)); - trident.setVelocity(new Vector(0,-1,0)); + if (damageDealtField != null) { + rescue(); + } else { + legacyRescue(); } - nextLocation.getBlock().setType(Main.SAFETY_MATERIAL); - Main.getInstance().debug("New Task: RemoveBarrier"); - new RemoveBarrier(trident, nextLocation.getBlock()).runTaskTimer(Main.getInstance(), 1, 1); - cancel(); } } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index af7dcc4..426e6e8 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -11,6 +11,10 @@ # bettertridents.savevoid # Allows to use the "void-saving" feature # Default: true +# +# bettertridents.reload +# Allows to reload the config using "/bettertridents" +# Default: OPs # When enabled, tridents enchanted with loyalty will be returned to the player # instead of vanishing when falling into the void