Skip to content

Commit b5c4bc1

Browse files
authored
Merge pull request #448 from jerzean/master
crafter fix/support Update ps admin command update ps view to be stronger visually update Player heads tested on mc 1.21.11 this breaks support for sub versions due to player_head/ crafter fixes
2 parents 1565497 + 82c9a69 commit b5c4bc1

File tree

7 files changed

+201
-60
lines changed

7 files changed

+201
-60
lines changed

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<modelVersion>4.0.0</modelVersion>
44
<groupId>dev.espi</groupId>
55
<artifactId>protectionstones</artifactId>
6-
<version>2.10.5</version>
6+
<version>2.10.7</version>
77
<name>ProtectionStones</name>
88
<description>A grief prevention plugin for Spigot Minecraft servers.</description>
99
<url>https://github.com/espidev/ProtectionStones</url>
@@ -207,7 +207,7 @@
207207
<dependency>
208208
<groupId>org.spigotmc</groupId>
209209
<artifactId>spigot-api</artifactId>
210-
<version>1.20.6-R0.1-SNAPSHOT</version>
210+
<version>1.21.10-R0.1-SNAPSHOT</version>
211211
<scope>provided</scope>
212212
</dependency>
213213
<dependency>

src/main/java/dev/espi/protectionstones/ListenerClass.java

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,7 @@
3333
import org.bukkit.ChatColor;
3434
import org.bukkit.Material;
3535
import org.bukkit.World;
36-
import org.bukkit.block.Block;
37-
import org.bukkit.block.BlockFace;
38-
import org.bukkit.block.BlockState;
39-
import org.bukkit.block.Furnace;
36+
import org.bukkit.block.*;
4037
import org.bukkit.command.CommandSender;
4138
import org.bukkit.enchantments.Enchantment;
4239
import org.bukkit.entity.Player;
@@ -53,6 +50,7 @@
5350
import org.bukkit.event.player.PlayerJoinEvent;
5451
import org.bukkit.event.player.PlayerTeleportEvent;
5552
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
53+
import org.bukkit.inventory.Inventory;
5654
import org.bukkit.inventory.ItemStack;
5755

5856
import java.util.List;
@@ -307,6 +305,22 @@ public void onPrepareItemCraft(PrepareItemCraftEvent e) {
307305
}
308306
}
309307

308+
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
309+
public void onCrafter(CrafterCraftEvent e) {
310+
Block block = e.getBlock();
311+
BlockState state = block.getState();
312+
if (block.getType() != Material.CRAFTER) return;
313+
if (!(state instanceof Container container)) return;
314+
Inventory inv = container.getInventory();
315+
for (ItemStack item : inv.getContents()) {
316+
if (item == null) continue;
317+
PSProtectBlock options = ProtectionStones.getBlockOptions(item);
318+
if (options != null && !options.allowUseInCrafting) {
319+
e.setCancelled(true);
320+
e.setResult(new ItemStack(Material.AIR));
321+
}
322+
}
323+
}
310324

311325
// -=-=-=- disable grindstone inventory to prevent infinite exp exploit with enchanted_effect option -=-=-=-
312326
// see https://github.com/espidev/ProtectionStones/issues/324

src/main/java/dev/espi/protectionstones/commands/ArgAdminHelp.java

Lines changed: 133 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,40 +16,149 @@
1616
package dev.espi.protectionstones.commands;
1717

1818
import dev.espi.protectionstones.ProtectionStones;
19-
import net.md_5.bungee.api.chat.ComponentBuilder;
19+
import net.md_5.bungee.api.chat.BaseComponent;
20+
import net.md_5.bungee.api.chat.ClickEvent;
2021
import net.md_5.bungee.api.chat.HoverEvent;
2122
import net.md_5.bungee.api.chat.TextComponent;
2223
import org.bukkit.ChatColor;
2324
import org.bukkit.command.CommandSender;
2425

