mirror of
https://github.com/PaperMC/Paper.git
synced 2025-01-02 17:32:03 +01:00
#1414: Convert InventoryView to interface
By: Miles Holder <mwholder2005@gmail.com>
This commit is contained in:
parent
6af115230a
commit
d2d0972bc3
4 changed files with 238 additions and 2 deletions
|
@ -0,0 +1,221 @@
|
|||
package org.bukkit.craftbukkit.inventory;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryView;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public abstract class CraftAbstractInventoryView implements InventoryView {
|
||||
|
||||
@Override
|
||||
public void setItem(final int slot, @Nullable final ItemStack item) {
|
||||
Inventory inventory = getInventory(slot);
|
||||
if (inventory != null) {
|
||||
inventory.setItem(convertSlot(slot), item);
|
||||
} else if (item != null) {
|
||||
getPlayer().getWorld().dropItemNaturally(getPlayer().getLocation(), item);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ItemStack getItem(final int slot) {
|
||||
Inventory inventory = getInventory(slot);
|
||||
return (inventory == null) ? null : inventory.getItem(convertSlot(slot));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCursor(@Nullable final ItemStack item) {
|
||||
getPlayer().setItemOnCursor(item);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ItemStack getCursor() {
|
||||
return getPlayer().getItemOnCursor();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Inventory getInventory(final int rawSlot) {
|
||||
// Slot may be -1 if not properly detected due to client bug
|
||||
// e.g. dropping an item into part of the enchantment list section of an enchanting table
|
||||
if (rawSlot == OUTSIDE || rawSlot == -1) {
|
||||
return null;
|
||||
}
|
||||
Preconditions.checkArgument(rawSlot >= 0, "Negative, non outside slot %s", rawSlot);
|
||||
Preconditions.checkArgument(rawSlot < countSlots(), "Slot %s greater than inventory slot count", rawSlot);
|
||||
|
||||
if (rawSlot < getTopInventory().getSize()) {
|
||||
return getTopInventory();
|
||||
} else {
|
||||
return getBottomInventory();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int convertSlot(final int rawSlot) {
|
||||
int numInTop = getTopInventory().getSize();
|
||||
// Index from the top inventory as having slots from [0,size]
|
||||
if (rawSlot < numInTop) {
|
||||
return rawSlot;
|
||||
}
|
||||
|
||||
// Move down the slot index by the top size
|
||||
int slot = rawSlot - numInTop;
|
||||
|
||||
// Player crafting slots are indexed differently. The matrix is caught by the first return.
|
||||
// Creative mode is the same, except that you can't see the crafting slots (but the IDs are still used)
|
||||
if (getType() == InventoryType.CRAFTING || getType() == InventoryType.CREATIVE) {
|
||||
/*
|
||||
* Raw Slots:
|
||||
*
|
||||
* 5 1 2 0
|
||||
* 6 3 4
|
||||
* 7
|
||||
* 8 45
|
||||
* 9 10 11 12 13 14 15 16 17
|
||||
* 18 19 20 21 22 23 24 25 26
|
||||
* 27 28 29 30 31 32 33 34 35
|
||||
* 36 37 38 39 40 41 42 43 44
|
||||
*/
|
||||
|
||||
/*
|
||||
* Converted Slots:
|
||||
*
|
||||
* 39 1 2 0
|
||||
* 38 3 4
|
||||
* 37
|
||||
* 36 40
|
||||
* 9 10 11 12 13 14 15 16 17
|
||||
* 18 19 20 21 22 23 24 25 26
|
||||
* 27 28 29 30 31 32 33 34 35
|
||||
* 0 1 2 3 4 5 6 7 8
|
||||
*/
|
||||
|
||||
if (slot < 4) {
|
||||
// Send [5,8] to [39,36]
|
||||
return 39 - slot;
|
||||
} else if (slot > 39) {
|
||||
// Slot lives in the extra slot section
|
||||
return slot;
|
||||
} else {
|
||||
// Reset index so 9 -> 0
|
||||
slot -= 4;
|
||||
}
|
||||
}
|
||||
|
||||
// 27 = 36 - 9
|
||||
if (slot >= 27) {
|
||||
// Put into hotbar section
|
||||
slot -= 27;
|
||||
} else {
|
||||
// Take out of hotbar section
|
||||
// 9 = 36 - 27
|
||||
slot += 9;
|
||||
}
|
||||
|
||||
return slot;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public InventoryType.SlotType getSlotType(final int slot) {
|
||||
InventoryType.SlotType type = InventoryType.SlotType.CONTAINER;
|
||||
if (slot >= 0 && slot < this.getTopInventory().getSize()) {
|
||||
switch (this.getType()) {
|
||||
case BLAST_FURNACE:
|
||||
case FURNACE:
|
||||
case SMOKER:
|
||||
if (slot == 2) {
|
||||
type = InventoryType.SlotType.RESULT;
|
||||
} else if (slot == 1) {
|
||||
type = InventoryType.SlotType.FUEL;
|
||||
} else {
|
||||
type = InventoryType.SlotType.CRAFTING;
|
||||
}
|
||||
break;
|
||||
case BREWING:
|
||||
if (slot == 3) {
|
||||
type = InventoryType.SlotType.FUEL;
|
||||
} else {
|
||||
type = InventoryType.SlotType.CRAFTING;
|
||||
}
|
||||
break;
|
||||
case ENCHANTING:
|
||||
type = InventoryType.SlotType.CRAFTING;
|
||||
break;
|
||||
case WORKBENCH:
|
||||
case CRAFTING:
|
||||
if (slot == 0) {
|
||||
type = InventoryType.SlotType.RESULT;
|
||||
} else {
|
||||
type = InventoryType.SlotType.CRAFTING;
|
||||
}
|
||||
break;
|
||||
case BEACON:
|
||||
type = InventoryType.SlotType.CRAFTING;
|
||||
break;
|
||||
case ANVIL:
|
||||
case SMITHING:
|
||||
case CARTOGRAPHY:
|
||||
case GRINDSTONE:
|
||||
case MERCHANT:
|
||||
if (slot == 2) {
|
||||
type = InventoryType.SlotType.RESULT;
|
||||
} else {
|
||||
type = InventoryType.SlotType.CRAFTING;
|
||||
}
|
||||
break;
|
||||
case STONECUTTER:
|
||||
if (slot == 1) {
|
||||
type = InventoryType.SlotType.RESULT;
|
||||
} else {
|
||||
type = InventoryType.SlotType.CRAFTING;
|
||||
}
|
||||
break;
|
||||
case LOOM:
|
||||
case SMITHING_NEW:
|
||||
if (slot == 3) {
|
||||
type = InventoryType.SlotType.RESULT;
|
||||
} else {
|
||||
type = InventoryType.SlotType.CRAFTING;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Nothing to do, it's a CONTAINER slot
|
||||
}
|
||||
} else {
|
||||
if (slot < 0) {
|
||||
type = InventoryType.SlotType.OUTSIDE;
|
||||
} else if (this.getType() == InventoryType.CRAFTING) { // Also includes creative inventory
|
||||
if (slot < 9) {
|
||||
type = InventoryType.SlotType.ARMOR;
|
||||
} else if (slot > 35) {
|
||||
type = InventoryType.SlotType.QUICKBAR;
|
||||
}
|
||||
} else if (slot >= (this.countSlots() - (9 + 4 + 1))) { // Quickbar, Armor, Offhand
|
||||
type = InventoryType.SlotType.QUICKBAR;
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
getPlayer().closeInventory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countSlots() {
|
||||
return getTopInventory().getSize() + getBottomInventory().getSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setProperty(@NotNull final Property prop, final int value) {
|
||||
return getPlayer().setWindowProperty(prop, value);
|
||||
}
|
||||
}
|
|
@ -48,7 +48,7 @@ public class CraftContainer extends Container {
|
|||
}
|
||||
|
||||
public CraftContainer(final Inventory inventory, final EntityHuman player, int id) {
|
||||
this(new InventoryView() {
|
||||
this(new CraftAbstractInventoryView() {
|
||||
|
||||
private final String originalTitle = (inventory instanceof CraftInventoryCustom) ? ((CraftInventoryCustom.MinecraftInventory) ((CraftInventory) inventory).getInventory()).getTitle() : inventory.getType().getDefaultTitle();
|
||||
private String title = originalTitle;
|
||||
|
|
|
@ -15,7 +15,7 @@ import org.bukkit.inventory.Inventory;
|
|||
import org.bukkit.inventory.InventoryView;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class CraftInventoryView extends InventoryView {
|
||||
public class CraftInventoryView extends CraftAbstractInventoryView {
|
||||
private final Container container;
|
||||
private final CraftHumanEntity player;
|
||||
private final CraftInventory viewing;
|
||||
|
|
|
@ -67,6 +67,10 @@ public class Commodore {
|
|||
"org/spigotmc/event/entity/EntityDismountEvent", "org/bukkit/event/entity/EntityDismountEvent"
|
||||
);
|
||||
|
||||
private static final Set<String> CLASS_TO_INTERFACE = Set.of(
|
||||
"org/bukkit/inventory/InventoryView"
|
||||
);
|
||||
|
||||
private static Map<String, RerouteMethodData> createReroutes(Class<?> clazz) {
|
||||
Map<String, RerouteMethodData> reroutes = RerouteBuilder.buildFromClass(clazz);
|
||||
REROUTES.add(reroutes);
|
||||
|
@ -288,6 +292,17 @@ public class Commodore {
|
|||
return;
|
||||
}
|
||||
|
||||
if (CLASS_TO_INTERFACE.contains(owner)) {
|
||||
if (opcode == Opcodes.INVOKEVIRTUAL) {
|
||||
opcode = Opcodes.INVOKEINTERFACE;
|
||||
}
|
||||
|
||||
if (opcode == Opcodes.H_INVOKEVIRTUAL) {
|
||||
opcode = Opcodes.H_INVOKEINTERFACE;
|
||||
}
|
||||
itf = true;
|
||||
}
|
||||
|
||||
// SPIGOT-4496
|
||||
if (owner.equals("org/bukkit/map/MapView") && name.equals("getId") && desc.equals("()S")) {
|
||||
// Should be same size on stack so just call other method
|
||||
|
|
Loading…
Reference in a new issue