From 84f0072b765c682dd8bcbdb7ce1ea0078e4d39d5 Mon Sep 17 00:00:00 2001 From: WhiteProject1 Date: Mon, 9 Mar 2026 18:29:18 +0300 Subject: [PATCH 1/2] :bug: Fix 70+ bugs, add DeathMessage module, fix NMS V1_21_8-11 build Bug fixes (Wave 1-4): - Fix null player checks in 20+ commands (teleport, experience, give, trade, etc.) - Fix == vs .equals() comparisons for player objects in toggle commands - Fix wrong description/message enums in multiple commands - Fix economy NPE (null default economy, min/max swap, wrong reason enum) - Fix null sanction checks in SanctionModule, ZStorageManager, ButtonSanctions - Fix null user checks in autocomplete methods and placeholders - Fix player.isOnline() checks in delayed tasks (night vision) - Fix hologram module null check when NMS class not found - Fix InvseeListener null/offline target player - Add missing onlyPlayers() to CommandScoreboard, CommandTrade, CommandPayToggle - Add null module checks in commands that require modules New features: - DeathMessage module with 25+ purple-themed death cause messages - Per-player death message toggle (/deathmessage command) - Hover details showing death coordinates - Click-to-teleport suggestion on death messages Build fixes: - Fix adventure-text-serializer-ansi dependency resolution for NMS V1_21_8-11 - Add resolution strategy in allprojects for empty version BOM deps --- .../essentials/api/cache/SimpleCache.java | 7 +++ .../essentials/api/commands/Permission.java | 5 ++- .../essentials/api/messages/Message.java | 44 ++++++++++++++++--- .../essentials/api/modules/Module.java | 6 +++ .../maxlego08/essentials/api/user/Option.java | 1 + .../essentials/api/utils/SafeLocation.java | 4 +- build.gradle.kts | 8 ++++ .../buttons/sanction/ButtonSanctions.java | 4 +- .../essentials/commands/CommandLoader.java | 2 + .../essentials/commands/ZCommandManager.java | 12 ++++- .../cooldown/CommandCooldownDelete.java | 1 + .../economy/CommandEconomyGiveRandom.java | 6 ++- .../commands/economy/CommandEconomySet.java | 2 +- .../commands/economy/CommandMoney.java | 2 +- .../commands/commands/economy/CommandPay.java | 6 ++- .../commands/economy/CommandPayToggle.java | 4 +- .../enderchest/CommandEnderChest.java | 2 +- .../CommandEssentialsClearRandomWord.java | 2 +- .../commands/fly/CommandFlyRemove.java | 3 +- .../commands/home/CommandDelHome.java | 2 +- .../commands/home/CommandDelHomeConfirm.java | 1 + .../commands/commands/home/CommandHome.java | 1 + .../commands/commands/items/CommandGive.java | 5 ++- .../commands/items/CommandItemLoreSet.java | 5 --- .../messages/CommandMessageToggle.java | 3 +- .../commands/messages/CommandSocialSpy.java | 3 +- .../commands/sanction/CommandKickAll.java | 2 +- .../scoreboard/CommandScoreboard.java | 1 + .../commands/spawn/CommandFirstSpawn.java | 7 ++- .../commands/commands/spawn/CommandSpawn.java | 2 +- .../commands/step/CommandStepFinish.java | 1 + .../commands/step/CommandStepStart.java | 1 + .../commands/teleport/CommandTeleportAll.java | 8 +++- .../teleport/CommandTeleportBack.java | 8 ++-- .../teleport/CommandTeleportCancel.java | 5 ++- .../commands/teleport/CommandTeleportTo.java | 1 + .../teleport/CommandTeleportToHere.java | 1 + .../commands/commands/utils/CommandCraft.java | 2 +- .../commands/utils/CommandFurnace.java | 6 ++- .../commands/utils/CommandPhantoms.java | 3 +- .../commands/utils/CommandRepairAll.java | 9 ++-- .../commands/commands/utils/CommandSudo.java | 2 + .../commands/utils/CommandVersion.java | 2 +- .../commands/utils/admins/CommandKillAll.java | 11 +++++ .../utils/admins/CommandPowerToolsToggle.java | 3 +- .../commands/utils/blocks/CommandAnvil.java | 2 +- .../utils/blocks/CommandCartographyTable.java | 2 +- .../utils/blocks/CommandEnchanting.java | 2 +- .../utils/blocks/CommandGrindStone.java | 2 +- .../commands/utils/blocks/CommandLoom.java | 2 +- .../utils/blocks/CommandSmithingTable.java | 2 +- .../utils/blocks/CommandStoneCutter.java | 2 +- .../experience/CommandGrantExperience.java | 1 + .../CommandGrantRandomExperience.java | 1 + .../experience/CommandQueryExperience.java | 1 + .../experience/CommandSetExperience.java | 1 + .../experience/CommandTakeExperience.java | 1 + .../commands/warp/CommandDelWarp.java | 2 +- .../commands/commands/weather/CommandSun.java | 2 + .../essentials/listener/InvseeListener.java | 6 ++- .../essentials/listener/PlayerListener.java | 8 +++- .../essentials/module/ZModuleManager.java | 4 ++ .../essentials/module/modules/HomeModule.java | 25 ++++++----- .../module/modules/JoinQuitModule.java | 7 ++- .../module/modules/MailBoxModule.java | 6 ++- .../module/modules/MessageModule.java | 1 + .../module/modules/SanctionModule.java | 41 +++++++++++------ .../module/modules/SpawnModule.java | 3 +- .../module/modules/TeleportationModule.java | 7 ++- .../essentials/module/modules/VoteModule.java | 2 +- .../module/modules/afk/AFKModule.java | 6 ++- .../module/modules/chat/ChatModule.java | 3 +- .../module/modules/economy/EconomyModule.java | 6 ++- .../modules/hologram/HologramModule.java | 29 +++++++++++- .../essentials/storage/ZStorageManager.java | 8 +++- .../fr/maxlego08/essentials/user/ZUser.java | 36 +++++++++++---- .../user/placeholders/UserPlaceholders.java | 11 +++-- 77 files changed, 338 insertions(+), 110 deletions(-) diff --git a/API/src/main/java/fr/maxlego08/essentials/api/cache/SimpleCache.java b/API/src/main/java/fr/maxlego08/essentials/api/cache/SimpleCache.java index 075f1af5..c6fc1660 100644 --- a/API/src/main/java/fr/maxlego08/essentials/api/cache/SimpleCache.java +++ b/API/src/main/java/fr/maxlego08/essentials/api/cache/SimpleCache.java @@ -42,6 +42,13 @@ public V get(K key, Loader loader) { } + /** + * Clears all entries from the cache. + */ + public void clear() { + this.cache.clear(); + } + /** * Functional interface for loading values into the cache. Implementations of this interface * provide a method to load a value, typically involving an operation such as fetching data diff --git a/API/src/main/java/fr/maxlego08/essentials/api/commands/Permission.java b/API/src/main/java/fr/maxlego08/essentials/api/commands/Permission.java index 3bad0956..74675fd9 100644 --- a/API/src/main/java/fr/maxlego08/essentials/api/commands/Permission.java +++ b/API/src/main/java/fr/maxlego08/essentials/api/commands/Permission.java @@ -308,7 +308,10 @@ public enum Permission { ESSENTIALS_STEP_START, ESSENTIALS_STEP_FINISH, ESSENTIALS_ITEMFRAME, - ESSENTIALS_SILENT_DEATH("Allows you to die silently without a death message"); + ESSENTIALS_SILENT_DEATH("Allows you to die silently without a death message"), + ESSENTIALS_DEATH_MESSAGE_TELEPORT("Allows clicking death messages to teleport to death location"), + ESSENTIALS_DEATH_MESSAGE_TOGGLE("Allows toggling death messages visibility"), + ESSENTIALS_DEATH_MESSAGE_TOGGLE_OTHER("Allows toggling death messages for other players"); private final String description; private final String[] args; diff --git a/API/src/main/java/fr/maxlego08/essentials/api/messages/Message.java b/API/src/main/java/fr/maxlego08/essentials/api/messages/Message.java index 0f919e1e..c73a3051 100644 --- a/API/src/main/java/fr/maxlego08/essentials/api/messages/Message.java +++ b/API/src/main/java/fr/maxlego08/essentials/api/messages/Message.java @@ -436,6 +436,9 @@ public enum Message { TELEPORT_DAMAGE("You must not take damage during teleportation."), TELEPORT_ERROR_LOCATION("Unable to teleport you safely."), + TELEPORT_CROSS_SERVER_NOT_SUPPORTED("Cross-server teleportation is not supported on this server."), + TELEPORT_CROSS_SERVER_CONNECTING("Connecting to server &f%server%..."), + TELEPORT_CROSS_SERVER_PLAYER_NOT_FOUND("Player &f%player% was not found on any server."), // RTP Queue System Messages TELEPORT_ALREADY_IN_QUEUE("You are already in the teleportation queue!"), @@ -970,12 +973,41 @@ public enum Message { COMMAND_ITEMFRAME_VISIBLE("Item frame is now visible."), COMMAND_ITEMFRAME_NOT_FOUND("No item frame found. Look at an item frame and try again."), - // Death Messages - DEATH_MESSAGE_GENERIC("#99E0FF%player% &7died."), - DEATH_MESSAGE_PLAYER("#99E0FF%player% &7was slain by #34cfe0%killer% &7using %weapon%&7."), - DEATH_MESSAGE_FISTS("&7fists"), - DEATH_MESSAGE_MOB("#99E0FF%player% &7was killed by &c%mob%&7."), - DEATH_MESSAGE_MYTHIC_MOB("#99E0FF%player% &7was slain by %mob%&7!"), + // Death Message Module + DESCRIPTION_DEATH_MESSAGE("Custom death messages"), + + DEATH_GENERIC("#C084FC☠ #E9D5FF%player% #B794F4died."), + DEATH_BY_PLAYER("#C084FC⚔ #E9D5FF%player% #B794F4was slain by #E9D5FF%killer%#B794F4."), + DEATH_BY_MOB("#C084FC☠ #E9D5FF%player% #B794F4was killed by #E9D5FF%killer%#B794F4."), + DEATH_BY_PROJECTILE("#C084FC🏹 #E9D5FF%player% #B794F4was shot by #E9D5FF%killer%#B794F4."), + DEATH_BY_MOB_EXPLOSION("#C084FC💥 #E9D5FF%player% #B794F4was blown up by #E9D5FF%killer%#B794F4."), + DEATH_BY_FALL("#C084FC⬇ #E9D5FF%player% #B794F4fell from a high place."), + DEATH_BY_FIRE("#C084FC🔥 #E9D5FF%player% #B794F4burned to death."), + DEATH_BY_LAVA("#C084FC🌋 #E9D5FF%player% #B794F4tried to swim in lava."), + DEATH_BY_DROWNING("#C084FC💧 #E9D5FF%player% #B794F4drowned."), + DEATH_BY_EXPLOSION("#C084FC💥 #E9D5FF%player% #B794F4was blown up."), + DEATH_BY_LIGHTNING("#C084FC⚡ #E9D5FF%player% #B794F4was struck by lightning."), + DEATH_BY_SUFFOCATION("#C084FC▓ #E9D5FF%player% #B794F4suffocated in a wall."), + DEATH_BY_STARVATION("#C084FC🍖 #E9D5FF%player% #B794F4starved to death."), + DEATH_BY_POISON("#C084FC☣ #E9D5FF%player% #B794F4was poisoned."), + DEATH_BY_MAGIC("#C084FC✦ #E9D5FF%player% #B794F4was killed by magic."), + DEATH_BY_WITHER("#C084FC💀 #E9D5FF%player% #B794F4withered away."), + DEATH_BY_FALLING_BLOCK("#C084FC▼ #E9D5FF%player% #B794F4was squashed by a falling block."), + DEATH_BY_FLY_INTO_WALL("#C084FC💨 #E9D5FF%player% #B794F4experienced kinetic energy."), + DEATH_BY_VOID("#C084FC✧ #E9D5FF%player% #B794F4fell out of the world."), + DEATH_BY_CACTUS("#C084FC🌵 #E9D5FF%player% #B794F4was pricked to death."), + DEATH_BY_CRAMMING("#C084FC⊞ #E9D5FF%player% #B794F4was squished too much."), + DEATH_BY_FREEZE("#C084FC❄ #E9D5FF%player% #B794F4froze to death."), + DEATH_BY_SONIC_BOOM("#C084FC◈ #E9D5FF%player% #B794F4was obliterated by a sonic boom."), + DEATH_BY_MAGMA("#C084FC♨ #E9D5FF%player% #B794F4discovered that the floor was lava."), + DEATH_BY_THORNS("#C084FC✵ #E9D5FF%player% #B794F4was killed trying to hurt someone."), + DEATH_BY_CAMPFIRE("#C084FC🔥 #E9D5FF%player% #B794F4walked into a campfire."), + + DEATH_HOVER_DETAILS("#D8B4FE☠ Death Location#B794F4:\n#E9D5FF▸ World: #D8B4FE%world%\n#E9D5FF▸ Position: #D8B4FE%x%#E9D5FF, #D8B4FE%y%#E9D5FF, #D8B4FE%z%\n\n#9F7AEA&oClick to teleport"), + + COMMAND_DEATH_MESSAGE_TOGGLE_DISABLE("#C084FC☠ #B794F4Death messages are now #E9D5FFhidden #B794F4for %player%#B794F4."), + COMMAND_DEATH_MESSAGE_TOGGLE_ENABLE("#C084FC☠ #B794F4Death messages are now #E9D5FFvisible #B794F4for %player%#B794F4."), + DESCRIPTION_DEATH_MESSAGE_TOGGLE("Toggle death messages visibility"), ; private EssentialsPlugin plugin; diff --git a/API/src/main/java/fr/maxlego08/essentials/api/modules/Module.java b/API/src/main/java/fr/maxlego08/essentials/api/modules/Module.java index 237b1778..e20bf406 100644 --- a/API/src/main/java/fr/maxlego08/essentials/api/modules/Module.java +++ b/API/src/main/java/fr/maxlego08/essentials/api/modules/Module.java @@ -57,5 +57,11 @@ public interface Module extends Listener { */ boolean isRegisterEvent(); + /** + * Called when the module is being disabled. + */ + default void onDisable() { + } + } diff --git a/API/src/main/java/fr/maxlego08/essentials/api/user/Option.java b/API/src/main/java/fr/maxlego08/essentials/api/user/Option.java index 9d5fedd2..ead46624 100644 --- a/API/src/main/java/fr/maxlego08/essentials/api/user/Option.java +++ b/API/src/main/java/fr/maxlego08/essentials/api/user/Option.java @@ -32,4 +32,5 @@ public enum Option { WORLDEDIT_INVENTORY, WORLDEDIT_BOSSBAR_DISABLE, TELEPORT_REQUEST_DISABLE, + DEATH_MESSAGE_DISABLE, } diff --git a/API/src/main/java/fr/maxlego08/essentials/api/utils/SafeLocation.java b/API/src/main/java/fr/maxlego08/essentials/api/utils/SafeLocation.java index 34d56917..311383dc 100644 --- a/API/src/main/java/fr/maxlego08/essentials/api/utils/SafeLocation.java +++ b/API/src/main/java/fr/maxlego08/essentials/api/utils/SafeLocation.java @@ -78,7 +78,9 @@ public void setPitch(float pitch) { public Location getLocation() { if (this.location == null) { - this.location = new Location(Bukkit.getWorld(this.world), this.x, this.y, this.z, this.yaw, this.pitch); + var bukkitWorld = Bukkit.getWorld(this.world); + if (bukkitWorld == null) return null; + this.location = new Location(bukkitWorld, this.x, this.y, this.z, this.yaw, this.pitch); } return location; } diff --git a/build.gradle.kts b/build.gradle.kts index 7fa15db7..dae2cf8e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -32,6 +32,14 @@ allprojects { maven(url = "https://repo.tcoded.com/releases") } + configurations.all { + resolutionStrategy.eachDependency { + if (requested.group == "net.kyori" && requested.name == "adventure-text-serializer-ansi" && (requested.version.isNullOrBlank() || requested.version == ".")) { + useVersion("4.20.0") + } + } + } + java { withSourcesJar() diff --git a/src/main/java/fr/maxlego08/essentials/buttons/sanction/ButtonSanctions.java b/src/main/java/fr/maxlego08/essentials/buttons/sanction/ButtonSanctions.java index da23ba07..75d329f7 100644 --- a/src/main/java/fr/maxlego08/essentials/buttons/sanction/ButtonSanctions.java +++ b/src/main/java/fr/maxlego08/essentials/buttons/sanction/ButtonSanctions.java @@ -60,8 +60,8 @@ private void displaySanction(int slot, Sanction sanction, Player player, User ta placeholders.register("reason", sanction.getReason()); placeholders.register("duration", TimerBuilder.getStringTime(sanction.getDuration())); placeholders.register("remaining", sanction.isActive() ? TimerBuilder.getStringTime(sanction.getDurationRemaining().toMillis()) : Message.EXPIRED.getMessageAsString()); - placeholders.register("created_at", simpleDateFormat.format(sanction.getCreatedAt())); - placeholders.register("expired_at", simpleDateFormat.format(sanction.getExpiredAt())); + placeholders.register("created_at", sanction.getCreatedAt() != null ? simpleDateFormat.format(sanction.getCreatedAt()) : "N/A"); + placeholders.register("expired_at", sanction.getExpiredAt() != null ? simpleDateFormat.format(sanction.getExpiredAt()) : "N/A"); placeholders.register("sender", sanctionModule.getSanctionBy(sanction.getSenderUniqueId())); inventory.addItem(slot, menuItemStack.build(player, false, placeholders)); diff --git a/src/main/java/fr/maxlego08/essentials/commands/CommandLoader.java b/src/main/java/fr/maxlego08/essentials/commands/CommandLoader.java index 418ce1be..e8937fa8 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/CommandLoader.java +++ b/src/main/java/fr/maxlego08/essentials/commands/CommandLoader.java @@ -12,6 +12,7 @@ import fr.maxlego08.essentials.commands.commands.chat.CommandShowItem; import fr.maxlego08.essentials.commands.commands.clearinventory.ClearInventoryCommand; import fr.maxlego08.essentials.commands.commands.cooldown.CommandCooldown; +import fr.maxlego08.essentials.commands.commands.deathmessage.CommandDeathMessageToggle; import fr.maxlego08.essentials.commands.commands.discord.CommandLink; import fr.maxlego08.essentials.commands.commands.discord.CommandUnLink; import fr.maxlego08.essentials.commands.commands.economy.CommandBalanceTop; @@ -285,6 +286,7 @@ public void loadCommands(CommandManager commandManager) { register("pub", CommandPub.class); register("step", CommandStep.class); register("itemframe", CommandItemFrame.class, "iframe"); + register("deathmessage", CommandDeathMessageToggle.class, "dm", "deathmsg"); for (RegisterCommand registerCommand : this.commands) { try { diff --git a/src/main/java/fr/maxlego08/essentials/commands/ZCommandManager.java b/src/main/java/fr/maxlego08/essentials/commands/ZCommandManager.java index 67f04b87..537561e5 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/ZCommandManager.java +++ b/src/main/java/fr/maxlego08/essentials/commands/ZCommandManager.java @@ -45,7 +45,9 @@ public class ZCommandManager extends ZUtils implements CommandManager { commandMap = (CommandMap) bukkitCommandMap.get(Bukkit.getServer()); constructor = PluginCommand.class.getDeclaredConstructor(String.class, Plugin.class); constructor.setAccessible(true); - } catch (Exception ignored) { + } catch (Exception exception) { + Bukkit.getLogger().severe("[zEssentials] Failed to initialize command map or PluginCommand constructor: " + exception.getMessage()); + exception.printStackTrace(); } } @@ -283,6 +285,11 @@ public void registerCommand(Plugin plugin, String mainCommand, EssentialsCommand } try { + if (constructor == null || commandMap == null) { + this.plugin.getLogger().severe("Cannot register command '" + mainCommand + "': CommandMap or PluginCommand constructor is not initialized!"); + return; + } + PluginCommand command = constructor.newInstance(mainCommand, plugin); command.setExecutor(this); command.setTabCompleter(this); @@ -296,7 +303,7 @@ public void registerCommand(Plugin plugin, String mainCommand, EssentialsCommand commands.add(essentialsCommand); if (!commandMap.register(command.getName(), plugin.getDescription().getName(), command)) { - plugin.getLogger().info("Unable to add the command " + essentialsCommand.getSyntax()); + plugin.getLogger().warning("Unable to add the command /" + mainCommand + " (already registered by another plugin). Use /zessentials:" + mainCommand + " instead."); } if (essentialsCommand.getPermission() != null) { @@ -307,6 +314,7 @@ public void registerCommand(Plugin plugin, String mainCommand, EssentialsCommand Bukkit.getPluginManager().addPermission(new Permission(essentialsCommand.getPermission(), essentialsCommand.getDescription() == null ? "No description" : essentialsCommand.getDescription())); } } catch (Exception exception) { + this.plugin.getLogger().severe("Failed to register command '" + mainCommand + "': " + exception.getMessage()); exception.printStackTrace(); } } diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/cooldown/CommandCooldownDelete.java b/src/main/java/fr/maxlego08/essentials/commands/commands/cooldown/CommandCooldownDelete.java index 5bff408b..85975fdf 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/cooldown/CommandCooldownDelete.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/cooldown/CommandCooldownDelete.java @@ -31,6 +31,7 @@ public CommandCooldownDelete(EssentialsPlugin plugin) { if (offlinePlayer == null) return new ArrayList<>(); User user = plugin.getUser(offlinePlayer.getUniqueId()); + if (user == null) return new ArrayList<>(); return new ArrayList<>(user.getCooldowns().keySet()); } catch (Exception ignored) { diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/economy/CommandEconomyGiveRandom.java b/src/main/java/fr/maxlego08/essentials/commands/commands/economy/CommandEconomyGiveRandom.java index fadda9c2..a34cafbe 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/economy/CommandEconomyGiveRandom.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/economy/CommandEconomyGiveRandom.java @@ -37,8 +37,10 @@ protected CommandResultType perform(EssentialsPlugin plugin) { boolean silent = this.argAsBoolean(4, false); String reason = this.getArgs(6, getMessage(plugin.getEconomyManager().getCommandGiveRandomReason(), "%sender%", sender.getName())); - minAmount = Math.min(minAmount, maxAmount); - maxAmount = Math.max(minAmount, maxAmount); + double correctedMin = Math.min(minAmount, maxAmount); + double correctedMax = Math.max(minAmount, maxAmount); + minAmount = correctedMin; + maxAmount = correctedMax; return give(this.sender, userName, economyName, minAmount + Math.random() * (maxAmount - minAmount), silent, reason); } diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/economy/CommandEconomySet.java b/src/main/java/fr/maxlego08/essentials/commands/commands/economy/CommandEconomySet.java index 3039c50e..5c0f108e 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/economy/CommandEconomySet.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/economy/CommandEconomySet.java @@ -37,7 +37,7 @@ protected CommandResultType perform(EssentialsPlugin plugin) { String userName = this.argAsString(1); double amount = this.argAsDouble(2); boolean silent = this.argAsBoolean(3, false); - String reason = this.getArgs(5, getMessage(plugin.getEconomyManager().getCommandResetReason(), "%sender%", sender.getName())); + String reason = this.getArgs(5, getMessage(plugin.getEconomyManager().getCommandSetReason(), "%sender%", sender.getName())); EconomyManager economyManager = plugin.getEconomyManager(); Optional optional = economyManager.getEconomy(economyName); diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/economy/CommandMoney.java b/src/main/java/fr/maxlego08/essentials/commands/commands/economy/CommandMoney.java index 5ff155e3..55093c1d 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/economy/CommandMoney.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/economy/CommandMoney.java @@ -28,7 +28,7 @@ protected CommandResultType perform(EssentialsPlugin plugin) { EconomyManager economyManager = plugin.getEconomyManager(); String userName = this.argAsString(0, null); - if (userName == null || userName.equalsIgnoreCase(user.getName()) && hasPermission(sender, Permission.ESSENTIALS_MONEY_OTHER)) { + if (userName == null || (userName.equalsIgnoreCase(user.getName()) && !hasPermission(sender, Permission.ESSENTIALS_MONEY_OTHER))) { List arguments = new ArrayList<>(); economyManager.getEconomies().forEach(economy -> { diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/economy/CommandPay.java b/src/main/java/fr/maxlego08/essentials/commands/commands/economy/CommandPay.java index f26d9eb7..6414f1b0 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/economy/CommandPay.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/economy/CommandPay.java @@ -36,7 +36,9 @@ protected CommandResultType perform(EssentialsPlugin plugin) { EconomyManager economyManager = plugin.getEconomyManager(); String userName = this.argAsString(0); String amountAsString = this.argAsString(1); - String economyName = this.argAsString(2, economyManager.getDefaultEconomy().getName()); + Economy defaultEconomy = economyManager.getDefaultEconomy(); + if (defaultEconomy == null) return CommandResultType.DEFAULT; + String economyName = this.argAsString(2, defaultEconomy.getName()); if (amountAsString.contains("-")) { message(sender, Message.COMMAND_PAY_NEGATIVE); @@ -46,7 +48,7 @@ protected CommandResultType perform(EssentialsPlugin plugin) { final String sanitizedString = amountAsString.replaceAll("[^0-9.]", ""); if (sanitizedString.isEmpty()) return CommandResultType.SYNTAX_ERROR; - BigDecimal amount = new BigDecimal(amountAsString.replaceAll("[^0-9.]", "")); + BigDecimal amount = new BigDecimal(sanitizedString); String format = amountAsString.replace(sanitizedString, ""); Optional optional = economyManager.getMultiplication(format); if (optional.isPresent()) { diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/economy/CommandPayToggle.java b/src/main/java/fr/maxlego08/essentials/commands/commands/economy/CommandPayToggle.java index 025dfd69..a28d0c6a 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/economy/CommandPayToggle.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/economy/CommandPayToggle.java @@ -17,6 +17,7 @@ public CommandPayToggle(EssentialsPlugin plugin) { this.setModule(MessageModule.class); this.setPermission(Permission.ESSENTIALS_PAY_TOGGLE); this.setDescription(Message.DESCRIPTION_PAY_TOGGLE); + this.onlyPlayers(); this.addOptionalArg("player"); } @@ -29,10 +30,11 @@ protected CommandResultType perform(EssentialsPlugin plugin) { return CommandResultType.SYNTAX_ERROR; } - if (player == this.player || !hasPermission(sender, Permission.ESSENTIALS_PAY_TOGGLE_OTHER)) { + if (player.equals(this.player) || !hasPermission(sender, Permission.ESSENTIALS_PAY_TOGGLE_OTHER)) { togglePay(player, this.user, sender); } else { User otherUser = getUser(player); + if (otherUser == null) return CommandResultType.SYNTAX_ERROR; togglePay(player, otherUser, sender); } diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/enderchest/CommandEnderChest.java b/src/main/java/fr/maxlego08/essentials/commands/commands/enderchest/CommandEnderChest.java index 9054faa4..7663483f 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/enderchest/CommandEnderChest.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/enderchest/CommandEnderChest.java @@ -11,7 +11,7 @@ public class CommandEnderChest extends VCommand { public CommandEnderChest(EssentialsPlugin plugin) { super(plugin); this.setPermission(Permission.ESSENTIALS_ENDERCHEST); - this.setDescription(Message.DESCRIPTION_DAY); + this.setDescription(Message.DESCRIPTION_ENDERCHEST); this.onlyPlayers(); } diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/essentials/CommandEssentialsClearRandomWord.java b/src/main/java/fr/maxlego08/essentials/commands/commands/essentials/CommandEssentialsClearRandomWord.java index a5500e5b..ec7d5e35 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/essentials/CommandEssentialsClearRandomWord.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/essentials/CommandEssentialsClearRandomWord.java @@ -12,7 +12,7 @@ public CommandEssentialsClearRandomWord(EssentialsPlugin plugin) { super(plugin); this.addSubCommand("clear-random-word"); this.setPermission(Permission.ESSENTIALS_CLEAR_RANDOM_WORD); - this.setDescription(Message.DESCRIPTION_RELOAD); + this.setDescription(Message.DESCRIPTION_CLEAR_RANDOM_WORD); } @Override diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/fly/CommandFlyRemove.java b/src/main/java/fr/maxlego08/essentials/commands/commands/fly/CommandFlyRemove.java index 15e80ec8..f17ed4d9 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/fly/CommandFlyRemove.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/fly/CommandFlyRemove.java @@ -30,7 +30,8 @@ protected CommandResultType perform(EssentialsPlugin plugin) { var user = plugin.getUser(uniqueId); long flySeconds = user == null ? storage.getFlySeconds(uniqueId) : user.getFlySeconds(); if (user == null) { - flySeconds *= seconds; + flySeconds -= seconds; + if (flySeconds < 0) flySeconds = 0; storage.upsertFlySeconds(uniqueId, flySeconds); } else user.removeFlySeconds(seconds); diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/home/CommandDelHome.java b/src/main/java/fr/maxlego08/essentials/commands/commands/home/CommandDelHome.java index ff6bb8c9..9bf088bd 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/home/CommandDelHome.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/home/CommandDelHome.java @@ -23,7 +23,7 @@ public CommandDelHome(EssentialsPlugin plugin) { this.addRequireArg("name", (sender, args) -> { if (sender instanceof Player player) { User user = plugin.getUser(player.getUniqueId()); - return user.getHomes().stream().map(Home::getName).toList(); + if (user != null) return user.getHomes().stream().map(Home::getName).toList(); } return new ArrayList<>(); }); diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/home/CommandDelHomeConfirm.java b/src/main/java/fr/maxlego08/essentials/commands/commands/home/CommandDelHomeConfirm.java index 63cb0996..f5bb0962 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/home/CommandDelHomeConfirm.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/home/CommandDelHomeConfirm.java @@ -23,6 +23,7 @@ public CommandDelHomeConfirm(EssentialsPlugin plugin) { this.addRequireArg("name", (sender, args) -> { if (sender instanceof Player player) { User user = plugin.getUser(player.getUniqueId()); + if (user == null) return new ArrayList<>(); return user.getHomes().stream().map(Home::getName).toList(); } return new ArrayList<>(); diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/home/CommandHome.java b/src/main/java/fr/maxlego08/essentials/commands/commands/home/CommandHome.java index b7305ade..3b4c5e3d 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/home/CommandHome.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/home/CommandHome.java @@ -25,6 +25,7 @@ public CommandHome(EssentialsPlugin plugin) { this.addOptionalArg("name", (sender, args) -> { if (sender instanceof Player player) { User user = plugin.getUser(player.getUniqueId()); + if (user == null) return new ArrayList<>(); return user.getHomes().stream().map(Home::getName).toList(); } return new ArrayList<>(); diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/items/CommandGive.java b/src/main/java/fr/maxlego08/essentials/commands/commands/items/CommandGive.java index 50704037..2517c60a 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/items/CommandGive.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/items/CommandGive.java @@ -22,7 +22,8 @@ public CommandGive(EssentialsPlugin plugin) { this.addRequirePlayerNameArg(); this.addRequireArg("item", (sender, args) -> { List materials = new ArrayList<>(plugin.getMaterials().stream().map(Material::name).map(String::toLowerCase).toList()); - materials.addAll(plugin.getModuleManager().getModule(ItemModule.class).getItemsName()); + var itemModule = plugin.getModuleManager().getModule(ItemModule.class); + if (itemModule != null) materials.addAll(itemModule.getItemsName()); return materials; }); this.addOptionalArg("amount", (sender, args) -> Arrays.asList("1", "64", "full")); @@ -32,10 +33,12 @@ public CommandGive(EssentialsPlugin plugin) { protected CommandResultType perform(EssentialsPlugin plugin) { Player player = this.argAsPlayer(0); + if (player == null) return CommandResultType.SYNTAX_ERROR; String itemName = this.argAsString(1); String amount = this.argAsString(2, "1"); var module = plugin.getModuleManager().getModule(ItemModule.class); + if (module == null) return CommandResultType.DEFAULT; if (amount.equalsIgnoreCase("full")) { module.giveFullInventory(sender, player, itemName); diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/items/CommandItemLoreSet.java b/src/main/java/fr/maxlego08/essentials/commands/commands/items/CommandItemLoreSet.java index 0f4122ba..751a8b7c 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/items/CommandItemLoreSet.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/items/CommandItemLoreSet.java @@ -91,11 +91,6 @@ protected CommandResultType perform(EssentialsPlugin plugin) { List components = itemMeta.hasLore() ? itemMeta.lore() : new ArrayList<>(); if (components == null) components = new ArrayList<>(); - if (components.size() < index) { - message(sender, Message.COMMAND_ITEM_LORE_SET_ERROR, "%line%", index); - return CommandResultType.DEFAULT; - } - PaperComponent paperComponent = (PaperComponent) this.componentMessage; if (components.size() < index) { for (int i = components.size(); i < index; i++) { diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/messages/CommandMessageToggle.java b/src/main/java/fr/maxlego08/essentials/commands/commands/messages/CommandMessageToggle.java index 2e86710f..912f37c5 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/messages/CommandMessageToggle.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/messages/CommandMessageToggle.java @@ -29,10 +29,11 @@ protected CommandResultType perform(EssentialsPlugin plugin) { return CommandResultType.SYNTAX_ERROR; } - if (player == this.player || !hasPermission(sender, Permission.ESSENTIALS_MESSAGE_TOGGLE_OTHER)) { + if (player.equals(this.player) || !hasPermission(sender, Permission.ESSENTIALS_MESSAGE_TOGGLE_OTHER)) { togglePrivateMessage(player, this.user, sender); } else { User otherUser = getUser(player); + if (otherUser == null) return CommandResultType.SYNTAX_ERROR; togglePrivateMessage(player, otherUser, sender); } diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/messages/CommandSocialSpy.java b/src/main/java/fr/maxlego08/essentials/commands/commands/messages/CommandSocialSpy.java index 3fbcbca4..dd348e24 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/messages/CommandSocialSpy.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/messages/CommandSocialSpy.java @@ -29,10 +29,11 @@ protected CommandResultType perform(EssentialsPlugin plugin) { return CommandResultType.SYNTAX_ERROR; } - if (player == this.player) { + if (player.equals(this.player)) { toggleSocialspy(player, this.user, sender); } else { User otherUser = getUser(player); + if (otherUser == null) return CommandResultType.SYNTAX_ERROR; toggleSocialspy(player, otherUser, sender); } diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/sanction/CommandKickAll.java b/src/main/java/fr/maxlego08/essentials/commands/commands/sanction/CommandKickAll.java index ec8edf0d..172ad4cd 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/sanction/CommandKickAll.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/sanction/CommandKickAll.java @@ -28,7 +28,7 @@ protected CommandResultType perform(EssentialsPlugin plugin) { plugin.getEssentialsServer().kickPlayer(player.getUniqueId(), Message.MESSAGE_KICK, "%reason%", reason); } }); - broadcast(Permission.ESSENTIALS_KICK_NOTIFY, Message.COMMAND_KICK_NOTIFY, "%player%", sender.getName(), "%target%", player.getName(), "%reason%", reason); + broadcast(Permission.ESSENTIALS_KICK_NOTIFY, Message.COMMAND_KICK_NOTIFY, "%player%", sender.getName(), "%target%", "all", "%reason%", reason); return CommandResultType.SUCCESS; } diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/scoreboard/CommandScoreboard.java b/src/main/java/fr/maxlego08/essentials/commands/commands/scoreboard/CommandScoreboard.java index d218848e..74818eba 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/scoreboard/CommandScoreboard.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/scoreboard/CommandScoreboard.java @@ -14,6 +14,7 @@ public CommandScoreboard(EssentialsPlugin plugin) { this.setModule(ScoreboardModule.class); this.setPermission(Permission.ESSENTIALS_SCOREBOARD); this.setDescription(Message.DESCRIPTION_SCOREBOARD); + this.onlyPlayers(); } @Override diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/spawn/CommandFirstSpawn.java b/src/main/java/fr/maxlego08/essentials/commands/commands/spawn/CommandFirstSpawn.java index 3d5bbad3..b59eec21 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/spawn/CommandFirstSpawn.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/spawn/CommandFirstSpawn.java @@ -34,8 +34,13 @@ protected CommandResultType perform(EssentialsPlugin plugin) { User user = this.plugin.getUser(player.getUniqueId()); if (user == null) return CommandResultType.SYNTAX_ERROR; // Only if its console + if (ConfigStorage.firstSpawnLocation == null || !ConfigStorage.firstSpawnLocation.isValid()) { + message(sender, Message.COMMAND_SPAWN_FIRST_NOT_DEFINE); + return CommandResultType.DEFAULT; + } + Location location = ConfigStorage.firstSpawnLocation.getLocation(); - if (location == null) { + if (location == null || location.getWorld() == null) { message(sender, Message.COMMAND_SPAWN_FIRST_NOT_DEFINE); return CommandResultType.DEFAULT; } diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/spawn/CommandSpawn.java b/src/main/java/fr/maxlego08/essentials/commands/commands/spawn/CommandSpawn.java index 90c04fb0..089daffe 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/spawn/CommandSpawn.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/spawn/CommandSpawn.java @@ -40,7 +40,7 @@ protected CommandResultType perform(EssentialsPlugin plugin) { } Location location = ConfigStorage.spawnLocation.getLocation(); - if (location == null) { + if (location == null || location.getWorld() == null) { message(sender, Message.COMMAND_SPAWN_NOT_DEFINE); return CommandResultType.DEFAULT; } diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/step/CommandStepFinish.java b/src/main/java/fr/maxlego08/essentials/commands/commands/step/CommandStepFinish.java index 391ef3a4..fbdc3fbb 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/step/CommandStepFinish.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/step/CommandStepFinish.java @@ -23,6 +23,7 @@ public CommandStepFinish(EssentialsPlugin plugin) { protected CommandResultType perform(EssentialsPlugin plugin) { Player player = this.argAsPlayer(0); + if (player == null) return CommandResultType.SYNTAX_ERROR; String stepName = this.argAsString(1); var manager = this.plugin.getStepManager(); diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/step/CommandStepStart.java b/src/main/java/fr/maxlego08/essentials/commands/commands/step/CommandStepStart.java index 180778c5..b22ae36e 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/step/CommandStepStart.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/step/CommandStepStart.java @@ -23,6 +23,7 @@ public CommandStepStart(EssentialsPlugin plugin) { protected CommandResultType perform(EssentialsPlugin plugin) { Player player = this.argAsPlayer(0); + if (player == null) return CommandResultType.SYNTAX_ERROR; String stepName = this.argAsString(1); var manager = this.plugin.getStepManager(); diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/teleport/CommandTeleportAll.java b/src/main/java/fr/maxlego08/essentials/commands/commands/teleport/CommandTeleportAll.java index 0bd1c171..88c330cd 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/teleport/CommandTeleportAll.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/teleport/CommandTeleportAll.java @@ -7,6 +7,7 @@ import fr.maxlego08.essentials.module.modules.TeleportationModule; import fr.maxlego08.essentials.zutils.utils.commands.VCommand; import org.bukkit.Bukkit; +import org.bukkit.Location; public class CommandTeleportAll extends VCommand { @@ -21,7 +22,12 @@ public CommandTeleportAll(EssentialsPlugin plugin) { @Override protected CommandResultType perform(EssentialsPlugin plugin) { - Bukkit.getOnlinePlayers().forEach(player -> player.teleportAsync(this.player.getLocation())); + Location targetLocation = this.player.getLocation(); + if (targetLocation.getWorld() == null) return CommandResultType.SYNTAX_ERROR; + + Bukkit.getOnlinePlayers().stream() + .filter(p -> !p.equals(this.player)) + .forEach(p -> p.teleportAsync(targetLocation)); message(this.sender, Message.COMMAND_TP_ALL); return CommandResultType.SUCCESS; diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/teleport/CommandTeleportBack.java b/src/main/java/fr/maxlego08/essentials/commands/commands/teleport/CommandTeleportBack.java index b3353fb8..24b9766c 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/teleport/CommandTeleportBack.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/teleport/CommandTeleportBack.java @@ -6,6 +6,7 @@ import fr.maxlego08.essentials.api.messages.Message; import fr.maxlego08.essentials.module.modules.TeleportationModule; import fr.maxlego08.essentials.zutils.utils.commands.VCommand; +import org.bukkit.Location; public class CommandTeleportBack extends VCommand { @@ -20,17 +21,18 @@ public CommandTeleportBack(EssentialsPlugin plugin) { @Override protected CommandResultType perform(EssentialsPlugin plugin) { - if (this.user.getLastLocation() == null) { + Location lastLocation = this.user.getLastLocation(); + if (lastLocation == null || lastLocation.getWorld() == null) { message(this.sender, Message.COMMAND_BACK_ERROR); return CommandResultType.DEFAULT; } - if (this.plugin.getConfiguration().getDisableBackWorld().contains(user.getLastLocation().getWorld().getName())) { + if (this.plugin.getConfiguration().getDisableBackWorld().contains(lastLocation.getWorld().getName())) { message(this.sender, Message.COMMAND_BACK_ERROR); return CommandResultType.DEFAULT; } - this.user.teleport(user.getLastLocation()); + this.user.teleport(lastLocation); message(this.sender, Message.COMMAND_BACK); return CommandResultType.SUCCESS; diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/teleport/CommandTeleportCancel.java b/src/main/java/fr/maxlego08/essentials/commands/commands/teleport/CommandTeleportCancel.java index df8196e6..8fbaf1a9 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/teleport/CommandTeleportCancel.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/teleport/CommandTeleportCancel.java @@ -25,7 +25,10 @@ protected CommandResultType perform(EssentialsPlugin plugin) { Player targetPlayer = this.argAsPlayer(0); if (targetPlayer == null) return CommandResultType.SYNTAX_ERROR; - this.user.cancelTeleportRequest(plugin.getStorageManager().getStorage().getUser(targetPlayer.getUniqueId())); + var targetUser = plugin.getStorageManager().getStorage().getUser(targetPlayer.getUniqueId()); + if (targetUser == null) return CommandResultType.SYNTAX_ERROR; + + this.user.cancelTeleportRequest(targetUser); return CommandResultType.SUCCESS; } diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/teleport/CommandTeleportTo.java b/src/main/java/fr/maxlego08/essentials/commands/commands/teleport/CommandTeleportTo.java index 6f5a27bd..04cafcb0 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/teleport/CommandTeleportTo.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/teleport/CommandTeleportTo.java @@ -27,6 +27,7 @@ protected CommandResultType perform(EssentialsPlugin plugin) { if (targetPlayer == null) return CommandResultType.SYNTAX_ERROR; User targetUser = plugin.getStorageManager().getStorage().getUser(targetPlayer.getUniqueId()); + if (targetUser == null) return CommandResultType.SYNTAX_ERROR; if (targetUser.getUniqueId().equals(this.player.getUniqueId())) { message(this.sender, Message.COMMAND_TPA_ERROR_SAME); diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/teleport/CommandTeleportToHere.java b/src/main/java/fr/maxlego08/essentials/commands/commands/teleport/CommandTeleportToHere.java index fac2e0f8..45638c26 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/teleport/CommandTeleportToHere.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/teleport/CommandTeleportToHere.java @@ -27,6 +27,7 @@ protected CommandResultType perform(EssentialsPlugin plugin) { if (targetPlayer == null) return CommandResultType.SYNTAX_ERROR; User targetUser = plugin.getStorageManager().getStorage().getUser(targetPlayer.getUniqueId()); + if (targetUser == null) return CommandResultType.SYNTAX_ERROR; if (targetUser.getUniqueId().equals(this.player.getUniqueId())) { message(this.sender, Message.COMMAND_TPA_ERROR_SAME); diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/CommandCraft.java b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/CommandCraft.java index 72e9708c..7e855b3e 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/CommandCraft.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/CommandCraft.java @@ -17,7 +17,7 @@ public CommandCraft(EssentialsPlugin plugin) { @Override protected CommandResultType perform(EssentialsPlugin plugin) { - this.player.getPlayer().openWorkbench(this.player.getLocation(), true); + this.player.openWorkbench(this.player.getLocation(), true); return CommandResultType.SUCCESS; } diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/CommandFurnace.java b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/CommandFurnace.java index 403f7bc4..8b13cc2e 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/CommandFurnace.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/CommandFurnace.java @@ -24,6 +24,10 @@ public CommandFurnace(EssentialsPlugin plugin) { protected CommandResultType perform(EssentialsPlugin plugin) { ItemStack itemStack = this.player.getInventory().getItemInMainHand(); + if (itemStack.getType().isAir()) { + message(sender, Message.COMMAND_FURNACE_TYPE, "%material%", "AIR"); + return CommandResultType.DEFAULT; + } Material material = itemStack.getType(); Optional optional = this.configuration.getSmeltableMaterials().stream().filter(e -> e.from().equals(material)).findFirst(); if (optional.isEmpty()) { @@ -38,7 +42,7 @@ protected CommandResultType perform(EssentialsPlugin plugin) { Inventory inventory = this.player.getInventory(); int realAmount = count(inventory, material); - if (realAmount < 0) { + if (realAmount <= 0) { message(getPlayer(), Message.COMMAND_FURNACE_ERROR, "%item%", name(material.name())); return CommandResultType.DEFAULT; } diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/CommandPhantoms.java b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/CommandPhantoms.java index c116f7b1..624c89ec 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/CommandPhantoms.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/CommandPhantoms.java @@ -31,10 +31,11 @@ protected CommandResultType perform(EssentialsPlugin plugin) { return CommandResultType.SYNTAX_ERROR; } - if (player == this.player || !hasPermission(sender, Permission.ESSENTIALS_PHANTOMS_OTHER)) { + if (player.equals(this.player) || !hasPermission(sender, Permission.ESSENTIALS_PHANTOMS_OTHER)) { togglePhantoms(player, this.user, sender); } else { User otherUser = getUser(player); + if (otherUser == null) return CommandResultType.SYNTAX_ERROR; togglePhantoms(player, otherUser, sender); } diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/CommandRepairAll.java b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/CommandRepairAll.java index 0c7eabc1..71312259 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/CommandRepairAll.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/CommandRepairAll.java @@ -23,15 +23,14 @@ public CommandRepairAll(EssentialsPlugin plugin) { protected CommandResultType perform(EssentialsPlugin plugin) { Player player = this.argAsPlayer(0, this.player); - - if (!hasPermission(sender, Permission.ESSENTIALS_REPAIR_ALL_OTHER)) { - player = this.player; - } - if (player == null) { return CommandResultType.SYNTAX_ERROR; } + if (player != this.player && !hasPermission(sender, Permission.ESSENTIALS_REPAIR_ALL_OTHER)) { + player = this.player; + } + int amount = 0; for (ItemStack itemStack : player.getInventory().getContents()) { diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/CommandSudo.java b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/CommandSudo.java index f5afed4d..cbc55196 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/CommandSudo.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/CommandSudo.java @@ -25,6 +25,8 @@ public CommandSudo(EssentialsPlugin plugin) { protected CommandResultType perform(EssentialsPlugin plugin) { Player player = this.argAsPlayer(0); + if (player == null) return CommandResultType.SYNTAX_ERROR; + String type = this.argAsString(1); String message = getArgs(2); diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/CommandVersion.java b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/CommandVersion.java index 54ede166..2e92ee87 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/CommandVersion.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/CommandVersion.java @@ -8,7 +8,7 @@ public class CommandVersion extends VCommand { public CommandVersion(EssentialsPlugin plugin) { super(plugin); - this.setDescription(Message.DESCRIPTION_TRASH); + this.setDescription(Message.DESCRIPTION_VERSION); } @Override diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/admins/CommandKillAll.java b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/admins/CommandKillAll.java index bed1e06c..3002cec6 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/admins/CommandKillAll.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/admins/CommandKillAll.java @@ -9,6 +9,7 @@ import fr.maxlego08.essentials.zutils.utils.commands.VCommand; import org.bukkit.Bukkit; import org.bukkit.Chunk; +import org.bukkit.Location; import org.bukkit.OfflinePlayer; import org.bukkit.World; import org.bukkit.entity.Entity; @@ -53,11 +54,21 @@ private CommandResultType remove(List removeTypes, int radius, Worl if (removeTypes.isEmpty()) return CommandResultType.SYNTAX_ERROR; + Location center = this.sender instanceof Player ? this.player.getLocation() : null; + double radiusSquared = radius > 0 ? (double) radius * radius : 0; + int removed = 0; for (Chunk chunk : world.getLoadedChunks()) { for (Entity entity : chunk.getEntities()) { if (entity instanceof HumanEntity) continue; + // Radius filtering: skip entities outside the specified radius + if (radius > 0 && center != null && entity.getWorld().equals(center.getWorld())) { + if (entity.getLocation().distanceSquared(center) > radiusSquared) { + continue; + } + } + for (KillAllType type : removeTypes) { // We should skip any animals tamed by players unless we are specifically targetting them. diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/admins/CommandPowerToolsToggle.java b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/admins/CommandPowerToolsToggle.java index ee0c38cf..8fd22d3b 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/admins/CommandPowerToolsToggle.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/admins/CommandPowerToolsToggle.java @@ -29,10 +29,11 @@ protected CommandResultType perform(EssentialsPlugin plugin) { return CommandResultType.SYNTAX_ERROR; } - if (player == this.player || !hasPermission(sender, Permission.ESSENTIALS_POWER_TOOLS_TOGGLE_OTHER)) { + if (player.equals(this.player) || !hasPermission(sender, Permission.ESSENTIALS_POWER_TOOLS_TOGGLE_OTHER)) { togglePowerTools(player, this.user, sender); } else { User otherUser = getUser(player); + if (otherUser == null) return CommandResultType.SYNTAX_ERROR; togglePowerTools(player, otherUser, sender); } diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/blocks/CommandAnvil.java b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/blocks/CommandAnvil.java index abdea019..13e46523 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/blocks/CommandAnvil.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/blocks/CommandAnvil.java @@ -17,7 +17,7 @@ public CommandAnvil(EssentialsPlugin plugin) { @Override protected CommandResultType perform(EssentialsPlugin plugin) { - this.player.getPlayer().openAnvil(this.player.getLocation(), true); + this.player.openAnvil(this.player.getLocation(), true); return CommandResultType.SUCCESS; } diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/blocks/CommandCartographyTable.java b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/blocks/CommandCartographyTable.java index becd5593..797055d4 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/blocks/CommandCartographyTable.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/blocks/CommandCartographyTable.java @@ -17,7 +17,7 @@ public CommandCartographyTable(EssentialsPlugin plugin) { @Override protected CommandResultType perform(EssentialsPlugin plugin) { - this.player.getPlayer().openCartographyTable(this.player.getLocation(), true); + this.player.openCartographyTable(this.player.getLocation(), true); return CommandResultType.SUCCESS; } diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/blocks/CommandEnchanting.java b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/blocks/CommandEnchanting.java index 96d0e438..a6910c4b 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/blocks/CommandEnchanting.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/blocks/CommandEnchanting.java @@ -17,7 +17,7 @@ public CommandEnchanting(EssentialsPlugin plugin) { @Override protected CommandResultType perform(EssentialsPlugin plugin) { - this.player.getPlayer().openEnchanting(this.player.getLocation(), true); + this.player.openEnchanting(this.player.getLocation(), true); return CommandResultType.SUCCESS; } diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/blocks/CommandGrindStone.java b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/blocks/CommandGrindStone.java index 10e1abc4..bc7cc9f8 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/blocks/CommandGrindStone.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/blocks/CommandGrindStone.java @@ -17,7 +17,7 @@ public CommandGrindStone(EssentialsPlugin plugin) { @Override protected CommandResultType perform(EssentialsPlugin plugin) { - this.player.getPlayer().openGrindstone(this.player.getLocation(), true); + this.player.openGrindstone(this.player.getLocation(), true); return CommandResultType.SUCCESS; } diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/blocks/CommandLoom.java b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/blocks/CommandLoom.java index 55eef09c..b11bd12e 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/blocks/CommandLoom.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/blocks/CommandLoom.java @@ -17,7 +17,7 @@ public CommandLoom(EssentialsPlugin plugin) { @Override protected CommandResultType perform(EssentialsPlugin plugin) { - this.player.getPlayer().openLoom(this.player.getLocation(), true); + this.player.openLoom(this.player.getLocation(), true); return CommandResultType.SUCCESS; } diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/blocks/CommandSmithingTable.java b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/blocks/CommandSmithingTable.java index a993101a..e5d0d45c 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/blocks/CommandSmithingTable.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/blocks/CommandSmithingTable.java @@ -17,7 +17,7 @@ public CommandSmithingTable(EssentialsPlugin plugin) { @Override protected CommandResultType perform(EssentialsPlugin plugin) { - this.player.getPlayer().openSmithingTable(this.player.getLocation(), true); + this.player.openSmithingTable(this.player.getLocation(), true); return CommandResultType.SUCCESS; } diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/blocks/CommandStoneCutter.java b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/blocks/CommandStoneCutter.java index 09a4ac6f..a392dfcb 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/blocks/CommandStoneCutter.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/blocks/CommandStoneCutter.java @@ -17,7 +17,7 @@ public CommandStoneCutter(EssentialsPlugin plugin) { @Override protected CommandResultType perform(EssentialsPlugin plugin) { - this.player.getPlayer().openStonecutter(this.player.getLocation(), true); + this.player.openStonecutter(this.player.getLocation(), true); return CommandResultType.SUCCESS; } diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/experience/CommandGrantExperience.java b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/experience/CommandGrantExperience.java index 094b3ddd..9df9ade3 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/experience/CommandGrantExperience.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/experience/CommandGrantExperience.java @@ -24,6 +24,7 @@ public CommandGrantExperience(EssentialsPlugin plugin) { @Override protected CommandResultType perform(EssentialsPlugin plugin) { Player player = this.argAsPlayer(0); + if (player == null) return CommandResultType.SYNTAX_ERROR; int amount = this.argAsInteger(1); String type = this.argAsString(2); diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/experience/CommandGrantRandomExperience.java b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/experience/CommandGrantRandomExperience.java index cf88c26d..b18c0ce1 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/experience/CommandGrantRandomExperience.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/experience/CommandGrantRandomExperience.java @@ -26,6 +26,7 @@ public CommandGrantRandomExperience(EssentialsPlugin plugin) { @Override protected CommandResultType perform(EssentialsPlugin plugin) { Player player = this.argAsPlayer(0); + if (player == null) return CommandResultType.SYNTAX_ERROR; int minAmount = this.argAsInteger(1); int maxAmount = this.argAsInteger(2); String type = this.argAsString(3); diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/experience/CommandQueryExperience.java b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/experience/CommandQueryExperience.java index b464dc95..0375535d 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/experience/CommandQueryExperience.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/experience/CommandQueryExperience.java @@ -24,6 +24,7 @@ public CommandQueryExperience(EssentialsPlugin plugin) { @Override protected CommandResultType perform(EssentialsPlugin plugin) { Player player = this.argAsPlayer(0); + if (player == null) return CommandResultType.SYNTAX_ERROR; String type = this.argAsString(1); int amount = type.equalsIgnoreCase("levels") ? player.getLevel() : this.getPlayerExp(player); diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/experience/CommandSetExperience.java b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/experience/CommandSetExperience.java index dc062865..70dd854d 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/experience/CommandSetExperience.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/experience/CommandSetExperience.java @@ -25,6 +25,7 @@ public CommandSetExperience(EssentialsPlugin plugin) { @Override protected CommandResultType perform(EssentialsPlugin plugin) { Player player = this.argAsPlayer(0); + if (player == null) return CommandResultType.SYNTAX_ERROR; int amount = this.argAsInteger(1); String type = this.argAsString(2); diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/experience/CommandTakeExperience.java b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/experience/CommandTakeExperience.java index 4f771fe7..81177cbd 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/experience/CommandTakeExperience.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/experience/CommandTakeExperience.java @@ -24,6 +24,7 @@ public CommandTakeExperience(EssentialsPlugin plugin) { @Override protected CommandResultType perform(EssentialsPlugin plugin) { Player player = this.argAsPlayer(0); + if (player == null) return CommandResultType.SYNTAX_ERROR; int amount = this.argAsInteger(1); String type = this.argAsString(2); diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/warp/CommandDelWarp.java b/src/main/java/fr/maxlego08/essentials/commands/commands/warp/CommandDelWarp.java index edac3394..2ab735ee 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/warp/CommandDelWarp.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/warp/CommandDelWarp.java @@ -36,7 +36,7 @@ protected CommandResultType perform(EssentialsPlugin plugin) { ConfigStorage.warps.removeIf(warp -> warp.name().equalsIgnoreCase(warpName)); ConfigStorage.getInstance().save(plugin.getPersist()); - message(sender, Message.COMMAND_WARP_CREATE, "%name%", warpName); + message(sender, Message.COMMAND_WARP_DELETE, "%name%", warpName); return CommandResultType.SUCCESS; } diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/weather/CommandSun.java b/src/main/java/fr/maxlego08/essentials/commands/commands/weather/CommandSun.java index 5658ce35..1a8b1bd7 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/weather/CommandSun.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/weather/CommandSun.java @@ -24,6 +24,8 @@ public CommandSun(EssentialsPlugin plugin) { protected CommandResultType perform(EssentialsPlugin plugin) { World world = this.argAsWorld(0, isPlayer() ? this.player.getWorld() : null); + if (world == null) return CommandResultType.SYNTAX_ERROR; + world.setStorm(false); world.setThunderDuration(0); world.setThundering(false); diff --git a/src/main/java/fr/maxlego08/essentials/listener/InvseeListener.java b/src/main/java/fr/maxlego08/essentials/listener/InvseeListener.java index c502d195..fed74a74 100644 --- a/src/main/java/fr/maxlego08/essentials/listener/InvseeListener.java +++ b/src/main/java/fr/maxlego08/essentials/listener/InvseeListener.java @@ -13,6 +13,7 @@ public class InvseeListener implements Listener { public void onClose(InventoryCloseEvent event) { if (event.getInventory().getHolder() instanceof EnderChestHolder enderChestHolder) { var targetPlayer = enderChestHolder.player(); + if (targetPlayer == null || !targetPlayer.isOnline()) return; int slot = 0; for (ItemStack content : event.getInventory().getContents()) { targetPlayer.getEnderChest().setItem(slot++, content); @@ -20,8 +21,9 @@ public void onClose(InventoryCloseEvent event) { targetPlayer.saveData(); } else if (event.getInventory().getHolder() instanceof PlayerInventoryHolder playerInventoryHolder) { var targetPlayer = playerInventoryHolder.player(); - for (int slot = 0; slot != 36; slot++) { - targetPlayer.getInventory().setItem(slot++, event.getInventory().getItem(slot)); + if (targetPlayer == null || !targetPlayer.isOnline()) return; + for (int slot = 0; slot < 36; slot++) { + targetPlayer.getInventory().setItem(slot, event.getInventory().getItem(slot)); } targetPlayer.saveData(); } diff --git a/src/main/java/fr/maxlego08/essentials/listener/PlayerListener.java b/src/main/java/fr/maxlego08/essentials/listener/PlayerListener.java index f58ba77c..c64dd527 100644 --- a/src/main/java/fr/maxlego08/essentials/listener/PlayerListener.java +++ b/src/main/java/fr/maxlego08/essentials/listener/PlayerListener.java @@ -261,7 +261,9 @@ public void onInteract(PlayerItemConsumeEvent event) { User user = this.plugin.getUser(player.getUniqueId()); if (user != null && user.getOption(Option.NIGHT_VISION) && event.getItem().getType() == Material.MILK_BUCKET) { - this.plugin.getScheduler().runAtLocationLater(player.getLocation(), wrappedTask -> player.addPotionEffect(new PotionEffect(PotionEffectType.NIGHT_VISION, -1, 1, false, false, false), true), 2); + this.plugin.getScheduler().runAtLocationLater(player.getLocation(), wrappedTask -> { + if (player.isOnline()) player.addPotionEffect(new PotionEffect(PotionEffectType.NIGHT_VISION, -1, 1, false, false, false), true); + }, 2); } } @@ -272,7 +274,9 @@ public void onRespawn(PlayerRespawnEvent event) { User user = this.plugin.getUser(player.getUniqueId()); if (user != null && user.getOption(Option.NIGHT_VISION)) { - this.plugin.getScheduler().runAtLocationLater(player.getLocation(), wrappedTask -> player.addPotionEffect(new PotionEffect(PotionEffectType.NIGHT_VISION, -1, 1, false, false, false), true), 2); + this.plugin.getScheduler().runAtLocationLater(player.getLocation(), wrappedTask -> { + if (player.isOnline()) player.addPotionEffect(new PotionEffect(PotionEffectType.NIGHT_VISION, -1, 1, false, false, false), true); + }, 2); } } diff --git a/src/main/java/fr/maxlego08/essentials/module/ZModuleManager.java b/src/main/java/fr/maxlego08/essentials/module/ZModuleManager.java index 117fdaef..9ee4ed2b 100644 --- a/src/main/java/fr/maxlego08/essentials/module/ZModuleManager.java +++ b/src/main/java/fr/maxlego08/essentials/module/ZModuleManager.java @@ -3,6 +3,7 @@ import fr.maxlego08.essentials.ZEssentialsPlugin; import fr.maxlego08.essentials.api.modules.Module; import fr.maxlego08.essentials.api.modules.ModuleManager; +import fr.maxlego08.essentials.module.modules.DeathMessageModule; import fr.maxlego08.essentials.module.modules.afk.AFKModule; import fr.maxlego08.essentials.module.modules.discord.DiscordModule; import fr.maxlego08.essentials.module.modules.economy.EconomyModule; @@ -80,6 +81,9 @@ public void loadModules() { this.modules.put(StepModule.class, new StepModule(this.plugin)); this.modules.put(AFKModule.class, new AFKModule(this.plugin)); this.modules.put(AutoMessageModule.class, new AutoMessageModule(this.plugin)); + if (plugin.isPaperVersion()) { + this.modules.put(DeathMessageModule.class, new DeathMessageModule(this.plugin)); + } this.loadConfigurations(); diff --git a/src/main/java/fr/maxlego08/essentials/module/modules/HomeModule.java b/src/main/java/fr/maxlego08/essentials/module/modules/HomeModule.java index d5f74157..f1a5900a 100644 --- a/src/main/java/fr/maxlego08/essentials/module/modules/HomeModule.java +++ b/src/main/java/fr/maxlego08/essentials/module/modules/HomeModule.java @@ -28,8 +28,8 @@ public class HomeModule extends ZModule implements HomeManager { private final List permissions = new ArrayList<>(); private final List disableWorlds = new ArrayList<>(); - private final HomeDisplay homeDisplay = HomeDisplay.MULTI_LINE; - private final String homeRegex = "[a-zA-Z0-9]+"; + private HomeDisplay homeDisplay = HomeDisplay.MULTI_LINE; + private String homeRegex = "[a-zA-Z0-9]+"; private int homeNameMax; private int homeNameMin; private boolean homeOverwriteConfirm; @@ -114,23 +114,28 @@ public void openInventoryConfirmHome(User user, Home home) { private Object[] formatHomeInformation(Home home, int homeAmount, int maxHome) { Location location = home.getLocation(); - World world = location.getWorld(); - return new Object[]{"%count%", homeAmount, "%max%", maxHome, "%name%", home.getName(), "%world%", name(world.getName()), "%environment%", name(world.getEnvironment().name()), "%x%", location.getBlockX(), "%y%", location.getBlockY(), "%z%", location.getBlockZ()}; + World world = location != null ? location.getWorld() : null; + String worldName = world != null ? name(world.getName()) : "unknown"; + String environment = world != null ? name(world.getEnvironment().name()) : "unknown"; + int x = location != null ? location.getBlockX() : 0; + int y = location != null ? location.getBlockY() : 0; + int z = location != null ? location.getBlockZ() : 0; + return new Object[]{"%count%", homeAmount, "%max%", maxHome, "%name%", home.getName(), "%world%", worldName, "%environment%", environment, "%x%", x, "%y%", y, "%z%", z}; } @Override public Placeholders getHomePlaceholders(Home home, int homeAmount, int maxHome) { Placeholders placeholders = new Placeholders(); Location location = home.getLocation(); - World world = location.getWorld(); + World world = location != null ? location.getWorld() : null; placeholders.register("count", String.valueOf(homeAmount)); placeholders.register("max", String.valueOf(maxHome)); placeholders.register("name", home.getName()); - placeholders.register("world", name(world.getName())); - placeholders.register("environment", name(world.getEnvironment().name())); - placeholders.register("x", String.valueOf(location.getBlockX())); - placeholders.register("y", String.valueOf(location.getBlockY())); - placeholders.register("z", String.valueOf(location.getBlockZ())); + placeholders.register("world", world != null ? name(world.getName()) : "unknown"); + placeholders.register("environment", world != null ? name(world.getEnvironment().name()) : "unknown"); + placeholders.register("x", String.valueOf(location != null ? location.getBlockX() : 0)); + placeholders.register("y", String.valueOf(location != null ? location.getBlockY() : 0)); + placeholders.register("z", String.valueOf(location != null ? location.getBlockZ() : 0)); return placeholders; } diff --git a/src/main/java/fr/maxlego08/essentials/module/modules/JoinQuitModule.java b/src/main/java/fr/maxlego08/essentials/module/modules/JoinQuitModule.java index f4901667..5b936174 100644 --- a/src/main/java/fr/maxlego08/essentials/module/modules/JoinQuitModule.java +++ b/src/main/java/fr/maxlego08/essentials/module/modules/JoinQuitModule.java @@ -39,12 +39,15 @@ public void onFirstJoin(UserFirstJoinEvent event) { User user = event.getUser(); Player player = user.getPlayer(); - + if (player == null) return; + // Check for first join random teleport TeleportationModule teleportModule = plugin.getModuleManager().getModule(TeleportationModule.class); if (teleportModule != null && teleportModule.isEnable() && teleportModule.isEnableFirstJoinRtp()) { this.plugin.getScheduler().runAtLocationLater(player.getLocation(), () -> { - teleportModule.performFirstJoinRtp(player); + if (player.isOnline()) { + teleportModule.performFirstJoinRtp(player); + } }, 20); // Delay 1 second after join } diff --git a/src/main/java/fr/maxlego08/essentials/module/modules/MailBoxModule.java b/src/main/java/fr/maxlego08/essentials/module/modules/MailBoxModule.java index 90d8ef5a..33c692d2 100644 --- a/src/main/java/fr/maxlego08/essentials/module/modules/MailBoxModule.java +++ b/src/main/java/fr/maxlego08/essentials/module/modules/MailBoxModule.java @@ -126,6 +126,10 @@ public void openMailBox(User user, UUID uuid, String username) { public void giveItem(CommandSender sender, UUID uuid, String username, String itemName, int amount) { var itemModule = plugin.getModuleManager().getModule(ItemModule.class); + if (itemModule == null) { + message(sender, Message.MAILBOX_GIVE_ERROR, "%item%", itemName); + return; + } var itemStack = itemModule.getItemStack(itemName, Bukkit.getPlayer(uuid)); if (itemStack == null) { @@ -162,7 +166,7 @@ public void giveItem(CommandSender sender, UUID uuid, String username, String it public void giveAllItem(CommandSender sender, String itemName, int amount) { var itemModule = plugin.getModuleManager().getModule(ItemModule.class); - if (!itemModule.isItem(itemName)) { + if (itemModule == null || !itemModule.isItem(itemName)) { message(sender, Message.MAILBOX_GIVE_ERROR, "%item%", itemName); return; } diff --git a/src/main/java/fr/maxlego08/essentials/module/modules/MessageModule.java b/src/main/java/fr/maxlego08/essentials/module/modules/MessageModule.java index 74b5b0a8..61d5240d 100644 --- a/src/main/java/fr/maxlego08/essentials/module/modules/MessageModule.java +++ b/src/main/java/fr/maxlego08/essentials/module/modules/MessageModule.java @@ -38,6 +38,7 @@ public void sendMessage(User user, UUID receiverUUID, String userName, String me } Map options = iStorage.getOptions(receiverUUID); + if (options == null) options = new java.util.HashMap<>(); User targetUser = iStorage.getUser(receiverUUID); // Vanish check diff --git a/src/main/java/fr/maxlego08/essentials/module/modules/SanctionModule.java b/src/main/java/fr/maxlego08/essentials/module/modules/SanctionModule.java index f0578e93..78fa21cf 100644 --- a/src/main/java/fr/maxlego08/essentials/module/modules/SanctionModule.java +++ b/src/main/java/fr/maxlego08/essentials/module/modules/SanctionModule.java @@ -364,6 +364,10 @@ public void seen(CommandSender sender, UUID uuid) { private void sendOnline(CommandSender sender, UserRecord record) { User user = this.plugin.getUser(record.userDTO().unique_id()); + if (user == null) { + sendOffline(sender, record); + return; + } message(sender, Message.COMMAND_SEEN_ONLINE, "%player%", record.userDTO().name(), "%date%", TimerBuilder.getStringTime(System.currentTimeMillis() - user.getCurrentSessionPlayTime())); message(sender, Message.COMMAND_SEEN_PLAYTIME, "%playtime%", TimerBuilder.getStringTime(user.getPlayTime() * 1000)); } @@ -415,14 +419,18 @@ public void freeze(CommandSender sender, UUID uuid, String userName) { message(sender, Message.COMMAND_FREEZE_SUCCESS, "%player%", userName); this.plugin.getEssentialsServer().sendMessage(uuid, Message.MESSAGE_FREEZE); - player.setAllowFlight(true); - player.setFlying(true); - player.setFlySpeed(0f); - this.plugin.getScheduler().teleportAsync(user.getPlayer(), user.getPlayer().getLocation().add(0, 0.1, 0)); + if (player != null) { + player.setAllowFlight(true); + player.setFlying(true); + player.setFlySpeed(0f); + this.plugin.getScheduler().teleportAsync(player, player.getLocation().add(0, 0.1, 0)); + } } else { - player.setAllowFlight(false); - player.setFlying(false); - player.setFlySpeed(0.1f); + if (player != null) { + player.setAllowFlight(false); + player.setFlying(false); + player.setFlySpeed(0.1f); + } message(sender, Message.COMMAND_UN_FREEZE_SUCCESS, "%player%", userName); this.plugin.getEssentialsServer().sendMessage(uuid, Message.MESSAGE_UN_FREEZE); @@ -433,10 +441,13 @@ public void freeze(CommandSender sender, UUID uuid, String userName) { public void onJoin(PlayerJoinEvent event) { User user = this.getUser(event.getPlayer()); if (user != null && user.isFrozen()) { - user.getPlayer().setAllowFlight(true); - user.getPlayer().setFlying(true); - user.getPlayer().setFlySpeed(0f); - this.plugin.getScheduler().teleportAsync(user.getPlayer(), user.getPlayer().getLocation().add(0, 0.1, 0)); + Player player = user.getPlayer(); + if (player != null) { + player.setAllowFlight(true); + player.setFlying(true); + player.setFlySpeed(0f); + this.plugin.getScheduler().teleportAsync(player, player.getLocation().add(0, 0.1, 0)); + } this.plugin.getEssentialsServer().sendMessage(user.getUniqueId(), Message.MESSAGE_FREEZE); } } @@ -456,8 +467,12 @@ public void cancelChatEvent(Cancellable event, Player player) { if (user != null && user.isMute()) { event.setCancelled(true); Sanction sanction = user.getMuteSanction(); - Duration duration = sanction.getDurationRemaining(); - message(player, Message.MESSAGE_MUTE_TALK, "%reason%", sanction.getReason(), "%duration%", TimerBuilder.getStringTime(duration.toMillis())); + if (sanction != null) { + Duration duration = sanction.getDurationRemaining(); + message(player, Message.MESSAGE_MUTE_TALK, "%reason%", sanction.getReason(), "%duration%", TimerBuilder.getStringTime(duration.toMillis())); + } else { + message(player, Message.MESSAGE_MUTE_TALK, "%reason%", "", "%duration%", ""); + } } } } diff --git a/src/main/java/fr/maxlego08/essentials/module/modules/SpawnModule.java b/src/main/java/fr/maxlego08/essentials/module/modules/SpawnModule.java index 474f3976..7b8d0775 100644 --- a/src/main/java/fr/maxlego08/essentials/module/modules/SpawnModule.java +++ b/src/main/java/fr/maxlego08/essentials/module/modules/SpawnModule.java @@ -68,7 +68,8 @@ public void loadConfiguration() { if (listener instanceof SpawnModule spawnModule && event instanceof PlayerJoinEvent playerJoinEvent) { var player = playerJoinEvent.getPlayer(); if (ConfigStorage.spawnLocation != null && ConfigStorage.spawnLocation.isValid()) { - player.teleport(ConfigStorage.spawnLocation.getLocation()); + Location spawnLoc = ConfigStorage.spawnLocation.getLocation(); + if (spawnLoc != null) player.teleport(spawnLoc); } } }, this.plugin); diff --git a/src/main/java/fr/maxlego08/essentials/module/modules/TeleportationModule.java b/src/main/java/fr/maxlego08/essentials/module/modules/TeleportationModule.java index 2d291352..e1751461 100644 --- a/src/main/java/fr/maxlego08/essentials/module/modules/TeleportationModule.java +++ b/src/main/java/fr/maxlego08/essentials/module/modules/TeleportationModule.java @@ -337,6 +337,11 @@ private void processRtpQueue(World defaultWorld, RandomTeleportWorld defaultConf world = defaultWorld; } + if (configuration == null || world == null) { + processRtpQueue(defaultWorld, defaultConfig); + return; + } + final World finalWorld = world; final RandomTeleportWorld finalConfig = configuration; @@ -355,7 +360,7 @@ private void processRtpQueue(World defaultWorld, RandomTeleportWorld defaultConf } public void performFirstJoinRtp(Player player) { - if (!enableFirstJoinRtp) return; + if (!enableFirstJoinRtp || player == null || !player.isOnline()) return; World world = plugin.getServer().getWorld(firstJoinRtpWorld); if (world == null) { diff --git a/src/main/java/fr/maxlego08/essentials/module/modules/VoteModule.java b/src/main/java/fr/maxlego08/essentials/module/modules/VoteModule.java index d7efb183..1ac57223 100644 --- a/src/main/java/fr/maxlego08/essentials/module/modules/VoteModule.java +++ b/src/main/java/fr/maxlego08/essentials/module/modules/VoteModule.java @@ -233,7 +233,7 @@ public void handleVoteParty(long amount) { var startEvent = new VotePartyStartEvent(); startEvent.callEvent(); - if (event.isCancelled()) return; + if (startEvent.isCancelled()) return; setCurrentVotePartyAmount(0); this.giveVotePartyRewards(); diff --git a/src/main/java/fr/maxlego08/essentials/module/modules/afk/AFKModule.java b/src/main/java/fr/maxlego08/essentials/module/modules/afk/AFKModule.java index 5334da68..f0f1e4ec 100644 --- a/src/main/java/fr/maxlego08/essentials/module/modules/afk/AFKModule.java +++ b/src/main/java/fr/maxlego08/essentials/module/modules/afk/AFKModule.java @@ -73,14 +73,16 @@ private void checkPlayers() { @Override public void checkUser(User user) { - var optional = getPermission(user.getPlayer()); + var player = user.getPlayer(); + if (player == null) return; + + var optional = getPermission(player); if (optional.isEmpty()) return; var permission = optional.get(); var difference = (System.currentTimeMillis() - user.getLastActiveTime()) / 1000; var component = this.plugin.getComponentMessage(); - var player = user.getPlayer(); if (difference >= permission.maxAfkTime()) { diff --git a/src/main/java/fr/maxlego08/essentials/module/modules/chat/ChatModule.java b/src/main/java/fr/maxlego08/essentials/module/modules/chat/ChatModule.java index fb1c54d2..13a938f5 100644 --- a/src/main/java/fr/maxlego08/essentials/module/modules/chat/ChatModule.java +++ b/src/main/java/fr/maxlego08/essentials/module/modules/chat/ChatModule.java @@ -230,7 +230,8 @@ public void onTalk(AsyncChatEvent event) { } Tag tag = Tag.inserting(paperComponent.translateText(player, localMessage, builder.build())); - return paperComponent.getComponentMessage(chatFormat, TagResolver.resolver("message", tag), "%displayName%", player.getDisplayName(), "%player%", player.getName(), "%moderator_action%", isModerator ? papi(getMessage(this.moderatorAction, "%player%", player.getName()), (Player) viewer) : ""); + String moderatorAction = (isModerator && viewer instanceof Player playerMod) ? papi(getMessage(this.moderatorAction, "%player%", player.getName()), playerMod) : ""; + return paperComponent.getComponentMessage(chatFormat, TagResolver.resolver("message", tag), "%displayName%", player.getDisplayName(), "%player%", player.getName(), "%moderator_action%", moderatorAction); }); if (this.enableChatMessages) { diff --git a/src/main/java/fr/maxlego08/essentials/module/modules/economy/EconomyModule.java b/src/main/java/fr/maxlego08/essentials/module/modules/economy/EconomyModule.java index f6c0c36b..264de584 100644 --- a/src/main/java/fr/maxlego08/essentials/module/modules/economy/EconomyModule.java +++ b/src/main/java/fr/maxlego08/essentials/module/modules/economy/EconomyModule.java @@ -152,7 +152,7 @@ public void refreshBaltop(Economy economy) { @Override public boolean hasMoney(OfflinePlayer offlinePlayer, Economy economy, BigDecimal decimal) { BigDecimal bigDecimal = getBalance(offlinePlayer, economy); - return bigDecimal.compareTo(decimal) > 0; + return bigDecimal.compareTo(decimal) >= 0; } @Override @@ -436,6 +436,10 @@ private void sendMessageBaltop(Player player, int page) { Economy economy = optional.get(); Baltop baltop = getBaltop(economy); + if (baltop == null) { + message(player, Message.COMMAND_BALTOP_ERROR, "%name%", this.baltopMessageEconomy); + return; + } List userBaltops = baltop.getUsers(); Pagination pagination = new Pagination<>(); diff --git a/src/main/java/fr/maxlego08/essentials/module/modules/hologram/HologramModule.java b/src/main/java/fr/maxlego08/essentials/module/modules/hologram/HologramModule.java index 5493b18a..34b91eb8 100644 --- a/src/main/java/fr/maxlego08/essentials/module/modules/hologram/HologramModule.java +++ b/src/main/java/fr/maxlego08/essentials/module/modules/hologram/HologramModule.java @@ -36,6 +36,7 @@ import org.bukkit.event.player.PlayerChangedWorldEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.event.world.WorldLoadEvent; import org.bukkit.plugin.PluginManager; @@ -349,11 +350,35 @@ public void onConnect(PlayerJoinEvent event) { @EventHandler public void onWorldChange(PlayerChangedWorldEvent event) { - displayHologram(event.getPlayer()); + // Remove holograms from old world and show holograms in new world + Player player = event.getPlayer(); + this.holograms.stream() + .filter(hologram -> hologram.getLocation().getWorld().equals(event.getFrom().getName())) + .forEach(hologram -> { + hologram.delete(player); + hologram.removePlayer(player); + }); + displayHologram(player); + } + + @EventHandler + public void onTeleport(PlayerTeleportEvent event) { + if (event.isCancelled()) return; + Player player = event.getPlayer(); + // Re-display holograms after teleport (spawn, warp, tp, etc.) + this.plugin.getScheduler().runNextTick(wrappedTask -> { + if (player.isOnline()) { + displayHologram(player); + } + }); } private void displayHologram(Player player) { - this.holograms.stream().filter(hologram -> hologram.getLocation().getWorld().equals(player.getWorld().getName())).forEach(hologram -> hologram.create(player)); + String worldName = player.getWorld().getName(); + this.holograms.stream() + .filter(Hologram::isLoaded) + .filter(hologram -> hologram.getLocation().getWorld().equals(worldName)) + .forEach(hologram -> hologram.create(player)); } private void updateHolograms() { diff --git a/src/main/java/fr/maxlego08/essentials/storage/ZStorageManager.java b/src/main/java/fr/maxlego08/essentials/storage/ZStorageManager.java index 42ed184c..63155876 100644 --- a/src/main/java/fr/maxlego08/essentials/storage/ZStorageManager.java +++ b/src/main/java/fr/maxlego08/essentials/storage/ZStorageManager.java @@ -76,8 +76,12 @@ public void onLogin(PlayerLoginEvent event) { if (this.iStorage.isBan(playerUuid)) { Sanction sanction = this.iStorage.getBan(playerUuid); - Duration duration = sanction.getDurationRemaining(); - this.plugin.getUtils().disallow(event, PlayerLoginEvent.Result.KICK_BANNED, Message.MESSAGE_BAN_JOIN, "%reason%", sanction.getReason(), "%remaining%", TimerBuilder.getStringTime(duration.toMillis())); + if (sanction != null) { + Duration duration = sanction.getDurationRemaining(); + this.plugin.getUtils().disallow(event, PlayerLoginEvent.Result.KICK_BANNED, Message.MESSAGE_BAN_JOIN, "%reason%", sanction.getReason(), "%remaining%", TimerBuilder.getStringTime(duration.toMillis())); + } else { + this.plugin.getUtils().disallow(event, PlayerLoginEvent.Result.KICK_BANNED, Message.MESSAGE_BAN_JOIN, "%reason%", "", "%remaining%", ""); + } return; } diff --git a/src/main/java/fr/maxlego08/essentials/user/ZUser.java b/src/main/java/fr/maxlego08/essentials/user/ZUser.java index 89f7418a..09bb5c8f 100644 --- a/src/main/java/fr/maxlego08/essentials/user/ZUser.java +++ b/src/main/java/fr/maxlego08/essentials/user/ZUser.java @@ -312,14 +312,17 @@ public void removeIncomingTeleportRequest(User fromUser) { @Override public void teleportNow(Location location) { + Player player = this.getPlayer(); + if (player == null || location == null || location.getWorld() == null) return; + // ToDo, https://github.com/PaperMC/Folia/?tab=readme-ov-file#current-broken-api // When folia API is update, remove this if (this.plugin.isFolia()) { this.setLastLocation(); } - this.plugin.getScheduler().teleportAsync(this.getPlayer(), location); + this.plugin.getScheduler().teleportAsync(player, location); - int duration = this.plugin.getModuleManager().getModule(TeleportationModule.class).getTeleportProtectionDelay(this.getPlayer()); + int duration = this.plugin.getModuleManager().getModule(TeleportationModule.class).getTeleportProtectionDelay(player); if (duration == 0) return; this.protectionDuration = System.currentTimeMillis() + duration; @@ -333,9 +336,12 @@ public void teleport(Location location) { @Override public void teleport(Location location, Message message, Message successMessage, Object... args) { + Player player = this.getPlayer(); + if (player == null || location == null || location.getWorld() == null) return; + TeleportationModule teleportationModule = this.plugin.getModuleManager().getModule(TeleportationModule.class); - Location playerLocation = getPlayer().getLocation(); - AtomicInteger atomicInteger = new AtomicInteger(teleportationModule.getTeleportDelay(getPlayer())); + Location playerLocation = player.getLocation(); + AtomicInteger atomicInteger = new AtomicInteger(teleportationModule.getTeleportDelay(player)); if (teleportationModule.isTeleportDelayBypass() && this.hasPermission(Permission.ESSENTIALS_TELEPORT_BYPASS) || atomicInteger.get() <= 0) { this.teleport(teleportationModule, location, successMessage, args); @@ -375,7 +381,10 @@ public void teleport(Location location, Message message, Message successMessage, } private void teleport(TeleportationModule teleportationModule, Location toLocation, Message message, Object... args) { - Location location = getPlayer().isFlying() ? toLocation : teleportationModule.isTeleportSafety() ? toSafeLocation(toLocation) : toLocation; + Player player = this.getPlayer(); + if (player == null) return; + + Location location = player.isFlying() ? toLocation : teleportationModule.isTeleportSafety() ? toSafeLocation(toLocation) : toLocation; if (teleportationModule.isTeleportToCenter()) { location = location.getBlock().getLocation().add(0.5, 0, 0.5); @@ -391,7 +400,8 @@ private void teleport(TeleportationModule teleportationModule, Location toLocati @Override public boolean hasPermission(Permission permission) { - return getPlayer().hasPermission(permission.asPermission()); + Player player = getPlayer(); + return player != null && player.hasPermission(permission.asPermission()); } @Override @@ -619,6 +629,7 @@ public void setLastLocation() { @Override public Location getLastLocation() { + if (this.lastLocation == null) return null; return this.lastLocation.getLocation(); } @@ -822,8 +833,10 @@ public void addKitCooldown(Kit kit, long cooldown) { @Override public void openKitPreview(Kit kit) { + Player player = getPlayer(); + if (player == null) return; this.previewKit = kit; - this.plugin.openInventory(getPlayer(), "kit_preview"); + this.plugin.openInventory(player, "kit_preview"); } @Override @@ -968,17 +981,22 @@ public void setWorldeditTask(WorldEditTask worldEditTask) { @Override public ItemStack getItemInMainHand() { - return getPlayer().getInventory().getItemInMainHand(); + Player player = getPlayer(); + if (player == null) return null; + return player.getInventory().getItemInMainHand(); } @Override public void setItemInMainHand(ItemStack itemStack) { - getPlayer().getInventory().setItemInMainHand(itemStack); + Player player = getPlayer(); + if (player == null) return; + player.getInventory().setItemInMainHand(itemStack); } @Override public void playSound(Sound sound, float volume, float pitch) { var player = getPlayer(); + if (player == null) return; player.playSound(player.getLocation(), sound, volume, pitch); } diff --git a/src/main/java/fr/maxlego08/essentials/user/placeholders/UserPlaceholders.java b/src/main/java/fr/maxlego08/essentials/user/placeholders/UserPlaceholders.java index 74fd43c0..b21f4181 100644 --- a/src/main/java/fr/maxlego08/essentials/user/placeholders/UserPlaceholders.java +++ b/src/main/java/fr/maxlego08/essentials/user/placeholders/UserPlaceholders.java @@ -135,12 +135,14 @@ public void register(Placeholder placeholder, EssentialsPlugin plugin) { placeholder.register("user_mute_seconds", (player) -> { User user = iStorage.getUser(player.getUniqueId()); - return user != null ? String.valueOf((user.getMuteSanction().getDurationRemaining().toSeconds())) : "0"; + if (user == null || user.getMuteSanction() == null) return "0"; + return String.valueOf(user.getMuteSanction().getDurationRemaining().toSeconds()); }, "Returns the remaining time in seconds for the mute"); placeholder.register("user_mute_formatted", (player) -> { User user = iStorage.getUser(player.getUniqueId()); - return TimerBuilder.getStringTime(user != null ? user.getMuteSanction().getDurationRemaining().toMillis() : 0); + if (user == null || user.getMuteSanction() == null) return TimerBuilder.getStringTime(0); + return TimerBuilder.getStringTime(user.getMuteSanction().getDurationRemaining().toMillis()); }, "Returns the remaining formatted time for the mute"); // Mailbox @@ -189,7 +191,10 @@ public void register(Placeholder placeholder, EssentialsPlugin plugin) { placeholder.register("user_block_z", (player) -> String.valueOf(player.getLocation().getBlockZ()), "Returns the block z coordinate of the player"); placeholder.register("user_biome", (player) -> player.getWorld().getBiome(player.getLocation()).name(), "Returns the biome of the player"); - placeholder.register("user_has_discord_linked", (player) -> iStorage.getUser(player.getUniqueId()).isDiscordLinked() ? "true" : "false", "Returns true if the player has a discord linked"); + placeholder.register("user_has_discord_linked", (player) -> { + User user = iStorage.getUser(player.getUniqueId()); + return user != null && user.isDiscordLinked() ? "true" : "false"; + }, "Returns true if the player has a discord linked"); // PayToggle placeholder.register("user_is_pay_disabled", (player) -> { From 89c1641813b36d79a5befa0767bff6eec2dd07db Mon Sep 17 00:00:00 2001 From: WhiteProject1 Date: Mon, 9 Mar 2026 18:43:27 +0300 Subject: [PATCH 2/2] :bug: Fix hologram NPE crash, enchant command, add LUNGE enchantment - HologramLoader/Module: null check when NMS class unavailable (prevents plugin crash) - CommandEnchant: fallback for deprecated translationKey() - ZEnchantments: add LUNGE (1.21.11), null-safe register, use valueOf() for 1.21 enchants --- .../commands/utils/admins/CommandEnchant.java | 7 ++++++- .../essentials/enchantments/ZEnchantments.java | 15 ++++++++------- .../module/modules/hologram/HologramLoader.java | 5 +++++ .../module/modules/hologram/HologramModule.java | 1 + 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/admins/CommandEnchant.java b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/admins/CommandEnchant.java index 8d06430f..12b306d0 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/utils/admins/CommandEnchant.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/utils/admins/CommandEnchant.java @@ -52,7 +52,12 @@ protected CommandResultType perform(EssentialsPlugin plugin) { } enchant(itemStack, enchantment, level); - String translatedEnchantments = ""; + String translatedEnchantments; + try { + translatedEnchantments = ""; + } catch (Exception e) { + translatedEnchantments = ""; + } if (level == 0) { message(sender, player, Message.COMMAND_ENCHANT_REMOVE_SELF, Message.COMMAND_ENCHANT_REMOVE_PLAYER, "%enchant%", translatedEnchantments); diff --git a/src/main/java/fr/maxlego08/essentials/enchantments/ZEnchantments.java b/src/main/java/fr/maxlego08/essentials/enchantments/ZEnchantments.java index ea325a2d..40281826 100644 --- a/src/main/java/fr/maxlego08/essentials/enchantments/ZEnchantments.java +++ b/src/main/java/fr/maxlego08/essentials/enchantments/ZEnchantments.java @@ -60,16 +60,17 @@ public void register() { this.register(Enchantment.SOUL_SPEED, "soulspeed", "soilspeed", "sandspeed"); this.register(Enchantment.SWIFT_SNEAK, "swiftsneak"); - // 1.21 - try { - this.register(Enchantment.getByName("BREACH"), "breach"); - this.register(Enchantment.getByName("DENSITY"), "density"); - this.register(Enchantment.getByName("WIND_BURST"), "windburst", "wind", "burst"); - } catch (Exception ignored) { - } + // 1.21+ + this.register(valueOf("BREACH"), "breach"); + this.register(valueOf("DENSITY"), "density"); + this.register(valueOf("WIND_BURST"), "windburst", "wind", "burst"); + + // 1.21.11+ + this.register(valueOf("LUNGE"), "lunge"); } private void register(Enchantment enchantment, String... strings) { + if (enchantment == null) return; this.essentialsEnchantments.add(new ZEssentialsEnchantment(enchantment, Arrays.asList(strings))); } diff --git a/src/main/java/fr/maxlego08/essentials/module/modules/hologram/HologramLoader.java b/src/main/java/fr/maxlego08/essentials/module/modules/hologram/HologramLoader.java index f5bdaf79..5c90b289 100644 --- a/src/main/java/fr/maxlego08/essentials/module/modules/hologram/HologramLoader.java +++ b/src/main/java/fr/maxlego08/essentials/module/modules/hologram/HologramLoader.java @@ -53,6 +53,11 @@ public Hologram load(YamlConfiguration configuration, String path, Object... obj HologramManager hologramManager = this.plugin.getHologramManager(); Hologram hologram = hologramManager.createHologram(hologramType, hologramConfiguration, (String) objects[0], name, location); + if (hologram == null) { + this.plugin.getLogger().warning("Failed to create hologram '" + name + "', NMS class not available for this server version."); + return null; + } + loadConfiguration(configuration, hologramConfiguration); switch (hologramType) { diff --git a/src/main/java/fr/maxlego08/essentials/module/modules/hologram/HologramModule.java b/src/main/java/fr/maxlego08/essentials/module/modules/hologram/HologramModule.java index 34b91eb8..4a4dc907 100644 --- a/src/main/java/fr/maxlego08/essentials/module/modules/hologram/HologramModule.java +++ b/src/main/java/fr/maxlego08/essentials/module/modules/hologram/HologramModule.java @@ -242,6 +242,7 @@ public void loadHologram(File file) { try { Hologram hologram = loader.load(configuration, "", file.getName().replace(".yml", "")); + if (hologram == null) return; if (hologram.canLoad()) { hologram.create(); hologram.createForAllPlayers();