2526
public class ArgAdminHelp {
2627

27-
private static void send(CommandSender p, String text, String info) {
28-
TextComponent tc = new TextComponent(text);
29-
tc.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(info).create()));
30-
p.spigot().sendMessage(tc);
28+
private static void send(CommandSender p, String text, String info, String clickCommand, boolean run) {
29+
// Create the main text component from legacy text.
30+
BaseComponent[] mainComponents = TextComponent.fromLegacyText(text);
31+
TextComponent mainText = new TextComponent("");
32+
for (BaseComponent component : mainComponents) {
33+
mainText.addExtra(component);
34+
}
35+
36+
// Create the hover event from the info text, add click event after
37+
BaseComponent[] hoverComponents = TextComponent.fromLegacyText(info);
38+
mainText.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, hoverComponents));
39+
//toggle for running on mouse click, currently disabled
40+
if (run) {
41+
mainText.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, ChatColor.stripColor(clickCommand)));
42+
} else {
43+
mainText.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, ChatColor.stripColor(clickCommand)));
44+
}
45+
46+
// Send the assembled message.
47+
p.spigot().sendMessage(mainText);
3148
}
3249

3350
static boolean argumentAdminHelp(CommandSender p, String[] args) {
34-
String bc = "/" + ProtectionStones.getInstance().getConfigOptions().base_command;
35-
36-
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");
37-
send(p, ChatColor.AQUA + "> " + ChatColor.GRAY + bc + " admin version", "Show the version number of the plugin.");
38-
send(p, ChatColor.AQUA + "> " + ChatColor.GRAY + bc + " admin hide", "Hide all of the protection stone blocks in the world you are in.");
39-
send(p, ChatColor.AQUA + "> " + ChatColor.GRAY + bc + " admin unhide", "Unhide all of the protection stone blocks in the world you are in.");
40-
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.");
41-
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).");
42-
send(p, ArgAdmin.getFlagHelp(), "Set a flag for all protection stone regions in a world.");
43-
send(p, ChatColor.AQUA + "> " + ChatColor.GRAY + bc + " admin lastlogon [player]", "Get the last time a player logged on.");
44-
send(p, ChatColor.AQUA + "> " + ChatColor.GRAY + bc + " admin lastlogons", "List all of the last logons of each player.");
45-
send(p, ChatColor.AQUA + "> " + ChatColor.GRAY + bc + " admin stats [player (optional)]", "Show some statistics of the plugin.");
46-
send(p, ChatColor.AQUA + "> " + ChatColor.GRAY + bc + " admin recreate", "Recreate all PS regions using radius set in config.");
47-
send(p, ChatColor.AQUA + "> " + ChatColor.GRAY + bc + " admin debug", "Toggles debug mode.");
48-
send(p, ChatColor.AQUA + "> " + ChatColor.GRAY + bc + " admin settaxautopayers", "Add a tax autopayer for every region on the server that does not have one.");
49-
send(p, ArgAdmin.getForceMergeHelp(), "Merge overlapping PS regions together if they have the same owners, members and flags.");
50-
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.");
51-
send(p, ArgAdmin.getChangeRegionTypeHelp(), "Change the internal type of all PS regions of a certain type. Useful for error correction.");
52-
send(p, ChatColor.AQUA + "> " + ChatColor.GRAY + bc + " admin fixregions", "Use this command to recalculate block types for PS regions in a world.");
51+
String baseCommand = ProtectionStones.getInstance().getConfigOptions().base_command;
52+
String bc = "/" + baseCommand;
53+
String tx = ChatColor.AQUA + "> " + ChatColor.GRAY + "/" + bc;
54+
55+
p.sendMessage(ChatColor.DARK_GRAY + "" + ChatColor.STRIKETHROUGH + "===============" +
56+
ChatColor.RESET + " PS Admin Help " +
57+
ChatColor.DARK_GRAY + ChatColor.STRIKETHROUGH + "===============\n");
58+
59+
send(p,
60+
tx + " admin version",
61+
"Show the version number of the plugin.\n\n" + bc + " admin version",
62+
baseCommand + " admin version",
63+
false);
64+
65+
send(p,
66+
tx + " admin hide",
67+
"Hide all of the protection stone blocks in the world you are in.\n\n" + bc + " admin hide",
68+
bc + " admin hide",
69+
false);
70+
71+
send(p,
72+
tx + " admin unhide",
73+
"Unhide all of the protection stone blocks in the world you are in.\n\n" + bc + " admin unhide",
74+
bc + " admin unhide",
75+
false);
76+
77+
send(p,
78+
tx + " admin cleanup remove",
79+
"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" +
80+
bc + " admin cleanup remove [days] [-t typealias (optional)] [world (console)]",
81+
bc + " admin cleanup remove",
82+
false);
83+
84+
send(p,
85+
tx + " admin cleanup disown",
86+
"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" +
87+
bc + " admin cleanup disown",
88+
bc + " admin cleanup disown",
89+
false);
90+
91+
send(p,
92+
tx + " admin flag",
93+
"Set a flag for all protection stone regions in a world.\n\n" +
94+
bc + " admin flag [world] [flagname] [value|null|default]",
95+
bc + " admin flag [world] [flagname] [value|null|default]",
96+
false);
97+
98+
send(p,
99+
tx + " admin lastlogon",
100+
"Get the last time a player logged on.\n\n" + bc + " admin lastlogon [player]",
101+
bc + " admin lastlogon",
102+
false);
103+
104+
send(p,
105+
tx + " admin lastlogons",
106+
"List all of the last logons of each player.\n\n" + bc + " admin lastlogons",
107+
bc + " admin lastlogons",
108+
false);
109+
110+
send(p,
111+
tx + " admin stats",
112+
"Show some statistics of the plugin.\n\n" + bc + " admin stats [player (optional)]",
113+
bc + " admin stats",
114+
false);
115+
116+
send(p,
117+
tx + " admin recreate",
118+
"Recreate all PS regions using radius set in config.\n\n" + bc + " admin recreate",
119+
bc + " admin recreate",
120+
false);
121+
122+
send(p,
123+
tx + " admin debug",
124+
"Toggle debug mode.\n\n" + bc + " admin debug",
125+
bc + " admin debug",
126+
false);
127+
128+
send(p,
129+
tx + " admin settaxautopayers",
130+
"Add a tax autopayer for every region on the server that does not have one.\n\n" + bc + " admin settaxautopayers",
131+
bc + " admin settaxautopayers",
132+
false);
133+
134+
send(p,
135+
tx + " admin forcemerge",
136+
"Merge overlapping PS regions together if they have the same owners, members and flags.\n\n" +
137+
bc + " admin forcemerge [world]",
138+
bc + " admin forcemerge [world]",
139+
false);
140+
141+
send(p,
142+
tx + " admin changeblock",
143+
"Change all of the PS blocks and regions in a world to a different block. Both blocks must be configured in config.\n\n" +
144+
bc + " admin changeblock [world] [oldtypealias] [newtypealias]",
145+
bc + " admin changeblock [world] [oldtypealias] [newtypealias]",
146+
false);
147+
148+
send(p,
149+
tx + " admin changeregiontype",
150+
"Change the internal type of all PS regions of a certain type. Useful for error correction.\n\n" +
151+
bc + " admin changeregiontype [world] [oldtype] [newtype]",
152+
bc + " admin changeregiontype [world] [oldtype] [newtype]",
153+
false);
154+
155+
send(p,
156+
tx + " admin fixregions",
157+
"Use this command to recalculate block types for PS regions in a world.\n\n" + bc + " admin fixregions",
158+
bc + " admin fixregions",
159+
false);
160+
//add footer since it was missing
161+
p.sendMessage(ChatColor.DARK_GRAY + "" + ChatColor.STRIKETHROUGH + "=============================================");
53162

