Skip to content

Commit 3bea8e9

Browse files
committed
Irpve logic for dublicate and blacklisted for menu.
1 parent 1b052ab commit 3bea8e9

6 files changed

Lines changed: 257 additions & 130 deletions

File tree

Menu Library/src/main/java/org/broken/arrow/library/menu/CheckItemsInsideMenu.java

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@
55
import org.broken.arrow.library.menu.utility.FilterMatch;
66
import org.broken.arrow.library.menu.utility.ItemCreator;
77
import org.broken.arrow.library.menu.utility.MatchCheckItemStack;
8+
import org.broken.arrow.library.menu.utility.message.BlacklistItemWrapper;
9+
import org.broken.arrow.library.menu.utility.message.DuplicatedItemWrapper;
810
import org.bukkit.Bukkit;
911
import org.bukkit.Location;
1012
import org.bukkit.Material;
1113
import org.bukkit.OfflinePlayer;
14+
import org.bukkit.World;
1215
import org.bukkit.entity.Player;
1316
import org.bukkit.inventory.Inventory;
1417
import org.bukkit.inventory.ItemStack;
@@ -265,13 +268,10 @@ private Map<Integer, ItemStack> addToMuchItems(final Map<Integer, ItemStack> ite
265268
* @param itemStack The item stack to return.
266269
*/
267270
private void addItemsBackToPlayer(final Player player, final ItemStack itemStack) {
268-
269-
final HashMap<Integer, ItemStack> ifInventorFull = player.getInventory().addItem(itemStack);
270-
if (!ifInventorFull.isEmpty() && player.getLocation().getWorld() != null)
271-
player.getLocation().getWorld().dropItemNaturally(player.getLocation(), ifInventorFull.get(0));
271+
this.returnsBackItems(player, itemStack);
272272

273273
if (!this.sendMsgPlayer) {
274-
this.registerMenuAPI.getMessages().sendBlacklistMessage(player, itemStack);
274+
this.registerMenuAPI.getMessages().sendBlacklistMessage(player, new BlacklistItemWrapper(itemStack.clone(), itemStack.getAmount()));
275275
this.sendMsgPlayer = true;
276276
}
277277
}
@@ -295,13 +295,8 @@ private void addItemsBackToPlayer(final Location location) {
295295
final OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(mapEntry.getKey());
296296
final Player player = offlinePlayer.getPlayer();
297297
if (player != null) {
298-
final HashMap<Integer, ItemStack> overflow = player.getInventory().addItem(itemStack);
299-
Location playerLocation = player.getLocation();
300-
if (!overflow.isEmpty() && playerLocation.getWorld() != null) {
301-
overflow.values().forEach(item ->
302-
playerLocation.getWorld().dropItemNaturally(playerLocation, item));
303-
}
304-
this.registerMenuAPI.getMessages().sendDuplicatedMessage(player, new SendMsgDuplicatedItems.DuplicatedItemWrapper(itemStack, mapEntry.getValue().size(), amount));
298+
this.returnsBackItems(player, itemStack);
299+
this.registerMenuAPI.getMessages().sendDuplicatedMessage(player, new DuplicatedItemWrapper(itemStack, mapEntry.getValue().size(), amount));
305300
} else if (location != null && location.getWorld() != null) {
306301
location.getWorld().dropItemNaturally(location, itemStack);
307302
}
@@ -310,6 +305,17 @@ private void addItemsBackToPlayer(final Location location) {
310305
}
311306
}
312307

308+
private void returnsBackItems(Player player, ItemStack itemStack) {
309+
final HashMap<Integer, ItemStack> overflow = player.getInventory().addItem(itemStack);
310+
final Location playerLocation = player.getLocation();
311+
final World world = playerLocation.getWorld();
312+
313+
if (!overflow.isEmpty() && world != null) {
314+
overflow.values().forEach(item ->
315+
world.dropItemNaturally(playerLocation, item));
316+
}
317+
}
318+
313319
/**
314320
* Checks whether the given item is blacklisted.
315321
*
@@ -401,7 +407,7 @@ public static class ItemOverflowBatch {
401407
*
402408
* @return map of material to its corresponding batch
403409
*/
404-
public Map<Material, Map<ItemStack, Integer>> getItems() {
410+
public Map<Material, Map<ItemStack, Integer>> getItems() {
405411
return items.entrySet().stream()
406412
.collect(Collectors.toMap(
407413
Map.Entry::getKey,
@@ -416,7 +422,7 @@ public Map<Material, Map<ItemStack, Integer>> getItems() {
416422
*
417423
* <p>Each insertion treats the first item of a new metadata group as the
418424
* "retained" item. Only the remaining amount is stored as overflow.</p>
419-
*
425+
* <p>
420426
* This method groups items by metadata and handles overflow automatically.
421427
*
422428
* @param itemStack the item to add (will be normalized to amount = 1 internally)
@@ -454,6 +460,7 @@ public static class MaterialOverflowBatch {
454460
public Map<ItemStack, Integer> getItems() {
455461
return Collections.unmodifiableMap(items);
456462
}
463+
457464
/**
458465
* Adds an item stack to this batch.
459466
*
@@ -470,9 +477,9 @@ public Map<ItemStack, Integer> getItems() {
470477
* </ul>
471478
*
472479
* @param itemStack the item to add (will be normalized to amount = 1)
473-
* @param amount the overflow amount derived from the item stack size
480+
* @param amount the overflow amount derived from the item stack size
474481
*/
475-
public void putItem(@Nonnull final ItemStack itemStack,final int amount) {
482+
public void putItem(@Nonnull final ItemStack itemStack, final int amount) {
476483
final ItemStack stackAsOne = ItemCreator.createItemStackAsOne(itemStack);
477484
items.compute(stackAsOne, (key, currentAmount) -> {
478485
if (currentAmount == null) {

Menu Library/src/main/java/org/broken/arrow/library/menu/messages/SendMsgDuplicatedItems.java

Lines changed: 30 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33

44
import net.md_5.bungee.api.ChatColor;
55
import org.broken.arrow.library.color.TextTranslator;
6-
import org.broken.arrow.library.menu.utility.DuplicateMessage;
6+
import org.broken.arrow.library.menu.utility.message.BlacklistItemWrapper;
7+
import org.broken.arrow.library.menu.utility.message.BlacklistMessage;
8+
import org.broken.arrow.library.menu.utility.message.DuplicateMessage;
9+
import org.broken.arrow.library.menu.utility.message.DuplicatedItemWrapper;
710
import org.broken.arrow.library.serialize.utility.converters.PlaceholderTranslator;
811
import org.bukkit.entity.Player;
912
import org.bukkit.inventory.ItemStack;
@@ -15,7 +18,7 @@
1518
* Set messages when player add duplicated items or items you have blacklisted.
1619
*/
1720
public class SendMsgDuplicatedItems {
18-
private Function<ItemStack, String> blacklistMessage;
21+
private BlacklistMessage blacklistMessage;
1922
private DuplicateMessage duplicatedMessage;
2023
private boolean notFoundTextTranslator;
2124

@@ -35,10 +38,12 @@ public SendMsgDuplicatedItems() {
3538
* Set message for when player have added item some are blacklisted.
3639
* Support both hex and &amp; color codes.
3740
*
38-
* <p><b>Supported color formats:</b></p>
41+
* <p><b>Formatting support:</b></p>
3942
* <ul>
40-
* <li>Hex colors: {@code <#8000ff>} or gradients like {@code <#8000ff:#ff0080>} (requires color conversion module).</li>
41-
* <li>Fallback to Spigot's legacy format: {@code &x&6&6&6&6&6&6}, or for white: {@code &x&F&F&F&F&F&F}, if color conversion is not enabled.</li>
43+
* <li>Legacy color codes: {@code &a}, {@code &f}, etc.</li>
44+
* <li>Legacy hex format (Spigot-compatible): {@code &x&R&R&G&G&B&B}</li>
45+
* <li>Hex colors: {@code <#RRGGBB>} and gradients like {@code <#RRGGBB:#RRGGBB>}
46+
* (supported when the internal formatter is available)</li>
4247
* </ul>
4348
*
4449
* <p>&nbsp;</p>
@@ -48,7 +53,7 @@ public SendMsgDuplicatedItems() {
4853
* @param blacklistMessage set a message.
4954
*/
5055
public void setBlacklistMessage(final String blacklistMessage) {
51-
this.blacklistMessage = itemStack -> blacklistMessage;
56+
this.blacklistMessage = (blacklistItemWrapper) -> blacklistMessage;
5257
}
5358

5459
/**
@@ -60,10 +65,12 @@ public void setBlacklistMessage(final String blacklistMessage) {
6065
* if you're using a localization file or want the text to be updated externally with minimal code changes.
6166
* </p>
6267
*
63-
* <p><b>Supported color formats:</b></p>
68+
* <p><b>Formatting support:</b></p>
6469
* <ul>
65-
* <li>Hex colors: {@code <#8000ff>} or gradients like {@code <#8000ff:#ff0080>} (requires the color conversion module).</li>
66-
* <li>Fallback to Spigot's legacy format: {@code &x&6&6&6&6&6&6}, or for white: {@code &x&F&F&F&F&F&F}, if color conversion is not enabled.</li>
70+
* <li>Legacy color codes: {@code &a}, {@code &f}, etc.</li>
71+
* <li>Legacy hex format (Spigot-compatible): {@code &x&R&R&G&G&B&B}</li>
72+
* <li>Hex colors: {@code <#RRGGBB>} and gradients like {@code <#RRGGBB:#RRGGBB>}
73+
* (supported when the internal formatter is available)</li>
6774
* </ul>
6875
*
6976
* <p><b>Available placeholders:</b></p>
@@ -85,7 +92,7 @@ public void setBlacklistMessage(final String blacklistMessage) {
8592
*
8693
* @param blacklistMessage a function that receives the {@link ItemStack} and returns the base message string to process.
8794
*/
88-
public void setBlacklistMessage(final Function<ItemStack, String> blacklistMessage) {
95+
public void setBlacklistMessage(final BlacklistMessage blacklistMessage) {
8996
this.blacklistMessage = blacklistMessage;
9097
}
9198

@@ -175,23 +182,30 @@ public void sendMessage(Player player, String msg) {
175182
* The message supports color codes and placeholder replacement.
176183
*
177184
* @param player the player to send the message to
178-
* @param itemStack the blacklisted item stack triggering the message
185+
* @param blacklistItemWrapper the blacklist wrapper for the item stack triggering the message
179186
*/
180-
public void sendBlacklistMessage(Player player, ItemStack itemStack) {
187+
public void sendBlacklistMessage(final Player player,@Nonnull final BlacklistItemWrapper blacklistItemWrapper) {
181188
String message;
182189
if (blacklistMessage == null) {
183190
message = "&fThis item&6 {0}&f are blacklisted and you get the items back.";
184191
} else {
185-
message = blacklistMessage.apply(itemStack.clone());
192+
message = blacklistMessage.apply(blacklistItemWrapper);
186193
}
187194

188195
if (message == null || message.isEmpty())
189196
return;
190197

191-
String itemName = itemStack.getType().name().toLowerCase();
198+
final PlaceholderTranslator.PlaceholderWrapper wrapper = blacklistItemWrapper.getPlaceholderWrapper();
199+
if (!wrapper.getPlaceholders().isEmpty())
200+
message = PlaceholderTranslator.translateText(message, wrapper);
201+
else {
202+
message = PlaceholderTranslator.translateText(message, blacklistItemWrapper.retrieveAsPlaceholderData());
203+
}
204+
192205
if (notFoundTextTranslator)
193-
player.sendMessage(ChatColor.translateAlternateColorCodes('&', (translatePlaceholders(message, itemName))));
194-
else player.sendMessage(TextTranslator.toSpigotFormat(translatePlaceholders(message, itemName)));
206+
player.sendMessage(ChatColor.translateAlternateColorCodes('&', message));
207+
else
208+
player.sendMessage(TextTranslator.toSpigotFormat(message));
195209
}
196210

197211
/**
@@ -240,98 +254,5 @@ public String translatePlaceholders(String rawText, Object... placeholders) {
240254
return rawText;
241255
}
242256

243-
/**
244-
* Wrapper class holding information about duplicated items for placeholder substitution.
245-
*/
246-
public static class DuplicatedItemWrapper {
247-
private final PlaceholderTranslator.PlaceholderWrapper placeholderWrapper;
248-
private final ItemStack itemStack;
249-
private final int size;
250-
private final int itemAmount;
251-
252-
/**
253-
* Constructs a new wrapper containing duplicated item data.
254-
*
255-
* @param itemStack the duplicated item stack
256-
* @param size the total number of duplicated stacks
257-
* @param itemAmount the total number of duplicated items
258-
*/
259-
public DuplicatedItemWrapper(final ItemStack itemStack, final int size, final int itemAmount) {
260-
this.placeholderWrapper = new PlaceholderTranslator.PlaceholderWrapper();
261-
this.itemStack = itemStack;
262-
this.size = size;
263-
this.itemAmount = itemAmount;
264-
}
265-
266-
/**
267-
* Returns the duplicated item stack.
268-
*
269-
* @return the item stack
270-
*/
271-
public ItemStack getItemStack() {
272-
return itemStack.clone();
273-
}
274-
275-
/**
276-
* Returns the total number of duplicated stacks.
277-
*
278-
* @return duplicated stacks count
279-
*/
280-
public int getSize() {
281-
return size;
282-
}
283-
284-
/**
285-
* Returns the total number of duplicated items.
286-
*
287-
* @return duplicated item count
288-
*/
289-
public int getItemAmount() {
290-
return itemAmount;
291-
}
292-
293-
/**
294-
* Returns a {@link PlaceholderTranslator.PlaceholderWrapper} for defining custom
295-
* key-based placeholders instead of using the default indexed placeholder system.
296-
*
297-
* <p>If no custom placeholders are provided, the system falls back to
298-
* {@link #retrieveAsPlaceholderData()}, which uses ordered placeholders such as
299-
* {@code {0}}, {@code {1}}, {@code {2}}.</p>
300-
*
301-
* <p>When this wrapper contains entries, it is used instead and allows named
302-
* placeholders.</p>
303-
*
304-
* <p><b>Example (default indexed placeholders):</b></p>
305-
* <pre>
306-
* {@code "&fYou can't add more if this &6 {0} &ftype, you get back &6 {2} &fitems. You have added totally &4 {1} &fextra itemstacks"}
307-
* </pre>
308-
*
309-
* <p><b>Example (custom named placeholders):</b></p>
310-
* <pre>
311-
* {@code
312-
* wrapper.put("{type}", itemStack.getType())
313-
.put("{addedStacks}", size)
314-
.put("{returnedItems}", itemAmount);
315-
}
316-
*
317-
* "&fYou can't add more if this &6 {type} &ftype, you get back &6 {returnedItems} &fitems.
318-
* You have added totally &4 {addedStacks} &fextra itemstacks"
319-
* </pre>
320-
*
321-
* @return the {@link PlaceholderTranslator.PlaceholderWrapper} for custom placeholders
322-
*/
323-
public PlaceholderTranslator.PlaceholderWrapper getPlaceholderWrapper() {
324-
return placeholderWrapper;
325-
}
326257

327-
/**
328-
* Returns an array of objects to be used as placeholders in messages:
329-
* item type, duplicated stacks count, and duplicated items count.
330-
*
331-
* @return an array of placeholder data objects
332-
*/
333-
public Object[] retrieveAsPlaceholderData() {
334-
return new Object[]{itemStack.getType(), size, itemAmount};
335-
}
336-
}
337258
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package org.broken.arrow.library.menu.utility.message;
2+
3+
import org.broken.arrow.library.serialize.utility.converters.PlaceholderTranslator;
4+
import org.bukkit.inventory.ItemStack;
5+
6+
/**
7+
* Wrapper class holding information about blacklisted items for placeholder substitution.
8+
*/
9+
public class BlacklistItemWrapper {
10+
private final PlaceholderTranslator.PlaceholderWrapper placeholderWrapper;
11+
private final ItemStack itemStack;
12+
private final int size;
13+
14+
/**
15+
* Constructs a new wrapper containing blacklisted items data.
16+
*
17+
* @param itemStack the blacklisted item stack
18+
* @param size the total number of blacklisted items
19+
*/
20+
public BlacklistItemWrapper(final ItemStack itemStack, final int size) {
21+
this.placeholderWrapper = new PlaceholderTranslator.PlaceholderWrapper();
22+
this.itemStack = itemStack;
23+
this.size = size;
24+
}
25+
26+
/**
27+
* Returns the blacklisted item stack.
28+
*
29+
* @return the item stack
30+
*/
31+
public ItemStack getItemStack() {
32+
return itemStack.clone();
33+
}
34+
35+
/**
36+
* Returns the total number of items returned back.
37+
*
38+
* @return duplicated stacks count
39+
*/
40+
public int getSize() {
41+
return size;
42+
}
43+
44+
45+
/**
46+
* Returns a {@link PlaceholderTranslator.PlaceholderWrapper} for defining custom
47+
* key-based placeholders instead of using the default indexed placeholder system.
48+
*
49+
* <p>If no custom placeholders are provided, the system falls back to
50+
* {@link #retrieveAsPlaceholderData()}, which uses ordered placeholders such as
51+
* {@code {0}}, {@code {1}}, {@code {2}}.</p>
52+
*
53+
* <p>When this wrapper contains entries, it is used instead and allows named
54+
* placeholders.</p>
55+
*
56+
* <p><b>Example (default indexed placeholders):</b></p>
57+
* <pre>
58+
* {@code "&fYou can't add more if this &6 {0} &ftype, you get back &6 {2} &fitems. You have added totally &4 {1} &fextra itemstacks"}
59+
* </pre>
60+
*
61+
* <p><b>Example (custom named placeholders):</b></p>
62+
* <pre>
63+
* {@code
64+
* wrapper.put("{type}", itemStack.getType())
65+
* .put("{addedStacks}", size)
66+
* .put("{returnedItems}", itemAmount);
67+
* }
68+
* {@code "&fYou can't add more if this &6 {type} &ftype, you get back &6 {returnedItems} &fitems. You have added totally &4 {addedStacks} &fextra itemstacks"}
69+
* </pre>
70+
*
71+
* @return the {@link PlaceholderTranslator.PlaceholderWrapper} for custom placeholders
72+
*/
73+
public PlaceholderTranslator.PlaceholderWrapper getPlaceholderWrapper() {
74+
return placeholderWrapper;
75+
}
76+
77+
/**
78+
* Returns an array of objects to be used as placeholders in messages:
79+
* item type, duplicated stacks count, and duplicated items count.
80+
*
81+
* @return an array of placeholder data objects
82+
*/
83+
public Object[] retrieveAsPlaceholderData() {
84+
return new Object[]{itemStack.getType(), size};
85+
}
86+
}

0 commit comments

Comments
 (0)