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]