54163
return true;
55164
}

src/main/java/dev/espi/protectionstones/commands/ArgFlag.java

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,8 @@ private boolean openFlagGUI(Player p, PSRegion r, int page) {
118118
}
119119

120120
// add line based on flag type
121+
boolean isGroupValueAll = groupfValue.equalsIgnoreCase("all") || groupfValue.isEmpty();;
121122
if (f instanceof StateFlag) { // allow/deny
122-
boolean isGroupValueAll = groupfValue.equalsIgnoreCase("all") || groupfValue.isEmpty();
123123

124124
TextComponent allow = new TextComponent((fValue == StateFlag.State.ALLOW ? ChatColor.WHITE : ChatColor.DARK_GRAY) + "Allow"),
125125
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) {
138138
deny.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, suggestedCommand + flagGroup + page + ":" + flag + " deny"));
139139
}
140140

141-
// 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
142-
if (flag.equalsIgnoreCase("pvp") && isGroupValueAll) {
143-
if (fValue == StateFlag.State.DENY) {
144-
deny.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(PSL.FLAG_PREVENT_EXPLOIT_HOVER.msg()).create()));
145-
} else if (fValue == StateFlag.State.ALLOW) {
146-
allow.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(PSL.FLAG_PREVENT_EXPLOIT_HOVER.msg()).create()));
147-
}
148-
}
149141

