diff --git a/README.md b/README.md index 595aa439..fe38dba2 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ View the Spigot page (with FAQ and install instructions) [here](https://www.spig Check the [wiki](https://github.com/espidev/ProtectionStones/wiki) for plugin reference information. ### Dependencies -* ProtectionStones 2.10.5 +* ProtectionStones 2.10.6 * Spigot 1.20.6+ * WorldGuard 7.0.9+ * WorldEdit 7.2.6+ diff --git a/pom.xml b/pom.xml index 37940957..39ee6ede 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 dev.espi protectionstones - 2.10.5 + 2.10.6 ProtectionStones A grief prevention plugin for Spigot Minecraft servers. https://github.com/espidev/ProtectionStones @@ -207,13 +207,13 @@ org.spigotmc spigot-api - 1.20.6-R0.1-SNAPSHOT + 1.21.5-R0.1-SNAPSHOT provided com.sk89q.worldguard worldguard-bukkit - 7.0.9-SNAPSHOT + 7.1.0-SNAPSHOT provided @@ -231,7 +231,7 @@ com.sk89q.worldedit worldedit-bukkit - 7.2.6-SNAPSHOT + 7.4.0-SNAPSHOT provided diff --git a/src/main/java/dev/espi/protectionstones/commands/ArgAdminHelp.java b/src/main/java/dev/espi/protectionstones/commands/ArgAdminHelp.java index c224df2b..0f5a0a00 100644 --- a/src/main/java/dev/espi/protectionstones/commands/ArgAdminHelp.java +++ b/src/main/java/dev/espi/protectionstones/commands/ArgAdminHelp.java @@ -16,7 +16,8 @@ package dev.espi.protectionstones.commands; import dev.espi.protectionstones.ProtectionStones; -import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.ClickEvent; import net.md_5.bungee.api.chat.HoverEvent; import net.md_5.bungee.api.chat.TextComponent; import org.bukkit.ChatColor; @@ -24,32 +25,140 @@ public class ArgAdminHelp { - private static void send(CommandSender p, String text, String info) { - TextComponent tc = new TextComponent(text); - tc.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(info).create())); - p.spigot().sendMessage(tc); + private static void send(CommandSender p, String text, String info, String clickCommand, boolean run) { + // Create the main text component from legacy text. + BaseComponent[] mainComponents = TextComponent.fromLegacyText(text); + TextComponent mainText = new TextComponent(""); + for (BaseComponent component : mainComponents) { + mainText.addExtra(component); + } + + // Create the hover event from the info text, add click event after + BaseComponent[] hoverComponents = TextComponent.fromLegacyText(info); + mainText.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, hoverComponents)); + //toggle for running on mouse click, currently disabled + if (run) { + mainText.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, ChatColor.stripColor(clickCommand))); + } else { + mainText.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, ChatColor.stripColor(clickCommand))); + } + + // Send the assembled message. + p.spigot().sendMessage(mainText); } static boolean argumentAdminHelp(CommandSender p, String[] args) { - String bc = "/" + ProtectionStones.getInstance().getConfigOptions().base_command; - - p.sendMessage(ChatColor.DARK_GRAY + "" + ChatColor.STRIKETHROUGH + "=====" + ChatColor.RESET + " PS Admin Help " + ChatColor.DARK_GRAY + ChatColor.STRIKETHROUGH + "=====\n" + ChatColor.AQUA + "> " + ChatColor.GRAY + "/ps admin help"); - send(p, ChatColor.AQUA + "> " + ChatColor.GRAY + bc + " admin version", "Show the version number of the plugin."); - send(p, ChatColor.AQUA + "> " + ChatColor.GRAY + bc + " admin hide", "Hide all of the protection stone blocks in the world you are in."); - send(p, ChatColor.AQUA + "> " + ChatColor.GRAY + bc + " admin unhide", "Unhide all of the protection stone blocks in the world you are in."); - send(p, ChatColor.AQUA + "> " + ChatColor.GRAY + bc + " admin cleanup remove [days] [-t typealias (optional)] [world (console)]", "Remove inactive players that haven't joined within the last [days] days from protected regions in the world you are in (or specified). Then, remove any regions with no owners left."); - send(p, ChatColor.AQUA + "> " + ChatColor.GRAY + bc + " admin cleanup disown [days] [-t typealias (optional)] [world (console)]", "Remove inactive players that haven't joined within the last [days] days from protected regions in the world you are in (or specified)."); - send(p, ArgAdmin.getFlagHelp(), "Set a flag for all protection stone regions in a world."); - send(p, ChatColor.AQUA + "> " + ChatColor.GRAY + bc + " admin lastlogon [player]", "Get the last time a player logged on."); - send(p, ChatColor.AQUA + "> " + ChatColor.GRAY + bc + " admin lastlogons", "List all of the last logons of each player."); - send(p, ChatColor.AQUA + "> " + ChatColor.GRAY + bc + " admin stats [player (optional)]", "Show some statistics of the plugin."); - send(p, ChatColor.AQUA + "> " + ChatColor.GRAY + bc + " admin recreate", "Recreate all PS regions using radius set in config."); - send(p, ChatColor.AQUA + "> " + ChatColor.GRAY + bc + " admin debug", "Toggles debug mode."); - send(p, ChatColor.AQUA + "> " + ChatColor.GRAY + bc + " admin settaxautopayers", "Add a tax autopayer for every region on the server that does not have one."); - send(p, ArgAdmin.getForceMergeHelp(), "Merge overlapping PS regions together if they have the same owners, members and flags."); - send(p, ArgAdmin.getChangeBlockHelp(), "Change all of the PS blocks and regions in a world to a different block. Both blocks must be configured in config."); - send(p, ArgAdmin.getChangeRegionTypeHelp(), "Change the internal type of all PS regions of a certain type. Useful for error correction."); - send(p, ChatColor.AQUA + "> " + ChatColor.GRAY + bc + " admin fixregions", "Use this command to recalculate block types for PS regions in a world."); + String baseCommand = ProtectionStones.getInstance().getConfigOptions().base_command; + String bc = "/" + baseCommand; + String tx = ChatColor.AQUA + "> " + ChatColor.GRAY + bc; + + p.sendMessage(ChatColor.DARK_GRAY + "" + ChatColor.STRIKETHROUGH + "===============" + + ChatColor.RESET + " PS Admin Help " + + ChatColor.DARK_GRAY + ChatColor.STRIKETHROUGH + "===============\n"); + + send(p, + tx + " admin version", + "Show the version number of the plugin.\n\n" + bc + " admin version", + baseCommand + " admin version", + false); + + send(p, + tx + " admin hide", + "Hide all of the protection stone blocks in the world you are in.\n\n" + bc + " admin hide", + bc + " admin hide", + false); + + send(p, + tx + " admin unhide", + "Unhide all of the protection stone blocks in the world you are in.\n\n" + bc + " admin unhide", + bc + " admin unhide", + false); + + send(p, + tx + " admin cleanup remove", + "Remove inactive players that haven't joined within the last [days] days from protected regions in the world you are in (or specified). Then, remove any regions with no owners left.\n\n" + + bc + " admin cleanup remove [days] [-t typealias (optional)] [world (console)]", + bc + " admin cleanup remove", + false); + + send(p, + tx + " admin cleanup disown", + "Remove inactive players that haven't joined within the last [days] days from protected regions in the world you are in (or specified).\n\n" + + bc + " admin cleanup disown", + bc + " admin cleanup disown", + false); + + send(p, + tx + " admin flag", + "Set a flag for all protection stone regions in a world.\n\n" + + bc + " admin flag [world] [flagname] [value|null|default]", + bc + " admin flag [world] [flagname] [value|null|default]", + false); + + send(p, + tx + " admin lastlogon", + "Get the last time a player logged on.\n\n" + bc + " admin lastlogon [player]", + bc + " admin lastlogon", + false); + + send(p, + tx + " admin lastlogons", + "List all of the last logons of each player.\n\n" + bc + " admin lastlogons", + bc + " admin lastlogons", + false); + + send(p, + tx + " admin stats", + "Show some statistics of the plugin.\n\n" + bc + " admin stats [player (optional)]", + bc + " admin stats", + false); + + send(p, + tx + " admin recreate", + "Recreate all PS regions using radius set in config.\n\n" + bc + " admin recreate", + bc + " admin recreate", + false); + + send(p, + tx + " admin debug", + "Toggle debug mode.\n\n" + bc + " admin debug", + bc + " admin debug", + false); + + send(p, + tx + " admin settaxautopayers", + "Add a tax autopayer for every region on the server that does not have one.\n\n" + bc + " admin settaxautopayers", + bc + " admin settaxautopayers", + false); + + send(p, + tx + " admin forcemerge", + "Merge overlapping PS regions together if they have the same owners, members and flags.\n\n" + + bc + " admin forcemerge [world]", + bc + " admin forcemerge [world]", + false); + + send(p, + tx + " admin changeblock", + "Change all of the PS blocks and regions in a world to a different block. Both blocks must be configured in config.\n\n" + + bc + " admin changeblock [world] [oldtypealias] [newtypealias]", + bc + " admin changeblock [world] [oldtypealias] [newtypealias]", + false); + + send(p, + tx + " admin changeregiontype", + "Change the internal type of all PS regions of a certain type. Useful for error correction.\n\n" + + bc + " admin changeregiontype [world] [oldtype] [newtype]", + bc + " admin changeregiontype [world] [oldtype] [newtype]", + false); + + send(p, + tx + " admin fixregions", + "Use this command to recalculate block types for PS regions in a world.\n\n" + bc + " admin fixregions", + bc + " admin fixregions", + false); + //add footer since it was missing + p.sendMessage(ChatColor.DARK_GRAY + "" + ChatColor.STRIKETHROUGH + "============================================="); return true; } diff --git a/src/main/java/dev/espi/protectionstones/commands/ArgFlag.java b/src/main/java/dev/espi/protectionstones/commands/ArgFlag.java index 829bdad2..486108d9 100644 --- a/src/main/java/dev/espi/protectionstones/commands/ArgFlag.java +++ b/src/main/java/dev/espi/protectionstones/commands/ArgFlag.java @@ -118,8 +118,8 @@ private boolean openFlagGUI(Player p, PSRegion r, int page) { } // add line based on flag type + boolean isGroupValueAll = groupfValue.equalsIgnoreCase("all") || groupfValue.isEmpty();; if (f instanceof StateFlag) { // allow/deny - boolean isGroupValueAll = groupfValue.equalsIgnoreCase("all") || groupfValue.isEmpty(); TextComponent allow = new TextComponent((fValue == StateFlag.State.ALLOW ? ChatColor.WHITE : ChatColor.DARK_GRAY) + "Allow"), deny = new TextComponent((fValue == StateFlag.State.DENY ? ChatColor.WHITE : ChatColor.DARK_GRAY) + "Deny"); @@ -138,14 +138,6 @@ private boolean openFlagGUI(Player p, PSRegion r, int page) { deny.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, suggestedCommand + flagGroup + page + ":" + flag + " deny")); } - // HACK: Prevent pvp flag value from being changed to none/null, if it is set to a value with the group flag set to all - if (flag.equalsIgnoreCase("pvp") && isGroupValueAll) { - if (fValue == StateFlag.State.DENY) { - deny.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(PSL.FLAG_PREVENT_EXPLOIT_HOVER.msg()).create())); - } else if (fValue == StateFlag.State.ALLOW) { - allow.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(PSL.FLAG_PREVENT_EXPLOIT_HOVER.msg()).create())); - } - } flagLine.addExtra(allow); flagLine.addExtra(" "); @@ -193,15 +185,27 @@ private boolean openFlagGUI(Player p, PSRegion r, int page) { // set hover and click task for flag group BaseComponent[] hover; - if (fValue == null) { + // HACK: Prevent pvp flag value from being changed to none/null + // Special handling for "pvp" flag with "all" group, disabling interaction. + if (flag.equalsIgnoreCase("pvp") && isGroupValueAll) { + hover = new ComponentBuilder(PSL.FLAG_PREVENT_EXPLOIT_HOVER.msg()).create(); + // Remove click action to fully disable changing this group. + groupChange.setClickEvent(null); + } else if (fValue == null) { hover = new ComponentBuilder(PSL.FLAG_GUI_HOVER_CHANGE_GROUP_NULL.msg()).create(); } else { hover = new ComponentBuilder(PSL.FLAG_GUI_HOVER_CHANGE_GROUP.msg().replace("%group%", nextGroup)).create(); } - if (!nextGroup.equals(groupfValue)) { // only display hover message if the group is not the same + + // Always set hover if the flag is pvp and group is "all" + if (flag.equalsIgnoreCase("pvp") && groupfValue.equalsIgnoreCase("all")) { + hover = new ComponentBuilder(PSL.FLAG_PREVENT_EXPLOIT_HOVER.msg()).create(); + groupChange.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, hover)); + groupChange.setClickEvent(null); // Disable click event explicitly + } else if (!nextGroup.equals(groupfValue)) { groupChange.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, hover)); + groupChange.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, suggestedCommand + "-g " + nextGroup + " " + page + ":" + flag + " " + fValue)); } - groupChange.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, suggestedCommand + "-g " + nextGroup + " " + page + ":" + flag + " " + fValue)); flagLine.addExtra(groupChange); // send message diff --git a/src/main/java/dev/espi/protectionstones/event/PSBreakProtectBlockEvent.java b/src/main/java/dev/espi/protectionstones/event/PSBreakProtectBlockEvent.java index 289a0fff..04455cda 100644 --- a/src/main/java/dev/espi/protectionstones/event/PSBreakProtectBlockEvent.java +++ b/src/main/java/dev/espi/protectionstones/event/PSBreakProtectBlockEvent.java @@ -6,7 +6,6 @@ import org.bukkit.event.Event; import org.bukkit.event.HandlerList; import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; import java.util.Objects; @@ -65,7 +64,6 @@ public void setCancelled(boolean cancel) { isCancelled = cancel; } - @NotNull @Override public HandlerList getHandlers() { return HANDLERS; diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index c5ad41a3..14c4232b 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,7 +1,7 @@ name: ProtectionStones version: ${version} description: ${description} -authors: [EspiDev] +authors: [EspiDev, Jerzean] depend: [WorldGuard, WorldEdit] softdepend: [Vault, PlaceholderAPI, LuckPerms]