Skip to content

Commit 64f0d18

Browse files
committed
feat: support legacy versions
1 parent 1b965dc commit 64f0d18

File tree

11 files changed

+124
-70
lines changed

11 files changed

+124
-70
lines changed

build.gradle

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ repositories {
2020

2121
dependencies {
2222
implementation('it.unimi.dsi:fastutil:8.5.15')
23-
compileOnly("io.papermc.paper:paper-api:1.21.5-R0.1-SNAPSHOT")
23+
implementation("net.kyori:adventure-api:4.23.0")
24+
compileOnly("net.kyori:adventure-text-serializer-legacy:4.23.0")
25+
compileOnly('org.spigotmc:spigot-api:1.8.8-R0.1-SNAPSHOT')
2426
compileOnly('org.jetbrains:annotations:26.0.2')
2527

2628
testImplementation platform('org.junit:junit-bom:5.10.0')

src/main/java/pt/supercrafting/menu/Menu.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package pt.supercrafting.menu;
22

3-
import it.unimi.dsi.fastutil.Function;
43
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
54
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
65
import it.unimi.dsi.fastutil.ints.Int2ObjectMaps;
76
import net.kyori.adventure.text.Component;
7+
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
88
import org.bukkit.Bukkit;
99
import org.bukkit.entity.Player;
1010
import org.bukkit.event.inventory.InventoryType;
@@ -58,10 +58,11 @@ protected Menu(@NotNull Component title, @NotNull InventoryType type, int size)
5858

5959
this.clickProcessor = new MenuClickProcessor(this);
6060

61+
String legacyTitle = LegacyComponentSerializer.legacySection().serialize(title);
6162
if(type == InventoryType.CHEST)
62-
this.handle = Bukkit.createInventory(this, size, title);
63+
this.handle = Bukkit.createInventory(this, size, legacyTitle);
6364
else
64-
this.handle = Bukkit.createInventory(this, type, title);
65+
this.handle = Bukkit.createInventory(this, type, legacyTitle);
6566
}
6667

6768
public void refresh() {

src/main/java/pt/supercrafting/menu/MenuClickProcessor.java

Lines changed: 55 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@
44
import com.google.common.cache.CacheBuilder;
55
import com.google.common.collect.HashMultimap;
66
import com.google.common.collect.Multimap;
7-
import io.papermc.paper.entity.PlayerGiveResult;
87
import it.unimi.dsi.fastutil.ints.*;
9-
import net.kyori.adventure.text.Component;
108
import org.bukkit.Bukkit;
119
import org.bukkit.entity.Player;
1210
import org.bukkit.event.inventory.*;
@@ -17,7 +15,7 @@
1715
import org.bukkit.plugin.Plugin;
1816
import org.jetbrains.annotations.ApiStatus;
1917
import org.jetbrains.annotations.NotNull;
20-
import pt.supercrafting.menu.editor.MenuUpdatable;
18+
import pt.supercrafting.menu.bridge.ItemBridge;
2119
import pt.supercrafting.menu.item.MenuItem;
2220
import pt.supercrafting.menu.slot.MenuSlot;
2321

@@ -56,10 +54,10 @@ final class MenuClickProcessor {
5654
));
5755

5856
if(hasBundleActions) {
59-
defaultBehaviors.add(InventoryAction.PICKUP_ALL_INTO_BUNDLE);
60-
defaultBehaviors.add(InventoryAction.PLACE_ALL_INTO_BUNDLE);
61-
defaultBehaviors.add(InventoryAction.PICKUP_SOME_INTO_BUNDLE);
62-
defaultBehaviors.add(InventoryAction.PLACE_SOME_INTO_BUNDLE);
57+
defaultBehaviors.add(getInventoryAction("PLACE_ALL_INTO_BUNDLE"));
58+
defaultBehaviors.add(getInventoryAction("PICKUP_ALL_INTO_BUNDLE"));
59+
defaultBehaviors.add(getInventoryAction("PICKUP_SOME_INTO_BUNDLE"));
60+
defaultBehaviors.add(getInventoryAction("PLACE_SOME_INTO_BUNDLE"));
6361
}
6462

6563
DEFAULT_BEHAVIORS = Collections.unmodifiableSet(defaultBehaviors);
@@ -80,6 +78,15 @@ final class MenuClickProcessor {
8078
REVERSED_PLAYER_INVENTORY_SLOTS = IntLists.unmodifiable(reversedPrioritySlots);
8179
}
8280

81+
@NotNull
82+
private static InventoryAction getInventoryAction(@NotNull String name) {
83+
try {
84+
return InventoryAction.valueOf(name);
85+
} catch (IllegalArgumentException e) {
86+
throw new IllegalArgumentException("Invalid InventoryAction name: " + name, e);
87+
}
88+
}
89+
8390
private final Menu menu;
8491
private final Cache<UUID, Boolean> closeCache = CacheBuilder.newBuilder()
8592
.expireAfterWrite(250, TimeUnit.MILLISECONDS)
@@ -120,7 +127,7 @@ private void clickMenu(@NotNull InventoryClickEvent event) {
120127

121128
ClickType clickType = event.getClick();
122129
ItemStack cursor = event.getCursor();
123-
boolean isAdd = !cursor.isEmpty() && !clickType.isShiftClick();
130+
boolean isAdd = !ItemBridge.isEmpty(cursor) && !clickType.isShiftClick();
124131

125132
boolean handled;
126133
if(isAdd) {
@@ -149,7 +156,7 @@ private void clickMenu(@NotNull InventoryClickEvent event) {
149156
IntList slots = new IntArrayList(PLAYER_INVENTORY_SLOTS.size());
150157
for (int i = 0; i < inventory.getSize(); i++) {
151158
ItemStack itemStack = inventory.getItem(i);
152-
if(itemStack != null && !itemStack.isEmpty() && itemStack.isSimilar(result))
159+
if(itemStack != null && !ItemBridge.isEmpty(itemStack) && itemStack.isSimilar(result))
153160
slots.add(i);
154161
}
155162

@@ -161,31 +168,31 @@ private void clickMenu(@NotNull InventoryClickEvent event) {
161168

162169
ItemStack playerItem = inventory.getItem(playerSlot);
163170
if(playerItem == null)
164-
playerItem = ItemStack.empty();
171+
playerItem = ItemBridge.empty();
165172

166-
if(!playerItem.isEmpty() && !playerItem.isSimilar(result))
173+
if(!ItemBridge.isEmpty(playerItem) && !playerItem.isSimilar(result))
167174
continue;
168175

169-
int allowedToAdd = playerItem.isEmpty() ? result.getMaxStackSize() : playerItem.getMaxStackSize() - playerItem.getAmount();
176+
int allowedToAdd = ItemBridge.isEmpty(playerItem) ? result.getMaxStackSize() : playerItem.getMaxStackSize() - playerItem.getAmount();
170177
if(allowedToAdd <= 0)
171178
continue;
172179

173180
int toAdd = Math.min(allowedToAdd, result.getAmount());
174-
ItemStack newPlayerItem = result.asQuantity(playerItem.getAmount() + toAdd);
181+
ItemStack newPlayerItem = ItemBridge.asQuantity(playerItem, playerItem.getAmount() + toAdd);
175182
inventory.setItem(playerSlot, newPlayerItem);
176183

177-
result = result.asQuantity(result.getAmount() - toAdd);
184+
result = ItemBridge.asQuantity(result, result.getAmount() - toAdd);
178185
if(result.getAmount() <= 0)
179186
break;
180187

181188
}
182189

183-
if(!result.isEmpty()) {
190+
if(!ItemBridge.isEmpty(result)) {
184191
MenuSlot.Add add = new MenuSlot.PlayerAdd(result, result.getAmount(), player);
185192
slot.add(add);
186193

187194
ItemStack remaining = add.getResult();
188-
if(!remaining.isEmpty()) // Drop overflow items
195+
if(!ItemBridge.isEmpty(remaining)) // Drop overflow items
189196
player.getWorld().dropItemNaturally(player.getLocation(), remaining);
190197
}
191198

@@ -222,23 +229,30 @@ private void clickHotBar(@NotNull InventoryClickEvent event) {
222229
Inventory inventory = player.getInventory();
223230

224231
ItemStack hotbarItem =inventory.getItem(hotbarButton);
225-
if(hotbarItem != null && !hotbarItem.isEmpty()) {
232+
if(hotbarItem != null && ItemBridge.isEmpty(hotbarItem)) {
226233

227234
MenuSlot.Add add = new MenuSlot.PlayerAdd(hotbarItem, hotbarItem.getAmount(), player);
228235
slot.add(add);
229236

230237
ItemStack remaining = add.getResult();
231-
if(remaining.isEmpty())
232-
remaining = ItemStack.empty();
238+
if(ItemBridge.isEmpty(remaining))
239+
remaining = ItemBridge.empty();
233240

234241
inventory.setItem(hotbarButton, remaining);
235242
}
236243

237244
hotbarItem = inventory.getItem(hotbarButton); // Updated
238-
if(hotbarItem == null || hotbarItem.isEmpty())
245+
if(hotbarItem == null || ItemBridge.isEmpty(hotbarItem))
239246
player.getInventory().setItem(hotbarButton, result);
240-
else
241-
player.give(hotbarItem);
247+
else {
248+
//player.give(hotbarItem);
249+
Map<Integer, ItemStack> overflow = player.getInventory().addItem(hotbarItem);
250+
for (ItemStack drop : overflow.values()) {
251+
if(!ItemBridge.isEmpty(drop)) {
252+
player.getWorld().dropItemNaturally(player.getLocation(), drop);
253+
}
254+
}
255+
}
242256

243257
menu.refresh();
244258
}
@@ -259,18 +273,18 @@ private void clickInventory(@NotNull InventoryClickEvent event) {
259273

260274
ItemStack playerItem = playerInventory.getItem(slot);
261275
if(playerItem == null)
262-
playerItem = ItemStack.empty();
263-
if(playerItem.isEmpty() || !playerItem.isSimilar(cursor))
276+
playerItem = ItemBridge.empty();
277+
if(ItemBridge.isEmpty(playerItem) || !playerItem.isSimilar(cursor))
264278
continue;
265279

266280
int allowedToAdd = cursor.getMaxStackSize() - cursor.getAmount();
267281
if(allowedToAdd <= 0)
268282
continue;
269283

270284
int toAdd = Math.min(allowedToAdd, playerItem.getAmount());
271-
ItemStack newCursor = cursor.asQuantity(cursor.getAmount() + toAdd);
285+
ItemStack newCursor = ItemBridge.asQuantity(cursor, cursor.getAmount() + toAdd);
272286

273-
ItemStack newPlayerItem = playerItem.asQuantity(playerItem.getAmount() - toAdd);
287+
ItemStack newPlayerItem = ItemBridge.asQuantity(playerItem, playerItem.getAmount() - toAdd);
274288
playerInventory.setItem(slot, newPlayerItem);
275289
cursor = newCursor;
276290

@@ -281,7 +295,7 @@ private void clickInventory(@NotNull InventoryClickEvent event) {
281295
}
282296

283297
ItemStack currentItem = event.getCurrentItem();
284-
if(currentItem == null || currentItem.isEmpty())
298+
if(currentItem == null || ItemBridge.isEmpty(currentItem))
285299
return;
286300

287301
if(DEFAULT_BEHAVIORS.contains(action))
@@ -334,7 +348,7 @@ public void drag(@NotNull InventoryDragEvent event) {
334348
InventoryView view = event.getView();
335349
for (int slot : slots) {
336350

337-
Inventory inventory = view.getInventory(slot);
351+
Inventory inventory = slot < view.getTopInventory().getSize() ? view.getTopInventory() : view.getBottomInventory();
338352
if (inventory == null)
339353
continue;
340354

@@ -353,7 +367,7 @@ public void drag(@NotNull InventoryDragEvent event) {
353367

354368
IntList draggedSlots = new IntArrayList(slotsByInventory.get(menuInventory));
355369
ItemStack cursor = event.getOldCursor();
356-
if(cursor.isEmpty())
370+
if(ItemBridge.isEmpty(cursor))
357371
return;
358372

359373
event.setCancelled(false);
@@ -374,23 +388,29 @@ public void drag(@NotNull InventoryDragEvent event) {
374388
menuSlot.add(add);
375389

376390
ItemStack result = add.getResult();
377-
if(!result.isEmpty() && !result.isSimilar(cursor)) {
391+
if(!ItemBridge.isEmpty(result) && !result.isSimilar(cursor)) {
378392
overFlow.add(result);
379393
} else if(result.isSimilar(cursor) && !add.isSuccessful())
380394
giveBack += amountPerSlot;
381395

382396
}
383397

384-
ItemStack newCursor = cursor.asQuantity(giveBack);
398+
ItemStack newCursor = ItemBridge.asQuantity(cursor, giveBack);
385399
event.setCursor(newCursor);
386400

387401
Plugin plugin = MenuManager.instance.getPlugin();
388-
player.getScheduler().runDelayed(plugin, (s) -> menu.refresh(), () -> {}, 3);
402+
//player.getScheduler().runDelayed(plugin, (s) -> menu.refresh(), () -> {}, 3);
389403

390-
if(!overFlow.isEmpty())
391-
player.give(overFlow);
404+
if(!overFlow.isEmpty()) {
405+
//player.give(overFlow);
406+
for (ItemStack itemStack : overFlow) {
407+
if(!ItemBridge.isEmpty(itemStack)) {
408+
player.getWorld().dropItemNaturally(player.getLocation(), itemStack);
409+
}
410+
}
411+
}
392412

393-
//Bukkit.getScheduler().runTaskLater(plugin, menu::refresh, 1); // Think about a better way to do this
413+
Bukkit.getScheduler().runTaskLater(plugin, menu::refresh, 1); // Think about a better way to do this
394414

395415
}
396416

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package pt.supercrafting.menu.bridge;
2+
3+
import org.bukkit.Material;
4+
import org.bukkit.inventory.ItemStack;
5+
import org.jetbrains.annotations.ApiStatus;
6+
import org.jetbrains.annotations.NotNull;
7+
import org.jetbrains.annotations.Nullable;
8+
9+
@ApiStatus.Internal
10+
public final class ItemBridge {
11+
12+
private ItemBridge() {
13+
throw new UnsupportedOperationException("This class cannot be instantiated.");
14+
}
15+
16+
@NotNull
17+
public static ItemStack asQuantity(@NotNull ItemStack itemStack, int quantity) {
18+
if (quantity <= 0) {
19+
return empty();
20+
}
21+
ItemStack newItemStack = itemStack.clone();
22+
newItemStack.setAmount(quantity);
23+
return newItemStack;
24+
}
25+
26+
public static boolean isEmpty(@Nullable ItemStack itemStack) {
27+
return itemStack == null || itemStack.getType() == Material.AIR || itemStack.getAmount() <= 0;
28+
}
29+
30+
@NotNull
31+
public static ItemStack empty() {
32+
return new ItemStack(Material.AIR);
33+
}
34+
35+
}

src/main/java/pt/supercrafting/menu/editor/decoration/MenuDecorations.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,7 @@ abstract class MenuDecorations implements MenuDecoration {
1717

1818
public MenuDecorations(@NotNull ItemStack icon) {
1919
Objects.requireNonNull(icon);
20-
21-
ItemStack noHover = icon.clone();
22-
noHover.editMeta(meta -> meta.setHideTooltip(true));
23-
this.slot = new ForbiddenSlot(noHover);
20+
this.slot = new ForbiddenSlot(icon);
2421
}
2522

2623
protected abstract int @NotNull[] generateSlots(int rows);

src/main/java/pt/supercrafting/menu/item/MenuItem.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import org.bukkit.event.inventory.InventoryClickEvent;
66
import org.bukkit.inventory.ItemStack;
77
import org.jetbrains.annotations.NotNull;
8+
import pt.supercrafting.menu.bridge.ItemBridge;
89
import pt.supercrafting.menu.slot.MenuSlot;
910

1011
import java.util.Objects;
@@ -49,7 +50,7 @@ public Click(@NotNull Player player, int slot, @NotNull ItemStack cursor, @NotNu
4950

5051
@Override
5152
public @NotNull ItemStack itemStack() {
52-
return ItemStack.empty();
53+
return ItemBridge.empty();
5354
}
5455

5556
@Override
Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package pt.supercrafting.menu.plugin;
22

3-
import net.kyori.adventure.text.Component;
4-
import net.kyori.adventure.text.format.NamedTextColor;
53
import org.bukkit.plugin.java.JavaPlugin;
64
import pt.supercrafting.menu.MenuManager;
75

@@ -11,14 +9,14 @@ public final class MenuPlugin extends JavaPlugin {
119
public void onEnable() {
1210
MenuManager.init(this);
1311

14-
getComponentLogger().info(Component.text("MenuAPI has been enabled!", NamedTextColor.GREEN));
12+
getLogger().info("MenuAPI has been enabled!");
1513
}
1614

1715
@Override
1816
public void onDisable() {
1917
MenuManager.shutdown();
2018

21-
getComponentLogger().info(Component.text("MenuAPI has been disabled!", NamedTextColor.RED));
19+
getLogger().info("MenuAPI has been disabled!");
2220
}
2321

2422
}

src/main/java/pt/supercrafting/menu/slot/ForbiddenSlot.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22

33
import org.bukkit.inventory.ItemStack;
44
import org.jetbrains.annotations.NotNull;
5+
import pt.supercrafting.menu.bridge.ItemBridge;
56

67
public record ForbiddenSlot(@NotNull ItemStack icon) implements MenuSlot {
78

89
public static final ForbiddenSlot INSTANCE = new ForbiddenSlot();
910

1011
private ForbiddenSlot() {
11-
this(ItemStack.empty());
12+
this(ItemBridge.empty());
1213
}
1314

1415
@Override
@@ -18,7 +19,7 @@ private ForbiddenSlot() {
1819

1920
@Override
2021
public @NotNull ItemStack itemStack() {
21-
return ItemStack.empty();
22+
return ItemBridge.empty();
2223
}
2324

2425
@Override

0 commit comments

Comments
 (0)