150142
flagLine.addExtra(allow);
151143
flagLine.addExtra(" ");
@@ -193,15 +185,27 @@ private boolean openFlagGUI(Player p, PSRegion r, int page) {
193185

194186
// set hover and click task for flag group
195187
BaseComponent[] hover;
196-
if (fValue == null) {
188+
// HACK: Prevent pvp flag value from being changed to none/null
189+
// Special handling for "pvp" flag with "all" group, disabling interaction.
190+
if (flag.equalsIgnoreCase("pvp") && isGroupValueAll) {
191+
hover = new ComponentBuilder(PSL.FLAG_PREVENT_EXPLOIT_HOVER.msg()).create();
192+
// Remove click action to fully disable changing this group.
193+
groupChange.setClickEvent(null);
194+
} else if (fValue == null) {
197195
hover = new ComponentBuilder(PSL.FLAG_GUI_HOVER_CHANGE_GROUP_NULL.msg()).create();
198196
} else {
199197
hover = new ComponentBuilder(PSL.FLAG_GUI_HOVER_CHANGE_GROUP.msg().replace("%group%", nextGroup)).create();
200198
}
201-
if (!nextGroup.equals(groupfValue)) { // only display hover message if the group is not the same
199+
200+
// Always set hover if the flag is pvp and group is "all"
201+
if (flag.equalsIgnoreCase("pvp") && groupfValue.equalsIgnoreCase("all")) {
202+
hover = new ComponentBuilder(PSL.FLAG_PREVENT_EXPLOIT_HOVER.msg()).create();
202203
groupChange.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, hover));
204+
groupChange.setClickEvent(null); // Disable click event explicitly
205+
} else if (!nextGroup.equals(groupfValue)) {
206+
groupChange.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, hover));
207+
groupChange.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, suggestedCommand + "-g " + nextGroup + " " + page + ":" + flag + " " + fValue));
203208
}
204-
groupChange.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, suggestedCommand + "-g " + nextGroup + " " + page + ":" + flag + " " + fValue));
205209

