From 56de63e89e743aacba4f5ebf9fbce678d8befd47 Mon Sep 17 00:00:00 2001 From: Henry Le Grys Date: Tue, 18 Aug 2026 19:51:51 +0100 Subject: [PATCH 1/2] Prevent un-leashing properly --- .../bestbuds/modules/AntiGriefModule.kt | 52 ++++++++++--------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/src/main/kotlin/ch/offbeatwit/bestbuds/modules/AntiGriefModule.kt b/src/main/kotlin/ch/offbeatwit/bestbuds/modules/AntiGriefModule.kt index 62a4c3b..1746066 100644 --- a/src/main/kotlin/ch/offbeatwit/bestbuds/modules/AntiGriefModule.kt +++ b/src/main/kotlin/ch/offbeatwit/bestbuds/modules/AntiGriefModule.kt @@ -7,10 +7,7 @@ import ch.offbeatwit.bestbuds.util.error import io.papermc.paper.entity.Leashable import io.papermc.paper.event.player.PlayerNameEntityEvent import org.bukkit.block.data.type.Fence -import org.bukkit.entity.AbstractHorse -import org.bukkit.entity.LeashHitch -import org.bukkit.entity.Player -import org.bukkit.entity.Tameable +import org.bukkit.entity.* import org.bukkit.event.EventHandler import org.bukkit.event.EventPriority import org.bukkit.event.Listener @@ -18,6 +15,8 @@ import org.bukkit.event.block.BlockBreakEvent import org.bukkit.event.entity.EntityDamageByEntityEvent import org.bukkit.event.entity.PlayerLeashEntityEvent import org.bukkit.event.player.PlayerInteractEntityEvent +import org.bukkit.event.player.PlayerUnleashEntityEvent +import org.bukkit.util.BoundingBox class AntiGriefModule(ctx: Context) : BestBudsModule(ctx), Listener { fun isAllowed(source: Player, target: Tameable): Boolean { @@ -60,20 +59,28 @@ class AntiGriefModule(ctx: Context) : BestBudsModule(ctx), Listener { @EventHandler fun onLeashed(ev: PlayerLeashEntityEvent) { - val source = ev.player - val target = ev.entity - - if (target is Tameable - && target.isTamed - && !source.isOwnerOf(target) - && !source.hasPermission(Permissions.LEASH_OTHERS) - && !isAllowed(source, target) - ) { + if (checkLeash(ev.player, ev.entity)) { ev.isCancelled = true - source.sendActionBar(error("Can't leash another player's pet!")) + ev.player.sendActionBar(error("Can't leash another player's pet!")) } } + @EventHandler + fun onRemoveLeash(ev: PlayerUnleashEntityEvent) { + if (checkLeash(ev.player, ev.entity)) { + ev.isCancelled = true + ev.player.sendActionBar(error("Can't unleash another player's pet!")) + } + } + + fun checkLeash(source: Player, target: Entity): Boolean { + return (target is Tameable + && target.isTamed + && !source.isOwnerOf(target) + && !source.hasPermission(Permissions.LEASH_OTHERS) + && !isAllowed(source, target)) + } + @EventHandler fun onBreakLeash(ev: BlockBreakEvent) { if (ev.block.blockData !is Fence) return @@ -81,19 +88,14 @@ class AntiGriefModule(ctx: Context) : BestBudsModule(ctx), Listener { val leashHitch = ev.block.location.getNearbyEntitiesByType(LeashHitch::class.java, 1.0) .firstOrNull() ?: return - val source = ev.player - val target = leashHitch.world.getNearbyEntitiesByType(Leashable::class.java, leashHitch.location, 32.0, 32.0) { - it.leashHolder == leashHitch - } + val aabb = BoundingBox.of(leashHitch.boundingBox.center, 32.0, 32.0, 32.0) + val target = leashHitch.world.getNearbyEntities(aabb) { + it is Leashable && it.isLeashed && it.leashHolder == leashHitch + }.firstOrNull() - if (target is Tameable - && target.isTamed - && !source.isOwnerOf(target) - && !source.hasPermission(Permissions.LEASH_OTHERS) - && !isAllowed(source, target) - ) { + if (target != null && checkLeash(ev.player, target)) { ev.isCancelled = true - source.sendActionBar(error("Can't unleash another player's pet!")) + ev.player.sendActionBar(error("Can't unleash another player's pet!")) } } From a0e9e6c3c0dbd15a98850e26fd66483e72e70a4f Mon Sep 17 00:00:00 2001 From: Henry Le Grys Date: Tue, 18 Aug 2026 20:00:57 +0100 Subject: [PATCH 2/2] Require holding a stick to open management dialog --- .../offbeatwit/bestbuds/modules/InteractionModule.kt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/ch/offbeatwit/bestbuds/modules/InteractionModule.kt b/src/main/kotlin/ch/offbeatwit/bestbuds/modules/InteractionModule.kt index 0895db5..792299a 100644 --- a/src/main/kotlin/ch/offbeatwit/bestbuds/modules/InteractionModule.kt +++ b/src/main/kotlin/ch/offbeatwit/bestbuds/modules/InteractionModule.kt @@ -24,15 +24,20 @@ import org.joml.Vector3f import kotlin.time.Duration.Companion.seconds class InteractionModule(ctx: Context) : BestBudsModule(ctx), Listener { + val infoItem = Material.SPYGLASS + val manageItem = Material.STICK + @EventHandler(priority = EventPriority.HIGH) fun onClickPet(ev: PlayerInteractEntityEvent) { if (ev.isCancelled) return if (!ev.player.isSneaking) return val target = ev.rightClicked - val holdingSpyglass = ev.player.inventory.getItem(ev.hand).type == Material.SPYGLASS + val handItem = ev.player.inventory.getItem(ev.hand).type + val holdingManage = handItem == manageItem + val holdingEither = handItem == infoItem || holdingManage - if (target is ChestedHorse && !holdingSpyglass) { + if (target is ChestedHorse && !holdingEither) { // Sneak-clicking usually accesses these mobs' GUI return } @@ -40,7 +45,7 @@ class InteractionModule(ctx: Context) : BestBudsModule(ctx), Listener { if (target is Tameable && target.isTamed) { ev.isCancelled = true - if (ev.player.isOwnerOf(target) && !holdingSpyglass) { + if (ev.player.isOwnerOf(target) && holdingManage) { ev.player.showDialog(InfoDialog(target).get()) } else { ev.player.showPetInfo(target)