From 380388ff8d30d3f455beb9e3557739ba62e8e2bd Mon Sep 17 00:00:00 2001 From: Chub74 Date: Thu, 13 Aug 2026 21:02:38 +0200 Subject: [PATCH] Some Changes --- .../mc/civchat2/listeners/KillListener.java | 67 ++-- .../java/net/minelink/ctplus/Settings.java | 10 +- .../ctplus/listener/PlayerListener.java | 46 ++- .../minelink/ctplus/listener/TagListener.java | 13 +- .../minelink/ctplus/task/SafeLogoutTask.java | 298 ++++++++++-------- .../src/main/resources/config.yml | 18 +- .../finale/listeners/CombatTagListener.java | 27 +- .../finale/listeners/PlayerListener.java | 254 +++++++-------- 8 files changed, 420 insertions(+), 313 deletions(-) diff --git a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/listeners/KillListener.java b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/listeners/KillListener.java index 32cd9c2513..0fe760afee 100644 --- a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/listeners/KillListener.java +++ b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/listeners/KillListener.java @@ -1,8 +1,10 @@ package vg.civcraft.mc.civchat2.listeners; import java.util.Optional; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.TextDecoration; import org.bukkit.Bukkit; -import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -42,35 +44,62 @@ public void onPlayerKill(PlayerDeathEvent event) { if (!settingsMan.getSendOwnKills(killer.getUniqueId())) { return; } - String msg; ItemStack item = killer.getInventory().getItemInMainHand(); - String victimFormattedName = String.format("%s%s", ChatColor.ITALIC, victim.getDisplayName()); - String killerFormattedName = String.format("%s%s", ChatColor.ITALIC, killer.getDisplayName()); - + Component killerComponent = Component.text(killer.getDisplayName(), NamedTextColor.DARK_GRAY); + Component victimComponent = Component.text(victim.getDisplayName(), NamedTextColor.DARK_GRAY); + Component verb = Component.text("killed", NamedTextColor.DARK_GRAY); + Component accent = Component.text("> ", NamedTextColor.DARK_GRAY).decorate(TextDecoration.BOLD); + Component killMessage; if (item == null || MaterialUtils.isAir(item.getType())) { - msg = String.format("%s%s %swas killed by %s %sby hand", ChatColor.DARK_GRAY, victimFormattedName, - ChatColor.DARK_GRAY, killerFormattedName, ChatColor.DARK_GRAY); + killMessage = Component.text() + .append(accent) + .append(killerComponent) + .append(Component.space()) + .append(verb) + .append(Component.space()) + .append(victimComponent) + .append(Component.space()) + .append(Component.text("by hand", NamedTextColor.DARK_GRAY)) + .build(); } else { - String itemName = ItemUtils.getItemName(item); - String displayName = ItemUtils.getDisplayName(item); Boolean hasWordBank = Optional.ofNullable(ItemUtils.getItemMeta(item)) .map(r -> r.displayName()) .map(f -> f.children().size() > 0) .orElse(false); + + Component itemName = item.hasItemMeta() && item.getItemMeta().hasDisplayName() + ? item.getItemMeta().displayName() + : Component.translatable(item.getType()); + + String connector; if (!hasWordBank) { - displayName = String.format("with a %s", itemName); + connector = "with"; } else { - String killMessageFormat = settingsMan.getKillMessageFormat(killer.getUniqueId()).simpleDescription; - if (killMessageFormat.isBlank()) { - displayName = String.format("%s%s", killMessageFormat, displayName); - } else { - displayName = String.format("%s %s", killMessageFormat, displayName); - } + connector = settingsMan.getKillMessageFormat(killer.getUniqueId()).simpleDescription; } - msg = String.format("%s%s %swas killed by %s %s%s", ChatColor.DARK_GRAY, victimFormattedName, - ChatColor.DARK_GRAY, killerFormattedName, ChatColor.DARK_GRAY, displayName); + Component itemPhrase; + if (connector.isBlank()) { + itemPhrase = itemName; + } else { + itemPhrase = Component.text(connector + " ") + .append(itemName); + } + itemPhrase = itemPhrase.color(NamedTextColor.DARK_GRAY) + .hoverEvent(item.asHoverEvent()); + + killMessage = Component.text() + .append(accent) + .append(killerComponent) + .append(Component.space()) + .append(verb) + .append(Component.space()) + .append(victimComponent) + .append(Component.space()) + .append(itemPhrase) + .build(); } + Location killLoc = victim.getLocation(); for (Player p : Bukkit.getOnlinePlayers()) { Location loc = p.getLocation(); @@ -87,7 +116,7 @@ public void onPlayerKill(PlayerDeathEvent event) { && dao.isIgnoringPlayer(p.getUniqueId(), killer.getUniqueId())) { continue; } - p.sendMessage(msg); + p.sendMessage(killMessage); } } diff --git a/plugins/combattagplus-paper/src/main/java/net/minelink/ctplus/Settings.java b/plugins/combattagplus-paper/src/main/java/net/minelink/ctplus/Settings.java index 27a64c31a1..8a1be5793a 100644 --- a/plugins/combattagplus-paper/src/main/java/net/minelink/ctplus/Settings.java +++ b/plugins/combattagplus-paper/src/main/java/net/minelink/ctplus/Settings.java @@ -337,14 +337,12 @@ public String getRandomNamePrefix() { return plugin.getConfig().getString("random-name-prefix"); } - public String getKillMessage() { - String message = plugin.getConfig().getString("kill-message", ""); - return ChatColor.translateAlternateColorCodes('&', message); + public List getKillMessages() { + return plugin.getConfig().getStringList("kill-messages"); } - public String getKillMessageItem() { - String message = plugin.getConfig().getString("kill-message-item", ""); - return ChatColor.translateAlternateColorCodes('&', message); + public List getKillMessagesItem() { + return plugin.getConfig().getStringList("kill-messages-item"); } public boolean useBarApi() { diff --git a/plugins/combattagplus-paper/src/main/java/net/minelink/ctplus/listener/PlayerListener.java b/plugins/combattagplus-paper/src/main/java/net/minelink/ctplus/listener/PlayerListener.java index 570eb7dc9c..6b084f76dd 100644 --- a/plugins/combattagplus-paper/src/main/java/net/minelink/ctplus/listener/PlayerListener.java +++ b/plugins/combattagplus-paper/src/main/java/net/minelink/ctplus/listener/PlayerListener.java @@ -1,7 +1,12 @@ package net.minelink.ctplus.listener; +import java.util.List; import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.TextReplacementConfig; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import net.minelink.ctplus.CombatTagPlus; import net.minelink.ctplus.Tag; import net.minelink.ctplus.event.CombatLogEvent; @@ -10,7 +15,6 @@ import net.minelink.ctplus.task.SafeLogoutTask; import net.minelink.ctplus.task.TagUpdateTask; -import org.apache.commons.lang3.text.WordUtils; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.entity.Player; @@ -105,9 +109,9 @@ public void updateTag(PlayerJoinEvent event) { @EventHandler(priority = EventPriority.LOWEST) public void broadcastKill(PlayerDeathEvent event) { // Do nothing if both kill messages are blank - String message = plugin.getSettings().getKillMessage(); - String messageItem = plugin.getSettings().getKillMessageItem(); - if (message.isEmpty() && messageItem.isEmpty()) return; + List messages = plugin.getSettings().getKillMessages(); + List messagesItem = plugin.getSettings().getKillMessagesItem(); + if (messages.isEmpty() && messagesItem.isEmpty()) return; Player player = event.getEntity(); UUID playerId = player.getUniqueId(); @@ -136,18 +140,36 @@ public void broadcastKill(PlayerDeathEvent event) { attacker = tag.getVictimName(); } - // Use item-based kill message? - ItemStack item = p.getItemInHand(); - if (item.getType() != Material.AIR) { - String name = WordUtils.capitalizeFully(item.getType().name().replace("_", " ")); - message = messageItem.replace("{item}", name); + // Determine item name and build hoverable item component + Component itemComponent = null; + ItemStack item = p.getInventory().getItemInMainHand(); + if (item != null && item.getType() != Material.AIR) { + Component itemName = item.hasItemMeta() && item.getItemMeta().hasDisplayName() + ? item.getItemMeta().displayName() + : Component.translatable(item.getType()); + itemComponent = itemName.hoverEvent(item.asHoverEvent()); } - // Insert victim and attacker names into message - message = message.replace("{victim}", victim).replace("{attacker}", attacker); + // Choose a random message from the appropriate pool + String template; + if (itemComponent != null && !messagesItem.isEmpty()) { + template = messagesItem.get(ThreadLocalRandom.current().nextInt(messagesItem.size())); + } else if (!messages.isEmpty()) { + template = messages.get(ThreadLocalRandom.current().nextInt(messages.size())); + } else { + return; + } + + Component killMessage = LegacyComponentSerializer.legacyAmpersand().deserialize(template) + .replaceText(TextReplacementConfig.builder().matchLiteral("{victim}").replacement(Component.text(victim)).build()) + .replaceText(TextReplacementConfig.builder().matchLiteral("{attacker}").replacement(Component.text(attacker)).build()); + + if (itemComponent != null) { + killMessage = killMessage.replaceText(TextReplacementConfig.builder().matchLiteral("{item}").replacement(itemComponent).build()); + } // Broadcast kill message - Bukkit.broadcast(message, "ctplus.notify.kill"); + Bukkit.broadcast(killMessage, "ctplus.notify.kill"); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) diff --git a/plugins/combattagplus-paper/src/main/java/net/minelink/ctplus/listener/TagListener.java b/plugins/combattagplus-paper/src/main/java/net/minelink/ctplus/listener/TagListener.java index 8514749f6e..6f935474f9 100644 --- a/plugins/combattagplus-paper/src/main/java/net/minelink/ctplus/listener/TagListener.java +++ b/plugins/combattagplus-paper/src/main/java/net/minelink/ctplus/listener/TagListener.java @@ -1,10 +1,16 @@ package net.minelink.ctplus.listener; +import java.time.Duration; import java.util.ArrayList; import java.util.Collections; import java.util.EnumSet; import java.util.List; import java.util.Objects; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.TextDecoration; +import net.kyori.adventure.title.Title; import net.minelink.ctplus.CombatTagPlus; import net.minelink.ctplus.Tag; import net.minelink.ctplus.TagManager; @@ -279,9 +285,10 @@ public void cancelLogout(PlayerCombatTagEvent event) { if (!SafeLogoutTask.cancel(player)) return; // Inform player - if (!plugin.getSettings().getLogoutCancelledMessage().isEmpty()) { - player.sendMessage(plugin.getSettings().getLogoutCancelledMessage()); - } + player.showTitle(Title.title( + Component.text("LOGOUT CANCELLED").color(NamedTextColor.DARK_RED).decorate(TextDecoration.BOLD), + Component.text("You were PvP tagged").color(NamedTextColor.RED), + Title.Times.times(Duration.ofMillis(500), Duration.ofSeconds(3), Duration.ofSeconds(1)))); } @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) diff --git a/plugins/combattagplus-paper/src/main/java/net/minelink/ctplus/task/SafeLogoutTask.java b/plugins/combattagplus-paper/src/main/java/net/minelink/ctplus/task/SafeLogoutTask.java index bf6f01bed0..f39f5c53be 100644 --- a/plugins/combattagplus-paper/src/main/java/net/minelink/ctplus/task/SafeLogoutTask.java +++ b/plugins/combattagplus-paper/src/main/java/net/minelink/ctplus/task/SafeLogoutTask.java @@ -1,14 +1,20 @@ package net.minelink.ctplus.task; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.TextDecoration; +import net.kyori.adventure.title.Title; import net.minelink.ctplus.CombatTagPlus; import org.bukkit.Bukkit; import org.bukkit.Location; +import org.bukkit.Sound; import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitScheduler; import org.bukkit.util.NumberConversions; +import java.time.Duration; import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -16,141 +22,161 @@ public final class SafeLogoutTask extends BukkitRunnable { - private final static Map tasks = new HashMap<>(); - - private final CombatTagPlus plugin; - - private final UUID playerId; - - private final Location loc; - - private final long logoutTime; - - private int remainingSeconds = Integer.MAX_VALUE; - - private boolean finished; - - SafeLogoutTask(CombatTagPlus plugin, Player player, long logoutTime) { - this.plugin = plugin; - this.playerId = player.getUniqueId(); - this.loc = player.getLocation(); - this.logoutTime = logoutTime; - } - - private int getRemainingSeconds() { - long currentTime = System.currentTimeMillis(); - return logoutTime > currentTime ? NumberConversions.ceil((logoutTime - currentTime) / 1000D) : 0; - } - - @Override - public void run() { - // Cancel the task if player is no longer online - Player player = plugin.getPlayerCache().getPlayer(playerId); - if (player == null) { - cancel(); - return; - } - - // Cancel the task if player has moved - if (hasMoved(player)) { - if (!plugin.getSettings().getLogoutCancelledMessage().isEmpty()) { - player.sendMessage(plugin.getSettings().getLogoutCancelledMessage()); - } - - cancel(); - return; - } - - // Safely logout the player once timer is up - int remainingSeconds = getRemainingSeconds(); - if (remainingSeconds <= 0) { - finished = true; - plugin.getTagManager().untag(playerId); - - if (!plugin.getSettings().getLogoutSuccessMessage().isEmpty()) { - player.kickPlayer(plugin.getSettings().getLogoutSuccessMessage()); - } - - cancel(); - return; - } - - // Inform player - if (remainingSeconds < this.remainingSeconds) { - String remaining = plugin.getSettings().formatDuration(remainingSeconds); - - if (!plugin.getSettings().getLogoutPendingMessage().isEmpty()) { - player.sendMessage(plugin.getSettings().getLogoutPendingMessage().replace("{remaining}", remaining)); - } - - this.remainingSeconds = remainingSeconds; - } - } - - private boolean hasMoved(Player player) { - Location l = player.getLocation(); - return loc.getWorld() != l.getWorld() || loc.getBlockX() != l.getBlockX() || - loc.getBlockY() != l.getBlockY() || loc.getBlockZ() != l.getBlockZ(); - } - - public static void run(CombatTagPlus plugin, Player player) { - // Do nothing if player already has a task - if (hasTask(player)) return; - - // Calculate logout time - long logoutTime = System.currentTimeMillis() + (plugin.getSettings().getLogoutWaitTime() * 1000); - - // Run the task every few ticks for accuracy - SafeLogoutTask task = new SafeLogoutTask(plugin, player, logoutTime); - task.runTaskTimer(plugin, 0, 5); - - // Cache the task - tasks.put(player.getUniqueId(), task); - } - - public static boolean hasTask(Player player) { - SafeLogoutTask task = tasks.get(player.getUniqueId()); - if (task == null) return false; - - BukkitScheduler s = Bukkit.getScheduler(); - if (s.isQueued(task.getTaskId()) || s.isCurrentlyRunning(task.getTaskId())) { - return true; - } - - tasks.remove(player.getUniqueId()); - return false; - } - - public static boolean isFinished(Player player) { - return hasTask(player) && tasks.get(player.getUniqueId()).finished; - } - - public static boolean cancel(Player player) { - // Do nothing if player has no logout task - if (!hasTask(player)) return false; - - // Cancel logout task - Bukkit.getScheduler().cancelTask(tasks.get(player.getUniqueId()).getTaskId()); - - // Remove task early to prevent exploits - tasks.remove(player.getUniqueId()); - - return true; - } - - public static void purgeFinished() { - Iterator iterator = tasks.values().iterator(); - BukkitScheduler s = Bukkit.getScheduler(); - - // Loop over each task - while (iterator.hasNext()) { - int taskId = iterator.next().getTaskId(); - - // Remove entry if task isn't running anymore - if (!s.isQueued(taskId) && !s.isCurrentlyRunning(taskId)) { - iterator.remove(); - } - } - } + private final static Map tasks = new HashMap<>(); + + private final CombatTagPlus plugin; + + private final UUID playerId; + + private final Location loc; + + private final long logoutTime; + + private int remainingSeconds = Integer.MAX_VALUE; + + private boolean finished; + + SafeLogoutTask(CombatTagPlus plugin, Player player, long logoutTime) { + this.plugin = plugin; + this.playerId = player.getUniqueId(); + this.loc = player.getLocation(); + this.logoutTime = logoutTime; + } + + private int getRemainingSeconds() { + long currentTime = System.currentTimeMillis(); + return logoutTime > currentTime ? NumberConversions.ceil((logoutTime - currentTime) / 1000D) : 0; + } + + @Override + public void run() { + // Cancel the task if player is no longer online + Player player = plugin.getPlayerCache().getPlayer(playerId); + if (player == null) { + cancel(); + return; + } + + // Cancel the task if player has moved + if (hasMoved(player)) { + player.showTitle(Title.title( + Component.text("LOGOUT CANCELLED").color(NamedTextColor.DARK_RED).decorate(TextDecoration.BOLD), + Component.text("You moved or entered PvP").color(NamedTextColor.RED), + Title.Times.times(Duration.ofMillis(500), Duration.ofSeconds(3), Duration.ofSeconds(1)))); + + cancel(); + return; + } + + // Safely logout the player once timer is up + int remainingSeconds = getRemainingSeconds(); + if (remainingSeconds <= 0) { + finished = true; + plugin.getTagManager().untag(playerId); + + if (!plugin.getSettings().getLogoutSuccessMessage().isEmpty()) { + player.kickPlayer(plugin.getSettings().getLogoutSuccessMessage()); + } + + cancel(); + return; + } + + if (remainingSeconds < this.remainingSeconds) { + String remaining = plugin.getSettings().formatDuration(remainingSeconds); + NamedTextColor color; + + if (remainingSeconds <= 3) { + color = NamedTextColor.DARK_RED; + player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_PLING, 1.0f, 1.6f); + } else if (remainingSeconds <= 6) { + color = NamedTextColor.RED; + player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_PLING, 1.0f, 1.2f); + } else { + color = NamedTextColor.GOLD; + player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_BASS, 1.0f, 0.8f); + } + + player.showTitle(Title.title(Component.text("SAFE LOGOUT").color(color).decorate(TextDecoration.BOLD), + Component.text("Logging out in ").color(NamedTextColor.WHITE) + .append(Component.text(remaining).color(color).decorate(TextDecoration.BOLD)) + .append(Component.text("...").color(NamedTextColor.WHITE)), + Title.Times.times(Duration.ofMillis(500), + Duration.ofSeconds(2), + Duration.ofMillis(500) + ))); + + this.remainingSeconds = remainingSeconds; + } + } + + private boolean hasMoved(Player player) { + Location l = player.getLocation(); + return loc.getWorld() != l.getWorld() || loc.getBlockX() != l.getBlockX() || loc.getBlockY() != l.getBlockY() + || loc.getBlockZ() != l.getBlockZ(); + } + + public static void run(CombatTagPlus plugin, Player player) { + // Do nothing if player already has a task + if (hasTask(player)) + return; + + // Calculate logout time + long logoutTime = System.currentTimeMillis() + (plugin.getSettings().getLogoutWaitTime() * 1000); + + // Run the task every few ticks for accuracy + SafeLogoutTask task = new SafeLogoutTask(plugin, player, logoutTime); + task.runTaskTimer(plugin, 0, 5); + + // Cache the task + tasks.put(player.getUniqueId(), task); + } + + public static boolean hasTask(Player player) { + SafeLogoutTask task = tasks.get(player.getUniqueId()); + if (task == null) + return false; + + BukkitScheduler s = Bukkit.getScheduler(); + if (s.isQueued(task.getTaskId()) || s.isCurrentlyRunning(task.getTaskId())) { + return true; + } + + tasks.remove(player.getUniqueId()); + return false; + } + + public static boolean isFinished(Player player) { + return hasTask(player) && tasks.get(player.getUniqueId()).finished; + } + + public static boolean cancel(Player player) { + // Do nothing if player has no logout task + if (!hasTask(player)) + return false; + + // Cancel logout task + Bukkit.getScheduler().cancelTask(tasks.get(player.getUniqueId()).getTaskId()); + + // Remove task early to prevent exploits + tasks.remove(player.getUniqueId()); + + return true; + } + + public static void purgeFinished() { + Iterator iterator = tasks.values().iterator(); + BukkitScheduler s = Bukkit.getScheduler(); + + // Loop over each task + while (iterator.hasNext()) { + int taskId = iterator.next().getTaskId(); + + // Remove entry if task isn't running anymore + if (!s.isQueued(taskId) && !s.isCurrentlyRunning(taskId)) { + iterator.remove(); + } + } + } } diff --git a/plugins/combattagplus-paper/src/main/resources/config.yml b/plugins/combattagplus-paper/src/main/resources/config.yml index ff4ff332d3..77ba494cef 100644 --- a/plugins/combattagplus-paper/src/main/resources/config.yml +++ b/plugins/combattagplus-paper/src/main/resources/config.yml @@ -114,11 +114,19 @@ generate-random-name: true # This is the prefix to use for the random name. 12 characters max. random-name-prefix: PvPLogger -# This message is displayed when a player is killed by another player. Set this to '' to display nothing. -kill-message: '&8&l>> &c{victim} was slain by {attacker}' - -# Same as above, this is displayed when a player is killed by another player with an item in hand. -kill-message-item: '&8&l>> &c{victim} was slain by {attacker} with a {item}' +# This pool of messages is displayed when a player is killed by another player. Set this to [] to display nothing. One is chosen randomly. +kill-messages: + - '&8&l>> &c{victim} was slain by {attacker}' + - '&8&l>> &c{victim} was taken down by {attacker}' + - '&8&l>> &c{victim} got wrecked by {attacker}' + - '&8&l>> &c{victim} was obliterated by {attacker}' + +# This pool of messages is displayed when a player is killed by another player with an item in hand. {item} will be replaced with the item name. One is chosen randomly. +kill-messages-item: + - '&8&l>> &c{victim} was slain by {attacker} with {item}' + - '&8&l>> &c{victim} was taken down by {attacker} using {item}' + - '&8&l>> &c{victim} got wrecked by {attacker} wielding {item}' + - '&8&l>> &c{victim} was obliterated by {attacker} with {item}' # Enables BarAPI integration for displaying a boss bar counting down with the remaining tag time. barapi: true diff --git a/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/listeners/CombatTagListener.java b/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/listeners/CombatTagListener.java index 0c70524b74..3bfe30217a 100644 --- a/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/listeners/CombatTagListener.java +++ b/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/listeners/CombatTagListener.java @@ -1,19 +1,24 @@ package com.github.maxopoly.finale.listeners; +import java.time.Duration; + +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; + import com.github.maxopoly.finale.Finale; + import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.TextColor; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.TextDecoration; +import net.kyori.adventure.title.Title; import net.minelink.ctplus.event.CombatLogEvent; -import net.minelink.ctplus.event.PlayerCombatTagEvent; import net.minelink.ctplus.event.SafeLogoutEvent; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerJoinEvent; public class CombatTagListener implements Listener { - private static final String UNSAFE_LOGOUT_MESSAGE = "You left the game without using /logout, make sure to run /logout to be safe!"; - private final Finale plugin; public CombatTagListener(Finale plugin) { @@ -32,8 +37,14 @@ public void onSafeLogout(SafeLogoutEvent event){ @EventHandler public void onPlayerJoin(PlayerJoinEvent event){ + Player player = event.getPlayer(); if(!plugin.getSettingsManager().getUnsafeLogout(event.getPlayer().getUniqueId())) return; - event.getPlayer().sendMessage(Component.text(UNSAFE_LOGOUT_MESSAGE).color(TextColor.color(255,0,0))); + + player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_BASS, 1.0f, 0.8f); + player.showTitle(Title.title( + Component.text("UNSAFE LOGOUT").color(NamedTextColor.DARK_RED).decorate(TextDecoration.BOLD), + Component.text("You left the game without using /logout").color(NamedTextColor.RED), + Title.Times.times(Duration.ofMillis(500), Duration.ofSeconds(3), Duration.ofSeconds(1)))); } } diff --git a/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/listeners/PlayerListener.java b/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/listeners/PlayerListener.java index a0779dfd21..2c1f24afae 100644 --- a/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/listeners/PlayerListener.java +++ b/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/listeners/PlayerListener.java @@ -2,6 +2,10 @@ import com.github.maxopoly.finale.Finale; import com.github.maxopoly.finale.FinaleManager; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; + import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.attribute.Attribute; @@ -19,129 +23,131 @@ public class PlayerListener implements Listener { - private FinaleManager manager; - - public PlayerListener(FinaleManager manager) { - this.manager = manager; - for (Player p : Bukkit.getOnlinePlayers()) { - if (manager.isAttackSpeedEnabled()) { - fixAttackSpeed(p); - } - if (manager.isRegenHandlerEnabled()) { - // Register login for custom health regen - manager.getPassiveRegenHandler().registerPlayer(p.getUniqueId()); - } - } - } - - @EventHandler - public void damageEntity(EntityDamageEvent e) { - if (!manager.isInvulTicksEnabled()) { - return; - } - if (!(e.getEntity() instanceof LivingEntity)) { - return; - } - LivingEntity victim = (LivingEntity) e.getEntity(); - if (victim.getNoDamageTicks() > 0) { - e.setCancelled(true); - return; - } - // see - // https://bukkit.org/threads/whats-up-with-setnodamageticks.141901/#post-1638021 - Bukkit.getScheduler().scheduleSyncDelayedTask(Finale.getPlugin(), new Runnable() { - - @Override - public void run() { - Integer ticks = manager.getInvulnerableTicks().get(e.getCause()); - if (ticks == null) { - return; - } - victim.setNoDamageTicks(ticks - 1); - } - - }, 1L); - } - - @EventHandler - public void healthRegen(EntityRegainHealthEvent e) { - if (!manager.isRegenHandlerEnabled()) { - return; - } - if (e.getEntityType() != EntityType.PLAYER) { - return; - } - if (e.getRegainReason() == RegainReason.SATIATED - && manager.getPassiveRegenHandler().blockPassiveHealthRegen()) { - // apparently setting to cancelled doesn't prevent the "consumption" of - // satiation. - Player p = (Player) e.getEntity(); - - double maxHealth = p.getAttribute(Attribute.MAX_HEALTH).getValue(); - @SuppressWarnings("resource") - double spigotRegenExhaustion = ((CraftWorld) p - .getWorld()).getHandle().spigotConfig.regenExhaustion; - float newExhaustion = (float) (p.getExhaustion() - e.getAmount() * spigotRegenExhaustion); - - StringBuilder alterHealth = null; - if (manager.isDebug()) { - alterHealth = new StringBuilder("SATIATED: " + p.getName()); - alterHealth.append(":").append(p.getHealth()).append("<").append(maxHealth); - alterHealth.append(":").append(p.getSaturation()).append(":").append(p.getExhaustion()); - alterHealth.append(":").append(p.getFoodLevel()); - } - if (newExhaustion < 0) // not 100% sure this is correct route; intention was restoring what spigot - // takes, but we'll roll with it - newExhaustion = 0; - - p.setExhaustion(newExhaustion); - - if (manager.isDebug()) { - alterHealth.append(" TO ").append(p.getHealth()).append("<").append(p.getMaxHealth()); - alterHealth.append(":").append(p.getSaturation()).append(":").append(p.getExhaustion()); - alterHealth.append(":").append(p.getFoodLevel()); - Finale.getPlugin().getLogger().info(alterHealth.toString()); - } - e.setCancelled(true); - return; - } - if (e.getRegainReason() == RegainReason.EATING && manager.getPassiveRegenHandler().blockFoodHealthRegen()) { - Player p = (Player) e.getEntity(); - double maxHealth = p.getAttribute(Attribute.MAX_HEALTH).getValue(); - if (manager.isDebug()) { - StringBuilder alterHealth = new StringBuilder("EATING:" + p.getName()); - alterHealth.append(":").append(p.getHealth()).append("<").append(maxHealth); - alterHealth.append(":").append(p.getSaturation()).append(":").append(p.getExhaustion()); - alterHealth.append(":").append(p.getFoodLevel()); - Finale.getPlugin().getLogger().info(alterHealth.toString()); - } - e.setCancelled(true); - } - } - - @EventHandler - public void playerLogin(PlayerJoinEvent e) { - if (manager.isAttackSpeedEnabled()) { - fixAttackSpeed(e.getPlayer()); - } - if (manager.isRegenHandlerEnabled()) { - // Register login for custom health regen - manager.getPassiveRegenHandler().registerPlayer(e.getPlayer().getUniqueId()); - } - if (Finale.getPlugin().getCombatTagPlusManager() == null) { - return; - } - if (manager.getCTPOnLogin()) { - Finale.getPlugin().getCombatTagPlusManager().tag(e.getPlayer(), null); - e.getPlayer().sendMessage(ChatColor.RED + "You have been combat tagged on login"); - } - } - - private void fixAttackSpeed(Player p) { - AttributeInstance attr = p.getAttribute(Attribute.ATTACK_SPEED); - if (attr != null) { - attr.setBaseValue(manager.getAttackSpeed()); - } - } + private FinaleManager manager; + + public PlayerListener(FinaleManager manager) { + this.manager = manager; + for (Player p : Bukkit.getOnlinePlayers()) { + if (manager.isAttackSpeedEnabled()) { + fixAttackSpeed(p); + } + if (manager.isRegenHandlerEnabled()) { + // Register login for custom health regen + manager.getPassiveRegenHandler().registerPlayer(p.getUniqueId()); + } + } + } + + @EventHandler + public void damageEntity(EntityDamageEvent e) { + if (!manager.isInvulTicksEnabled()) { + return; + } + if (!(e.getEntity() instanceof LivingEntity)) { + return; + } + LivingEntity victim = (LivingEntity) e.getEntity(); + if (victim.getNoDamageTicks() > 0) { + e.setCancelled(true); + return; + } + // see + // https://bukkit.org/threads/whats-up-with-setnodamageticks.141901/#post-1638021 + Bukkit.getScheduler().scheduleSyncDelayedTask(Finale.getPlugin(), new Runnable() { + + @Override + public void run() { + Integer ticks = manager.getInvulnerableTicks().get(e.getCause()); + if (ticks == null) { + return; + } + victim.setNoDamageTicks(ticks - 1); + } + + }, 1L); + } + + @EventHandler + public void healthRegen(EntityRegainHealthEvent e) { + if (!manager.isRegenHandlerEnabled()) { + return; + } + if (e.getEntityType() != EntityType.PLAYER) { + return; + } + if (e.getRegainReason() == RegainReason.SATIATED + && manager.getPassiveRegenHandler().blockPassiveHealthRegen()) { + // apparently setting to cancelled doesn't prevent the "consumption" of + // satiation. + Player p = (Player) e.getEntity(); + + double maxHealth = p.getAttribute(Attribute.MAX_HEALTH).getValue(); + @SuppressWarnings("resource") + double spigotRegenExhaustion = ((CraftWorld) p.getWorld()).getHandle().spigotConfig.regenExhaustion; + float newExhaustion = (float) (p.getExhaustion() - e.getAmount() * spigotRegenExhaustion); + + StringBuilder alterHealth = null; + if (manager.isDebug()) { + alterHealth = new StringBuilder("SATIATED: " + p.getName()); + alterHealth.append(":").append(p.getHealth()).append("<").append(maxHealth); + alterHealth.append(":").append(p.getSaturation()).append(":").append(p.getExhaustion()); + alterHealth.append(":").append(p.getFoodLevel()); + } + if (newExhaustion < 0) // not 100% sure this is correct route; intention was restoring what spigot + // takes, but we'll roll with it + newExhaustion = 0; + + p.setExhaustion(newExhaustion); + + if (manager.isDebug()) { + alterHealth.append(" TO ").append(p.getHealth()).append("<").append(p.getMaxHealth()); + alterHealth.append(":").append(p.getSaturation()).append(":").append(p.getExhaustion()); + alterHealth.append(":").append(p.getFoodLevel()); + Finale.getPlugin().getLogger().info(alterHealth.toString()); + } + e.setCancelled(true); + return; + } + if (e.getRegainReason() == RegainReason.EATING && manager.getPassiveRegenHandler().blockFoodHealthRegen()) { + Player p = (Player) e.getEntity(); + double maxHealth = p.getAttribute(Attribute.MAX_HEALTH).getValue(); + if (manager.isDebug()) { + StringBuilder alterHealth = new StringBuilder("EATING:" + p.getName()); + alterHealth.append(":").append(p.getHealth()).append("<").append(maxHealth); + alterHealth.append(":").append(p.getSaturation()).append(":").append(p.getExhaustion()); + alterHealth.append(":").append(p.getFoodLevel()); + Finale.getPlugin().getLogger().info(alterHealth.toString()); + } + e.setCancelled(true); + } + } + + @EventHandler + public void playerLogin(PlayerJoinEvent e) { + if (manager.isAttackSpeedEnabled()) { + fixAttackSpeed(e.getPlayer()); + } + if (manager.isRegenHandlerEnabled()) { + // Register login for custom health regen + manager.getPassiveRegenHandler().registerPlayer(e.getPlayer().getUniqueId()); + } + if (Finale.getPlugin().getCombatTagPlusManager() == null) { + return; + } + if (manager.getCTPOnLogin()) { + Finale.getPlugin().getCombatTagPlusManager().tag(e.getPlayer(), null); + e.getPlayer() + .sendActionBar(Component.text().append(Component.text(">> ", NamedTextColor.DARK_GRAY)) + .append(Component.text("You have been combat tagged on login", NamedTextColor.RED)) + .append(Component.text(" <<", NamedTextColor.DARK_GRAY)).build()); + } + } + + private void fixAttackSpeed(Player p) { + AttributeInstance attr = p.getAttribute(Attribute.ATTACK_SPEED); + if (attr != null) { + attr.setBaseValue(manager.getAttackSpeed()); + } + } }