206210
flagLine.addExtra(groupChange);
207211
// send message
@@ -251,7 +255,7 @@ public boolean executeArgument(CommandSender s, String[] args, HashMap<String, S
251255

252256
// /ps flag GUI
253257
if (args.length == 1) return openFlagGUI(p, r, 0);
254-
258+
255259
// go to GUI page
256260
if (args.length == 2) {
257261
if (MiscUtil.isValidInteger(args[1])) {

src/main/java/dev/espi/protectionstones/utils/BlockUtil.java

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,26 +18,23 @@
1818
import dev.espi.protectionstones.PSProtectBlock;
1919
import dev.espi.protectionstones.ProtectionStones;
2020
import org.bukkit.Bukkit;
21-
import org.bukkit.Location;
2221
import org.bukkit.Material;
2322
import org.bukkit.OfflinePlayer;
2423
import org.bukkit.block.Block;
2524
import org.bukkit.block.Skull;
26-
import org.bukkit.entity.ArmorStand;
27-
import org.bukkit.entity.Entity;
2825
import org.bukkit.inventory.ItemStack;
2926
import org.bukkit.inventory.meta.SkullMeta;
3027
import org.bukkit.profile.PlayerProfile;
3128
import org.bukkit.profile.PlayerTextures;
29+
import org.json.simple.JSONObject;
30+
import org.json.simple.parser.JSONParser;
31+
import org.json.simple.parser.ParseException;
3232

3333
import java.net.MalformedURLException;
3434
import java.net.URL;
35+
import java.util.Base64;
3536
import java.util.HashMap;
3637
import java.util.UUID;
37-
import java.util.Base64;
38-
import org.json.simple.JSONObject;
39-
import org.json.simple.parser.JSONParser;
40-
import org.json.simple.parser.ParseException;
4138

4239
public class BlockUtil {
4340
static final int MAX_USERNAME_LENGTH = 16;
@@ -71,12 +68,13 @@ public static String getProtectBlockType(ItemStack i) {
7168
}
7269

7370
// PLAYER_HEAD:base64
74-
if (ProtectionStones.getBlockOptions("PLAYER_HEAD:" + sm.getOwningPlayer().getUniqueId()) != null) {
75-
return Material.PLAYER_HEAD + ":" + sm.getOwningPlayer().getUniqueId();
71+
PlayerProfile offlineProfile = sm.getOwnerProfile();
72+
if (ProtectionStones.getBlockOptions("PLAYER_HEAD:" +offlineProfile.getUniqueId()) != null) {
73+
return Material.PLAYER_HEAD + ":" +offlineProfile.getUniqueId();
7674
}
7775

7876
// PLAYER_HEAD:name
79-
return Material.PLAYER_HEAD + ":" + sm.getOwningPlayer().getName(); // return name if it doesn't exist
77+
return Material.PLAYER_HEAD + ":" + offlineProfile.getName(); // return name if it doesn't exist
8078
}
8179
return i.getType().toString();
8280
}
@@ -86,13 +84,13 @@ public static String getProtectBlockType(Block block) {
8684

8785
Skull s = (Skull) block.getState();
8886
if (s.hasOwner() && isOwnedSkullTypeConfigured()) {
89-
OfflinePlayer op = s.getOwningPlayer();
90-
if (ProtectionStones.getBlockOptions("PLAYER_HEAD:" + op.getUniqueId()) != null) {
87+
PlayerProfile offlineProfile = s.getOwnerProfile();
88+
if (ProtectionStones.getBlockOptions("PLAYER_HEAD:" + offlineProfile.getUniqueId()) != null) {
9189
// PLAYER_HEAD:base64
92-
return Material.PLAYER_HEAD + ":" + op.getUniqueId();
90+
return Material.PLAYER_HEAD + ":" + offlineProfile.getUniqueId();
9391
} else {
9492
// PLAYER_HEAD:name
95-
return Material.PLAYER_HEAD + ":" + op.getName(); // return name if doesn't exist
93+
return Material.PLAYER_HEAD + ":" + offlineProfile.getName(); // return name if doesn't exist
9694
}
9795
} else { // PLAYER_HEAD
9896
return Material.PLAYER_HEAD.toString();
@@ -203,4 +201,4 @@ public static String getUUIDFromBase64PS(PSProtectBlock b) {
203201
// see github issue #126
204202
return new UUID(base64.hashCode(), base64.hashCode()).toString();
205203
}
206-
}
204+
}

0 commit comments

Comments
 (0)