diff --git a/src/main/java/dev/loki/listener/PlayerInteractListener.java b/src/main/java/dev/loki/listener/PlayerInteractListener.java index 67b1fa5..5b6faf4 100644 --- a/src/main/java/dev/loki/listener/PlayerInteractListener.java +++ b/src/main/java/dev/loki/listener/PlayerInteractListener.java @@ -11,9 +11,9 @@ import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.plugin.Plugin; -import java.util.HashMap; import java.util.Map; import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; import java.util.function.BiConsumer; public class PlayerInteractListener implements Listener { @@ -23,152 +23,77 @@ public class PlayerInteractListener implements Listener { private BiConsumer onGeneratorInteract; private BiConsumer onAttack; private BiConsumer onPalletInteract; - private BiConsumer onWindowInteract; private BiConsumer onRescueAttempt; private BiConsumer onChestInteract; private BiConsumer onHatchInteract; - private final Map lastRightClick = new HashMap<>(); - private final Map lastLeftClick = new HashMap<>(); - private static final long CLICK_COOLDOWN_MS = 200; + private final Map lastClick = new ConcurrentHashMap<>(); + private static final long COOLDOWN_MS = 200; public PlayerInteractListener(Plugin plugin, GameManager gameManager) { this.plugin = plugin; this.gameManager = gameManager; } - public void setOnGeneratorInteract(BiConsumer handler) { - this.onGeneratorInteract = handler; - } - - public void setOnAttack(BiConsumer handler) { - this.onAttack = handler; - } - - public void setOnPalletInteract(BiConsumer handler) { - this.onPalletInteract = handler; - } - - public void setOnWindowInteract(BiConsumer handler) { - this.onWindowInteract = handler; - } - - public void setOnRescueAttempt(BiConsumer handler) { - this.onRescueAttempt = handler; - } - - public void setOnChestInteract(BiConsumer handler) { - this.onChestInteract = handler; - } - - public void setOnHatchInteract(BiConsumer handler) { - this.onHatchInteract = handler; - } + public void setOnGeneratorInteract(BiConsumer h) { this.onGeneratorInteract = h; } + public void setOnAttack(BiConsumer h) { this.onAttack = h; } + public void setOnPalletInteract(BiConsumer h) { this.onPalletInteract = h; } + public void setOnRescueAttempt(BiConsumer h) { this.onRescueAttempt = h; } + public void setOnChestInteract(BiConsumer h) { this.onChestInteract = h; } + public void setOnHatchInteract(BiConsumer h) { this.onHatchInteract = h; } @EventHandler - public void onPlayerInteract(PlayerInteractEvent event) { + public void onInteract(PlayerInteractEvent event) { if (event.getHand() != EquipmentSlot.HAND) return; - Player player = event.getPlayer(); if (!gameManager.isInGame(player.getUniqueId())) return; - - BasePlayer basePlayer = gameManager.getPlayerSession(player.getUniqueId()).getPlayer(player.getUniqueId()); - if (basePlayer == null) return; + BasePlayer bp = gameManager.getPlayerSession(player.getUniqueId()).getPlayer(player.getUniqueId()); + if (bp == null || isIncapacitated(bp)) { event.setCancelled(true); return; } Action action = event.getAction(); - boolean isRightClick = action == Action.RIGHT_CLICK_AIR || action == Action.RIGHT_CLICK_BLOCK; - boolean isLeftClick = action == Action.LEFT_CLICK_AIR || action == Action.LEFT_CLICK_BLOCK; + boolean isRight = action == Action.RIGHT_CLICK_AIR || action == Action.RIGHT_CLICK_BLOCK; - if (basePlayer.getState() == PlayerState.DOWNED || basePlayer.getState() == PlayerState.HOOKED) { - event.setCancelled(true); - return; - } - - if (isRightClick) { - if (isOnCooldown(player.getUniqueId(), lastRightClick)) { - event.setCancelled(true); - return; - } - handleRightClick(event, player, basePlayer); - } else if (isLeftClick) { - if (isOnCooldown(player.getUniqueId(), lastLeftClick)) { - return; - } - handleLeftClick(event, player, basePlayer); - } + if (isOnCooldown(player)) { if (isRight) event.setCancelled(true); return; } + if (isRight) handleRightClick(event, player, bp); + else if (action.isLeftClick()) handleLeftClick(event, player, bp); } - private boolean isOnCooldown(UUID uuid, Map lastClickMap) { + private boolean isIncapacitated(BasePlayer bp) { + return bp.getState() == PlayerState.DOWNED || bp.getState() == PlayerState.HOOKED; + } + + private boolean isOnCooldown(Player player) { long now = System.currentTimeMillis(); - Long last = lastClickMap.get(uuid); - if (last != null && now - last < CLICK_COOLDOWN_MS) { - return true; - } - lastClickMap.put(uuid, now); + Long last = lastClick.get(player.getUniqueId()); + if (last != null && now - last < COOLDOWN_MS) return true; + lastClick.put(player.getUniqueId(), now); return false; } - private void handleRightClick(PlayerInteractEvent event, Player player, BasePlayer basePlayer) { + private void handleRightClick(PlayerInteractEvent event, Player player, BasePlayer bp) { + if (event.getClickedBlock() == null) { + if (onAttack != null && bp.isKiller()) onAttack.accept(player, true); + return; + } + String type = event.getClickedBlock().getType().toString(); + if (type.contains("TRAPDOOR") && onGeneratorInteract != null) onGeneratorInteract.accept(player, event.getAction()); + if ((type.contains("FENCE") || type.contains("PLANKS")) && onPalletInteract != null && !bp.isKiller()) onPalletInteract.accept(player, true); + if (!bp.isKiller() && onRescueAttempt != null) onRescueAttempt.accept(player, true); + if (type.contains("CHEST") && onChestInteract != null) onChestInteract.accept(player, true); + if ((type.contains("HOPPER") || type.contains("PORTAL")) && onHatchInteract != null && !bp.isKiller()) onHatchInteract.accept(player, true); + } + + private void handleLeftClick(PlayerInteractEvent event, Player player, BasePlayer bp) { if (event.getClickedBlock() != null) { - String blockType = event.getClickedBlock().getType().toString(); - - if (blockType.contains("IRON_TRAPDOOR") || blockType.contains("TRAP_DOOR")) { - if (onGeneratorInteract != null) { - onGeneratorInteract.accept(player, event.getAction()); - } - } else if (blockType.contains("FENCE") || blockType.contains("OAK_PLANKS")) { - if (onPalletInteract != null && !basePlayer.isKiller()) { - onPalletInteract.accept(player, true); - } - } - - if (!basePlayer.isKiller()) { - if (onRescueAttempt != null) { - onRescueAttempt.accept(player, true); - } - } - - if (blockType.contains("CHEST")) { - if (onChestInteract != null) { - onChestInteract.accept(player, true); - } - } - - if (blockType.contains("HOPPER") || blockType.contains("END_PORTAL_FRAME")) { - if (onHatchInteract != null && !basePlayer.isKiller()) { - onHatchInteract.accept(player, true); - } + String type = event.getClickedBlock().getType().toString(); + if ((type.contains("PLANKS") || type.contains("FENCE")) && onPalletInteract != null && bp.isKiller()) { + event.setCancelled(true); + onPalletInteract.accept(player, false); } } - - if (onAttack != null && basePlayer.isKiller()) { - onAttack.accept(player, true); - } + if (onAttack != null && bp.isKiller()) { event.setCancelled(true); onAttack.accept(player, false); } } - private void handleLeftClick(PlayerInteractEvent event, Player player, BasePlayer basePlayer) { - if (event.getClickedBlock() != null) { - String blockType = event.getClickedBlock().getType().toString(); - - if (blockType.contains("OAK_PLANKS") || blockType.contains("FENCE")) { - if (onPalletInteract != null && basePlayer.isKiller()) { - event.setCancelled(true); - onPalletInteract.accept(player, false); - } - } - } - - if (onAttack != null && basePlayer.isKiller()) { - event.setCancelled(true); - onAttack.accept(player, false); - } - } - - public void register() { - org.bukkit.Bukkit.getPluginManager().registerEvents(this, plugin); - } - - public void unregister() { - org.bukkit.event.HandlerList.unregisterAll(this); - } + public void register() { org.bukkit.Bukkit.getPluginManager().registerEvents(this, plugin); } + public void unregister() { org.bukkit.event.HandlerList.unregisterAll(this); } } diff --git a/src/main/java/dev/loki/listener/PlayerMoveListener.java b/src/main/java/dev/loki/listener/PlayerMoveListener.java index 002e3d4..ced92b6 100644 --- a/src/main/java/dev/loki/listener/PlayerMoveListener.java +++ b/src/main/java/dev/loki/listener/PlayerMoveListener.java @@ -5,7 +5,6 @@ import dev.loki.player.BasePlayer; import dev.loki.player.Killer; import dev.loki.player.PlayerState; import dev.loki.player.Survivor; -import dev.loki.util.PlayerUtil; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -15,9 +14,9 @@ import org.bukkit.event.player.PlayerToggleSneakEvent; import org.bukkit.event.player.PlayerToggleSprintEvent; import org.bukkit.plugin.Plugin; -import java.util.HashMap; import java.util.Map; import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; import java.util.function.BiConsumer; public class PlayerMoveListener implements Listener { @@ -30,167 +29,76 @@ public class PlayerMoveListener implements Listener { private BiConsumer onSurvivorMove; private BiConsumer onKillerMove; - private final Map lastLocations = new HashMap<>(); - private final Map wasSneaking = new HashMap<>(); - private final Map wasSprinting = new HashMap<>(); - - private static final double MOVEMENT_THRESHOLD = 0.01; + private final Map wasSneaking = new ConcurrentHashMap<>(); + private final Map wasSprinting = new ConcurrentHashMap<>(); private int tickCounter = 0; - private static final int CHECK_INTERVAL = 2; public PlayerMoveListener(Plugin plugin, GameManager gameManager) { this.plugin = plugin; this.gameManager = gameManager; } - public void setOnMovement(BiConsumer handler) { - this.onMovement = handler; - } - - public void setOnCrouch(BiConsumer handler) { - this.onCrouch = handler; - } - - public void setOnSprint(BiConsumer handler) { - this.onSprint = handler; - } - - public void setOnSurvivorMove(BiConsumer handler) { - this.onSurvivorMove = handler; - } - - public void setOnKillerMove(BiConsumer handler) { - this.onKillerMove = handler; - } + public void setOnMovement(BiConsumer h) { this.onMovement = h; } + public void setOnCrouch(BiConsumer h) { this.onCrouch = h; } + public void setOnSprint(BiConsumer h) { this.onSprint = h; } + public void setOnSurvivorMove(BiConsumer h) { this.onSurvivorMove = h; } + public void setOnKillerMove(BiConsumer h) { this.onKillerMove = h; } @EventHandler - public void onPlayerMove(PlayerMoveEvent event) { + public void onMove(PlayerMoveEvent event) { tickCounter++; - if (tickCounter % CHECK_INTERVAL != 0) return; - + if (tickCounter % 2 != 0) return; Player player = event.getPlayer(); if (!gameManager.isInGame(player.getUniqueId())) return; - - BasePlayer basePlayer = gameManager.getPlayerSession(player.getUniqueId()).getPlayer(player.getUniqueId()); - if (basePlayer == null) return; - - Location from = event.getFrom(); + BasePlayer bp = gameManager.getPlayerSession(player.getUniqueId()).getPlayer(player.getUniqueId()); + if (bp == null) return; Location to = event.getTo(); - if (to == null) return; - - if (shouldCancelMovement(basePlayer, from, to)) { - event.setCancelled(true); - return; - } - - if (hasSignificantMovement(from, to)) { - handleMovement(player, basePlayer, to); - } - - updateStateTracking(player.getUniqueId(), from); + if (shouldCancel(bp, to, event.getFrom())) { event.setCancelled(true); return; } + handleMovement(player, bp, to); } - @EventHandler - public void onPlayerToggleSneak(PlayerToggleSneakEvent event) { - Player player = event.getPlayer(); - if (!gameManager.isInGame(player.getUniqueId())) return; - - boolean isSneaking = event.isSneaking(); - UUID uuid = player.getUniqueId(); - - Boolean previous = wasSneaking.get(uuid); - if (previous == null || previous != isSneaking) { - wasSneaking.put(uuid, isSneaking); - - if (onCrouch != null) { - onCrouch.accept(player, isSneaking); - } + private boolean shouldCancel(BasePlayer bp, Location to, Location from) { + if (bp.getState() == PlayerState.HOOKED) return true; + if (bp.getState() == PlayerState.DOWNED) { + double dist = Math.sqrt(Math.pow(to.getX() - from.getX(), 2) + Math.pow(to.getZ() - from.getZ(), 2)); + return dist > 0.08; } - } - - @EventHandler - public void onPlayerToggleSprint(PlayerToggleSprintEvent event) { - Player player = event.getPlayer(); - if (!gameManager.isInGame(player.getUniqueId())) return; - - BasePlayer basePlayer = gameManager.getPlayerSession(player.getUniqueId()).getPlayer(player.getUniqueId()); - if (basePlayer == null) return; - - boolean isSprinting = event.isSprinting(); - UUID uuid = player.getUniqueId(); - - if (basePlayer.getState() == PlayerState.DOWNED || basePlayer.getState() == PlayerState.HOOKED) { - if (isSprinting) { - event.setCancelled(true); - player.setSprinting(false); - } - return; - } - - Boolean previous = wasSprinting.get(uuid); - if (previous == null || previous != isSprinting) { - wasSprinting.put(uuid, isSprinting); - - if (onSprint != null) { - onSprint.accept(player, isSprinting); - } - } - } - - private boolean shouldCancelMovement(BasePlayer player, Location from, Location to) { - if (player.getState() == PlayerState.HOOKED) { - return true; - } - - if (player.getState() == PlayerState.DOWNED) { - double dx = to.getX() - from.getX(); - double dz = to.getZ() - from.getZ(); - double horizontalDistance = Math.sqrt(dx * dx + dz * dz); - - double maxCrawlDistance = 0.08; - return horizontalDistance > maxCrawlDistance; - } - return false; } - private boolean hasSignificantMovement(Location from, Location to) { - double dx = to.getX() - from.getX(); - double dy = to.getY() - from.getY(); - double dz = to.getZ() - from.getZ(); - double distance = Math.sqrt(dx * dx + dy * dy + dz * dz); - - return distance > MOVEMENT_THRESHOLD; + private void handleMovement(Player player, BasePlayer bp, Location to) { + if (onMovement != null) onMovement.accept(player, to); + if (!bp.isKiller() && onSurvivorMove != null) onSurvivorMove.accept((Survivor) bp, to); + else if (bp.isKiller() && onKillerMove != null) onKillerMove.accept((Killer) bp, to); } - private void handleMovement(Player player, BasePlayer basePlayer, Location to) { - if (onMovement != null) { - onMovement.accept(player, to); - } - - if (!basePlayer.isKiller() && onSurvivorMove != null) { - onSurvivorMove.accept((Survivor) basePlayer, to); - } else if (basePlayer.isKiller() && onKillerMove != null) { - onKillerMove.accept((Killer) basePlayer, to); - } + @EventHandler + public void onSneak(PlayerToggleSneakEvent event) { + Player player = event.getPlayer(); + if (!gameManager.isInGame(player.getUniqueId())) return; + boolean now = event.isSneaking(); + Boolean before = wasSneaking.put(player.getUniqueId(), now); + if ((before == null || before != now) && onCrouch != null) onCrouch.accept(player, now); } - private void updateStateTracking(UUID uuid, Location location) { - lastLocations.put(uuid, location.clone()); + @EventHandler + public void onSprint(PlayerToggleSprintEvent event) { + Player player = event.getPlayer(); + if (!gameManager.isInGame(player.getUniqueId())) return; + BasePlayer bp = gameManager.getPlayerSession(player.getUniqueId()).getPlayer(player.getUniqueId()); + if (bp == null) return; + boolean now = event.isSprinting(); + if (isIncapacitated(bp) && now) { event.setCancelled(true); player.setSprinting(false); return; } + Boolean before = wasSprinting.put(player.getUniqueId(), now); + if ((before == null || before != now) && onSprint != null) onSprint.accept(player, now); } - public void clearTracking(UUID uuid) { - lastLocations.remove(uuid); - wasSneaking.remove(uuid); - wasSprinting.remove(uuid); + private boolean isIncapacitated(BasePlayer bp) { + return bp.getState() == PlayerState.DOWNED || bp.getState() == PlayerState.HOOKED; } - public void register() { - org.bukkit.Bukkit.getPluginManager().registerEvents(this, plugin); - } - - public void unregister() { - org.bukkit.event.HandlerList.unregisterAll(this); - } + public void clear(UUID uuid) { wasSneaking.remove(uuid); wasSprinting.remove(uuid); } + public void register() { org.bukkit.Bukkit.getPluginManager().registerEvents(this, plugin); } + public void unregister() { org.bukkit.event.HandlerList.unregisterAll(this); } }