From bb24fb721f21753d3ceea89edb4530f01e1c1cf4 Mon Sep 17 00:00:00 2001 From: Leonard Steppy Date: Sat, 25 Oct 2025 16:15:32 +0200 Subject: [PATCH 01/16] Add givable items to ItemUtils --- .../java/net/coreprotect/utility/ItemUtils.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/coreprotect/utility/ItemUtils.java b/src/main/java/net/coreprotect/utility/ItemUtils.java index 97e2fa97a..503b0e7a1 100644 --- a/src/main/java/net/coreprotect/utility/ItemUtils.java +++ b/src/main/java/net/coreprotect/utility/ItemUtils.java @@ -37,6 +37,7 @@ import net.coreprotect.utility.serialize.ItemMetaHandler; public class ItemUtils { + private static final Set GIVABLE_ITEMS = Collections.synchronizedSet(new LinkedHashSet<>()); private static final Object UNSERIALIZABLE_VALUE = new Object(); private static final Logger LOGGER = Logger.getLogger("CoreProtect"); @@ -70,6 +71,20 @@ private ItemUtils() { throw new IllegalStateException("Utility class"); } + public static ItemStack getGivableItem(int id) { + if (id < 0 || id >= GIVABLE_ITEMS.size()) { + return null; + } + + return new ArrayList<>(GIVABLE_ITEMS).get(id); + } + + public static int makeGivableItem(ItemStack item) { + if (GIVABLE_ITEMS.add(item)) return GIVABLE_ITEMS.size(); + + return new ArrayList<>(GIVABLE_ITEMS).indexOf(item); + } + public static void mergeItems(Material material, ItemStack[] items) { if (material != null && (material.equals(Material.ARMOR_STAND) || BukkitAdapter.ADAPTER.isItemFrame(material))) { return; @@ -730,4 +745,4 @@ public static ItemStack unserializeItemStack(Object value) { return result; } -} +} From d6d1fba3271cba571c7f326fa0acee1a1e247397 Mon Sep 17 00:00:00 2001 From: Leonard Steppy Date: Sat, 25 Oct 2025 18:06:13 +0200 Subject: [PATCH 02/16] Improve performance of givable items methods --- .../java/net/coreprotect/utility/ItemUtils.java | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/main/java/net/coreprotect/utility/ItemUtils.java b/src/main/java/net/coreprotect/utility/ItemUtils.java index 503b0e7a1..12554af8c 100644 --- a/src/main/java/net/coreprotect/utility/ItemUtils.java +++ b/src/main/java/net/coreprotect/utility/ItemUtils.java @@ -7,7 +7,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; -import java.util.LinkedHashSet; +import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; @@ -37,7 +37,7 @@ import net.coreprotect.utility.serialize.ItemMetaHandler; public class ItemUtils { - private static final Set GIVABLE_ITEMS = Collections.synchronizedSet(new LinkedHashSet<>()); + private static final Map GIVABLE_ITEMS = Collections.synchronizedMap(new LinkedHashMap<>()); private static final Object UNSERIALIZABLE_VALUE = new Object(); private static final Logger LOGGER = Logger.getLogger("CoreProtect"); @@ -72,17 +72,12 @@ private ItemUtils() { } public static ItemStack getGivableItem(int id) { - if (id < 0 || id >= GIVABLE_ITEMS.size()) { - return null; - } - - return new ArrayList<>(GIVABLE_ITEMS).get(id); + //we can use skip here because it's a linked map from which elements are never removed + return GIVABLE_ITEMS.keySet().stream().skip(id).findFirst().orElse(null); } public static int makeGivableItem(ItemStack item) { - if (GIVABLE_ITEMS.add(item)) return GIVABLE_ITEMS.size(); - - return new ArrayList<>(GIVABLE_ITEMS).indexOf(item); + return GIVABLE_ITEMS.computeIfAbsent(item, k -> GIVABLE_ITEMS.size()); } public static void mergeItems(Material material, ItemStack[] items) { From 98f6f3db49f625b996445db670f42556a84f049f Mon Sep 17 00:00:00 2001 From: Leonard Steppy Date: Sat, 25 Oct 2025 18:46:55 +0200 Subject: [PATCH 03/16] Add ItemUtils#getItemStack --- .../net/coreprotect/utility/ItemUtils.java | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/main/java/net/coreprotect/utility/ItemUtils.java b/src/main/java/net/coreprotect/utility/ItemUtils.java index 12554af8c..b60c66b04 100644 --- a/src/main/java/net/coreprotect/utility/ItemUtils.java +++ b/src/main/java/net/coreprotect/utility/ItemUtils.java @@ -76,7 +76,11 @@ public static ItemStack getGivableItem(int id) { return GIVABLE_ITEMS.keySet().stream().skip(id).findFirst().orElse(null); } - public static int makeGivableItem(ItemStack item) { + public static Integer makeGivableItem(ItemStack item) { + if (item == null) { + return null; + } + return GIVABLE_ITEMS.computeIfAbsent(item, k -> GIVABLE_ITEMS.size()); } @@ -656,14 +660,21 @@ public static ItemMeta deserializeItemMeta(Class itemMetaCla return null; } - - public static String getEnchantments(byte[] metadata, int type, int amount) { + + public static ItemStack getItemStack(byte[] metadata, int type, int amount) { if (metadata == null) { - return ""; + return null; } ItemStack item = new ItemStack(MaterialUtils.getType(type), amount); item = (ItemStack) net.coreprotect.database.rollback.Rollback.populateItemStack(item, metadata)[2]; + return item; + } + + public static String getEnchantments(byte[] metadata, int type, int amount) { + var item = getItemStack(metadata, type, amount); + if (item == null) return ""; + String displayName = item.hasItemMeta() && item.getItemMeta().hasDisplayName() ? item.getItemMeta().getDisplayName() : ""; StringBuilder message = new StringBuilder(Color.ITALIC + displayName + Color.GREY); @@ -685,7 +696,7 @@ else if (!enchantments.isEmpty()) { return message.toString(); } - + public static Map serializeItemStackLegacy(ItemStack itemStack, String faceData, int slot) { Map result = new HashMap<>(); Map itemMap = serializeItemStack(itemStack, faceData, slot); From b24a8521f81d3706604566d1a36326f03660fd11 Mon Sep 17 00:00:00 2001 From: Leonard Steppy Date: Sat, 25 Oct 2025 18:53:06 +0200 Subject: [PATCH 04/16] Add ChatUtils#createGiveItemComponent --- src/main/java/net/coreprotect/utility/ChatUtils.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/net/coreprotect/utility/ChatUtils.java b/src/main/java/net/coreprotect/utility/ChatUtils.java index 8dbd9f614..a2c657be5 100644 --- a/src/main/java/net/coreprotect/utility/ChatUtils.java +++ b/src/main/java/net/coreprotect/utility/ChatUtils.java @@ -185,6 +185,14 @@ public static String createTooltip(String phrase, String tooltip) { return message.append(Chat.COMPONENT_TAG_CLOSE).toString(); } + public static String createGiveItemComponent(String phrase, String command, Integer itemId) { + if (itemId == null) { + return phrase; + } + + return Chat.COMPONENT_TAG_OPEN + Chat.COMPONENT_COMMAND + "|/" + command + " give " + itemId + "|" + phrase + Chat.COMPONENT_TAG_CLOSE; + } + // This theoretically initializes the component code, to prevent gson adapter errors public static void sendConsoleComponentStartup(ConsoleCommandSender consoleSender, String string) { Chat.sendComponent(consoleSender, Color.RESET + "[CoreProtect] " + string + Chat.COMPONENT_TAG_OPEN + Chat.COMPONENT_POPUP + "| | " + Chat.COMPONENT_TAG_CLOSE); From 3b3cd43ee677c0dbc37ae527960d93e65109f045 Mon Sep 17 00:00:00 2001 From: Leonard Steppy Date: Sat, 25 Oct 2025 18:54:31 +0200 Subject: [PATCH 05/16] Fix ChatUtils#createGiveItemComponent not returning empty String when no id is given --- src/main/java/net/coreprotect/utility/ChatUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/coreprotect/utility/ChatUtils.java b/src/main/java/net/coreprotect/utility/ChatUtils.java index a2c657be5..365978642 100644 --- a/src/main/java/net/coreprotect/utility/ChatUtils.java +++ b/src/main/java/net/coreprotect/utility/ChatUtils.java @@ -187,7 +187,7 @@ public static String createTooltip(String phrase, String tooltip) { public static String createGiveItemComponent(String phrase, String command, Integer itemId) { if (itemId == null) { - return phrase; + return ""; } return Chat.COMPONENT_TAG_OPEN + Chat.COMPONENT_COMMAND + "|/" + command + " give " + itemId + "|" + phrase + Chat.COMPONENT_TAG_CLOSE; From d03adae361b503603241b7658937adea7321ed3b Mon Sep 17 00:00:00 2001 From: Leonard Steppy Date: Sat, 25 Oct 2025 19:01:10 +0200 Subject: [PATCH 06/16] Add 'give item' components to StandardLookupThread --- .../coreprotect/command/lookup/StandardLookupThread.java | 6 ++++-- src/main/java/net/coreprotect/utility/ChatUtils.java | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/coreprotect/command/lookup/StandardLookupThread.java b/src/main/java/net/coreprotect/command/lookup/StandardLookupThread.java index cbeba9209..cafc01efc 100644 --- a/src/main/java/net/coreprotect/command/lookup/StandardLookupThread.java +++ b/src/main/java/net/coreprotect/command/lookup/StandardLookupThread.java @@ -292,6 +292,7 @@ else if (LookupActions.isInventoryLookup(actions)) { String dname = StringUtils.nameFilter(blockType.name().toLowerCase(Locale.ROOT), ddata); byte[] metadata = data[11] == null ? null : data[11].getBytes(StandardCharsets.ISO_8859_1); String tooltip = ItemUtils.getEnchantments(metadata, dtype, amount); + Integer itemId = ItemUtils.makeGivableItem(ItemUtils.getItemStack(metadata, dtype, amount)); String selector = Selector.FIRST; String tag = Color.WHITE + "-"; @@ -320,7 +321,7 @@ else if (daction == ItemTransactionActions.SELL || daction == ItemTransactionAct tag = (daction == ItemTransactionActions.REMOVE ? Color.GREEN + "+" : Color.RED + "-"); } - Chat.sendComponent(player, timeago + " " + tag + " " + Phrase.build(Phrase.LOOKUP_CONTAINER, Color.DARK_AQUA + rbd + dplayer + Color.WHITE + rbd, "x" + amount, ChatUtils.createTooltip(Color.DARK_AQUA + rbd + dname, tooltip) + Color.WHITE, selector)); + Chat.sendComponent(player, timeago + " " + tag + " " + Phrase.build(Phrase.LOOKUP_CONTAINER, Color.DARK_AQUA + rbd + dplayer + Color.WHITE + rbd, "x" + amount, ChatUtils.createTooltip(Color.DARK_AQUA + rbd + dname, tooltip) + ChatUtils.createGiveItemComponent(Color.GREY + "(↓)", command.getName(), itemId) + Color.WHITE, selector)); PluginChannelListener.getInstance().sendData(player, Integer.parseInt(time), Phrase.LOOKUP_CONTAINER, selector, dplayer, dname, amount, dataX, dataY, dataZ, wid, rbd, true, tag.contains("+")); } } @@ -389,6 +390,7 @@ else if (daction == ItemTransactionActions.SELL || daction == ItemTransactionAct if (actions.contains(LookupActions.CONTAINER) || actions.contains(5) || actions.contains(LookupActions.ITEM) || amount > -1) { byte[] metadata = data[11] == null ? null : data[11].getBytes(StandardCharsets.ISO_8859_1); String tooltip = ItemUtils.getEnchantments(metadata, dtype, amount); + Integer itemId = ItemUtils.makeGivableItem(ItemUtils.getItemStack(metadata, dtype, amount)); if (daction == ItemTransactionActions.DROP || daction == ItemTransactionActions.PICKUP) { phrase = Phrase.LOOKUP_ITEM; // {picked up|dropped} @@ -415,7 +417,7 @@ else if (daction == ItemTransactionActions.THROW || daction == ItemTransactionAc action = "a:container"; } - Chat.sendComponent(player, timeago + " " + tag + " " + Phrase.build(phrase, Color.DARK_AQUA + rbd + dplayer + Color.WHITE + rbd, "x" + amount, ChatUtils.createTooltip(Color.DARK_AQUA + rbd + dname, tooltip) + Color.WHITE, selector)); + Chat.sendComponent(player, timeago + " " + tag + " " + Phrase.build(phrase, Color.DARK_AQUA + rbd + dplayer + Color.WHITE + rbd, "x" + amount, ChatUtils.createTooltip(Color.DARK_AQUA + rbd + dname, tooltip) + ChatUtils.createGiveItemComponent(Color.GREY + "(↓)", command.getName(), itemId) + Color.WHITE, selector)); PluginChannelListener.getInstance().sendData(player, Integer.parseInt(time), phrase, selector, dplayer, dname, (tag.contains("+") ? 1 : -1), dataX, dataY, dataZ, wid, rbd, action.contains("container"), tag.contains("+")); } else { diff --git a/src/main/java/net/coreprotect/utility/ChatUtils.java b/src/main/java/net/coreprotect/utility/ChatUtils.java index 365978642..1124ec86c 100644 --- a/src/main/java/net/coreprotect/utility/ChatUtils.java +++ b/src/main/java/net/coreprotect/utility/ChatUtils.java @@ -190,7 +190,7 @@ public static String createGiveItemComponent(String phrase, String command, Inte return ""; } - return Chat.COMPONENT_TAG_OPEN + Chat.COMPONENT_COMMAND + "|/" + command + " give " + itemId + "|" + phrase + Chat.COMPONENT_TAG_CLOSE; + return Chat.COMPONENT_TAG_OPEN + Chat.COMPONENT_COMMAND + "|/" + command + " give #" + itemId + "|" + phrase + Chat.COMPONENT_TAG_CLOSE; } // This theoretically initializes the component code, to prevent gson adapter errors From 0ce3ec3a2ff491251bb988a16ea40d32c5fdc792 Mon Sep 17 00:00:00 2001 From: Leonard Steppy Date: Sat, 25 Oct 2025 19:22:25 +0200 Subject: [PATCH 07/16] Add GivableItemIdParser --- .../command/parser/GivableItemIdParser.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/main/java/net/coreprotect/command/parser/GivableItemIdParser.java diff --git a/src/main/java/net/coreprotect/command/parser/GivableItemIdParser.java b/src/main/java/net/coreprotect/command/parser/GivableItemIdParser.java new file mode 100644 index 000000000..628b88571 --- /dev/null +++ b/src/main/java/net/coreprotect/command/parser/GivableItemIdParser.java @@ -0,0 +1,19 @@ +package net.coreprotect.command.parser; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class GivableItemIdParser { + + protected static final Pattern PATTERN = Pattern.compile("#([0-9]+)"); + + public static Integer parseGivableItemId(String[] inputArguments) { + if (inputArguments.length > 0) { + Matcher matcher = PATTERN.matcher(inputArguments[0]); + if (matcher.find()) { + return Integer.parseInt(matcher.group(1)); + } + } + return null; + } +} From 34d42b669f35dc0271a90999467f17cc5c6c16da Mon Sep 17 00:00:00 2001 From: Leonard Steppy Date: Sat, 25 Oct 2025 19:25:35 +0200 Subject: [PATCH 08/16] Add CommandParser#parseGivableItemId --- .../java/net/coreprotect/command/CommandParser.java | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/main/java/net/coreprotect/command/CommandParser.java b/src/main/java/net/coreprotect/command/CommandParser.java index 56e855df9..84e0145d9 100644 --- a/src/main/java/net/coreprotect/command/CommandParser.java +++ b/src/main/java/net/coreprotect/command/CommandParser.java @@ -5,17 +5,11 @@ import java.util.Map; import java.util.Set; +import net.coreprotect.command.parser.*; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.command.CommandSender; -import net.coreprotect.command.parser.ActionParser; -import net.coreprotect.command.parser.LocationParser; -import net.coreprotect.command.parser.MaterialParser; -import net.coreprotect.command.parser.TimeParser; -import net.coreprotect.command.parser.UserParser; -import net.coreprotect.command.parser.WorldParser; - /** * Main parser class for CoreProtect commands. * Delegates to specialized parser classes for specific functionality. @@ -326,4 +320,7 @@ private static String timeString(BigDecimal input) { return input.stripTrailingZeros().toPlainString(); } + protected static Integer parseGivableItemId(String[] inputArguments) { + return GivableItemIdParser.parseGivableItemId(inputArguments); + } } From 0093c4d297048162ec0f047ff98e8a3639cfb308 Mon Sep 17 00:00:00 2001 From: Leonard Steppy Date: Sat, 25 Oct 2025 19:37:02 +0200 Subject: [PATCH 09/16] Add Phrase#INVALID_ITEM_ID --- src/main/java/net/coreprotect/language/Language.java | 1 + src/main/java/net/coreprotect/language/Phrase.java | 1 + 2 files changed, 2 insertions(+) diff --git a/src/main/java/net/coreprotect/language/Language.java b/src/main/java/net/coreprotect/language/Language.java index 37e7bda93..1d9ca23af 100644 --- a/src/main/java/net/coreprotect/language/Language.java +++ b/src/main/java/net/coreprotect/language/Language.java @@ -127,6 +127,7 @@ public static void loadPhrases() { phrases.put(Phrase.INVALID_INCLUDE, "\"{0}\" is an invalid block/entity name."); phrases.put(Phrase.INVALID_INCLUDE_COMBO, "That is an invalid block/entity combination."); phrases.put(Phrase.INVALID_PARAMETER, "\"{0}\" is not a supported parameter."); + phrases.put(Phrase.INVALID_ITEM_ID, "Please enter a valid item id."); phrases.put(Phrase.INVALID_RADIUS, "Please enter a valid radius."); phrases.put(Phrase.INVALID_SELECTION, "{0} selection not found."); phrases.put(Phrase.INVALID_USERNAME, "\"{0}\" is an invalid username."); diff --git a/src/main/java/net/coreprotect/language/Phrase.java b/src/main/java/net/coreprotect/language/Phrase.java index d844763e6..ab85c0fca 100644 --- a/src/main/java/net/coreprotect/language/Phrase.java +++ b/src/main/java/net/coreprotect/language/Phrase.java @@ -110,6 +110,7 @@ public enum Phrase { INVALID_INCLUDE, INVALID_INCLUDE_COMBO, INVALID_PARAMETER, + INVALID_ITEM_ID, INVALID_RADIUS, INVALID_SELECTION, INVALID_USERNAME, From bba4060a98abd1089ba486184b5add2230082044 Mon Sep 17 00:00:00 2001 From: Leonard Steppy Date: Sat, 25 Oct 2025 22:00:05 +0200 Subject: [PATCH 10/16] Add GiveCommand --- .../coreprotect/command/CommandHandler.java | 6 +++ .../net/coreprotect/command/GiveCommand.java | 40 +++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 src/main/java/net/coreprotect/command/GiveCommand.java diff --git a/src/main/java/net/coreprotect/command/CommandHandler.java b/src/main/java/net/coreprotect/command/CommandHandler.java index 03faf4e93..340f92a29 100755 --- a/src/main/java/net/coreprotect/command/CommandHandler.java +++ b/src/main/java/net/coreprotect/command/CommandHandler.java @@ -76,6 +76,9 @@ else if (user.hasPermission("coreprotect.consumer") && corecommand.equals("consu else if (user.hasPermission("coreprotect.networking") && corecommand.equals("network-debug")) { permission = true; } + else if (user.hasPermission("coreprotect.give") && corecommand.equals("give")) { + permission = true; + } } if (corecommand.equals("rollback") || corecommand.equals("restore") || corecommand.equals("rb") || corecommand.equals("rs") || corecommand.equals("ro") || corecommand.equals("re")) { @@ -120,6 +123,9 @@ else if (corecommand.equals("consumer")) { else if (corecommand.equals("network-debug")) { NetworkDebugCommand.runCommand(user, permission, argumentArray); } + else if (corecommand.equals("give")) { + GiveCommand.runCommand(user, command, permission, argumentArray); + } else if (corecommand.equals("migrate-db")) { if (!VersionUtils.validDonationKey()) { Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DONATION_KEY_REQUIRED)); diff --git a/src/main/java/net/coreprotect/command/GiveCommand.java b/src/main/java/net/coreprotect/command/GiveCommand.java new file mode 100644 index 000000000..0ab2d2b4c --- /dev/null +++ b/src/main/java/net/coreprotect/command/GiveCommand.java @@ -0,0 +1,40 @@ +package net.coreprotect.command; + +import net.coreprotect.language.Phrase; +import net.coreprotect.utility.Chat; +import net.coreprotect.utility.ChatMessage; +import net.coreprotect.utility.Color; +import net.coreprotect.utility.ItemUtils; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +public class GiveCommand { + public static void runCommand(CommandSender sender, Command command, boolean permission, String[] args) { + if (!permission) { + Chat.sendMessage(sender, new ChatMessage(Phrase.build(Phrase.NO_PERMISSION)).build()); + return; + } + + Integer itemId = CommandParser.parseGivableItemId(args); + if (itemId == null) { + Chat.sendMessage(sender, new ChatMessage(Phrase.build(Phrase.MISSING_PARAMETERS, Color.WHITE, "/" + command.getName() + " give ")).build()); + return; + } + + ItemStack item = ItemUtils.getGivableItem(itemId); + if (item == null) { + Chat.sendMessage(sender, new ChatMessage(Phrase.build(Phrase.INVALID_ITEM_ID)).build()); + return; + } + + if (!(sender instanceof Player)) { + Chat.sendMessage(sender, new ChatMessage(Phrase.build(Phrase.ACTION_NOT_SUPPORTED)).build()); + return; + } + + Player player = (Player) sender; + player.getInventory().addItem(item); + } +} From 2c9c317ba46a8e43cee44adb12302dbfa7cd9930 Mon Sep 17 00:00:00 2001 From: Leonard Steppy Date: Sat, 25 Oct 2025 22:01:27 +0200 Subject: [PATCH 11/16] Update permissions.md --- docs/permissions.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/permissions.md b/docs/permissions.md index 7ae600329..90237813b 100644 --- a/docs/permissions.md +++ b/docs/permissions.md @@ -39,6 +39,9 @@ The following permissions can be used to restrict functionality within the plugi * **coreprotect.consumer** *(default: op)* Allows access to the CoreProtect consumer command.   +* **coreprotect.give** *(default: op)* + Allows access to the CoreProtect give command. +   * **coreprotect.networking** *(default: op)* Allows access to the CoreProtect networking API. From 17c9b7f3330094a266a0ae6662d2c77c4ac44c16 Mon Sep 17 00:00:00 2001 From: Leonard Steppy Date: Sat, 25 Oct 2025 22:20:15 +0200 Subject: [PATCH 12/16] Fix itemId parsing --- .../net/coreprotect/command/parser/GivableItemIdParser.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/coreprotect/command/parser/GivableItemIdParser.java b/src/main/java/net/coreprotect/command/parser/GivableItemIdParser.java index 628b88571..ffa088477 100644 --- a/src/main/java/net/coreprotect/command/parser/GivableItemIdParser.java +++ b/src/main/java/net/coreprotect/command/parser/GivableItemIdParser.java @@ -8,8 +8,8 @@ public class GivableItemIdParser { protected static final Pattern PATTERN = Pattern.compile("#([0-9]+)"); public static Integer parseGivableItemId(String[] inputArguments) { - if (inputArguments.length > 0) { - Matcher matcher = PATTERN.matcher(inputArguments[0]); + for (String argument : inputArguments) { + Matcher matcher = PATTERN.matcher(argument); if (matcher.find()) { return Integer.parseInt(matcher.group(1)); } From f090b5a45dcdfa3ff83b5c536aa2b210a0f586f0 Mon Sep 17 00:00:00 2001 From: Leonard Steppy Date: Sat, 25 Oct 2025 18:06:13 +0200 Subject: [PATCH 13/16] Improve performance of givable items methods --- src/main/java/net/coreprotect/utility/ItemUtils.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/net/coreprotect/utility/ItemUtils.java b/src/main/java/net/coreprotect/utility/ItemUtils.java index b60c66b04..5efaf3749 100644 --- a/src/main/java/net/coreprotect/utility/ItemUtils.java +++ b/src/main/java/net/coreprotect/utility/ItemUtils.java @@ -7,7 +7,6 @@ import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; -import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; From b1053e6b5990d1230c39f78b268e492f1a76ac7a Mon Sep 17 00:00:00 2001 From: Leonard Steppy Date: Fri, 22 May 2026 14:02:41 +0200 Subject: [PATCH 14/16] Update coreprotect.give permission to be false by default --- docs/permissions.md | 2 +- src/main/resources/plugin.yml | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/permissions.md b/docs/permissions.md index 90237813b..ab6d9fae8 100644 --- a/docs/permissions.md +++ b/docs/permissions.md @@ -39,7 +39,7 @@ The following permissions can be used to restrict functionality within the plugi * **coreprotect.consumer** *(default: op)* Allows access to the CoreProtect consumer command.   -* **coreprotect.give** *(default: op)* +* **coreprotect.give** *(default: false)* Allows access to the CoreProtect give command.   * **coreprotect.networking** *(default: op)* diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 25c5ad3a3..037eb1617 100755 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -53,6 +53,7 @@ permissions: coreprotect.status: true coreprotect.consumer: true coreprotect.networking: true + coreprotect.give: true coreprotect.co: description: Has permission to access the CoreProtect /co command default: true @@ -144,3 +145,6 @@ permissions: coreprotect.networking: description: Has permission to use the networking API default: op + coreproctect.give: + description: Has permission to use the give command + default: false From 5982a99ab7fbf0576c40dbda0942134c91367692 Mon Sep 17 00:00:00 2001 From: Leonard Steppy Date: Fri, 22 May 2026 14:11:10 +0200 Subject: [PATCH 15/16] Only show give component if player has permission to use the command --- .../net/coreprotect/command/lookup/StandardLookupThread.java | 4 ++-- src/main/java/net/coreprotect/utility/ChatUtils.java | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/coreprotect/command/lookup/StandardLookupThread.java b/src/main/java/net/coreprotect/command/lookup/StandardLookupThread.java index cafc01efc..b95387229 100644 --- a/src/main/java/net/coreprotect/command/lookup/StandardLookupThread.java +++ b/src/main/java/net/coreprotect/command/lookup/StandardLookupThread.java @@ -321,7 +321,7 @@ else if (daction == ItemTransactionActions.SELL || daction == ItemTransactionAct tag = (daction == ItemTransactionActions.REMOVE ? Color.GREEN + "+" : Color.RED + "-"); } - Chat.sendComponent(player, timeago + " " + tag + " " + Phrase.build(Phrase.LOOKUP_CONTAINER, Color.DARK_AQUA + rbd + dplayer + Color.WHITE + rbd, "x" + amount, ChatUtils.createTooltip(Color.DARK_AQUA + rbd + dname, tooltip) + ChatUtils.createGiveItemComponent(Color.GREY + "(↓)", command.getName(), itemId) + Color.WHITE, selector)); + Chat.sendComponent(player, timeago + " " + tag + " " + Phrase.build(Phrase.LOOKUP_CONTAINER, Color.DARK_AQUA + rbd + dplayer + Color.WHITE + rbd, "x" + amount, ChatUtils.createTooltip(Color.DARK_AQUA + rbd + dname, tooltip) + ChatUtils.filterComponent(player.hasPermission("coreprotect.give"), ChatUtils.createGiveItemComponent(Color.GREY + "(↓)", command.getName(), itemId)) + Color.WHITE, selector)); PluginChannelListener.getInstance().sendData(player, Integer.parseInt(time), Phrase.LOOKUP_CONTAINER, selector, dplayer, dname, amount, dataX, dataY, dataZ, wid, rbd, true, tag.contains("+")); } } @@ -417,7 +417,7 @@ else if (daction == ItemTransactionActions.THROW || daction == ItemTransactionAc action = "a:container"; } - Chat.sendComponent(player, timeago + " " + tag + " " + Phrase.build(phrase, Color.DARK_AQUA + rbd + dplayer + Color.WHITE + rbd, "x" + amount, ChatUtils.createTooltip(Color.DARK_AQUA + rbd + dname, tooltip) + ChatUtils.createGiveItemComponent(Color.GREY + "(↓)", command.getName(), itemId) + Color.WHITE, selector)); + Chat.sendComponent(player, timeago + " " + tag + " " + Phrase.build(phrase, Color.DARK_AQUA + rbd + dplayer + Color.WHITE + rbd, "x" + amount, ChatUtils.createTooltip(Color.DARK_AQUA + rbd + dname, tooltip) + ChatUtils.filterComponent(player.hasPermission("coreprotect.give"), ChatUtils.createGiveItemComponent(Color.GREY + "(↓)", command.getName(), itemId)) + Color.WHITE, selector)); PluginChannelListener.getInstance().sendData(player, Integer.parseInt(time), phrase, selector, dplayer, dname, (tag.contains("+") ? 1 : -1), dataX, dataY, dataZ, wid, rbd, action.contains("container"), tag.contains("+")); } else { diff --git a/src/main/java/net/coreprotect/utility/ChatUtils.java b/src/main/java/net/coreprotect/utility/ChatUtils.java index 1124ec86c..e208d2455 100644 --- a/src/main/java/net/coreprotect/utility/ChatUtils.java +++ b/src/main/java/net/coreprotect/utility/ChatUtils.java @@ -197,4 +197,8 @@ public static String createGiveItemComponent(String phrase, String command, Inte public static void sendConsoleComponentStartup(ConsoleCommandSender consoleSender, String string) { Chat.sendComponent(consoleSender, Color.RESET + "[CoreProtect] " + string + Chat.COMPONENT_TAG_OPEN + Chat.COMPONENT_POPUP + "| | " + Chat.COMPONENT_TAG_CLOSE); } + + public static String filterComponent(boolean condition, String component) { + return condition ? component : ""; + } } \ No newline at end of file From d2bc9b39018a6fdf32a180d3e71d39728ce7be61 Mon Sep 17 00:00:00 2001 From: Leonard Steppy Date: Sat, 23 May 2026 00:01:49 +0200 Subject: [PATCH 16/16] Fix missing import which was accidentally removed during rebasing --- src/main/java/net/coreprotect/utility/ItemUtils.java | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/main/java/net/coreprotect/utility/ItemUtils.java b/src/main/java/net/coreprotect/utility/ItemUtils.java index 5efaf3749..1a2d05633 100644 --- a/src/main/java/net/coreprotect/utility/ItemUtils.java +++ b/src/main/java/net/coreprotect/utility/ItemUtils.java @@ -2,15 +2,7 @@ import java.io.ByteArrayOutputStream; import java.lang.reflect.Array; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern;