mirror of
https://github.com/PaperMC/Paper.git
synced 2025-01-25 01:25:03 +01:00
[Bleeding] Fix the openInventory methods for custom inventories. Fixes BUKKIT-1248
Details: - The attributes of custom inventory views are no longer ignored - Enchanting or crafting inventories no longer ignore the passed inventory and open a new one - Inventories associated with tile entities no longer raise a class cast exception if there was no associated tile entity - InventoryOpenEvent and InventoryCloseEvent (if they already had some other inventory open) now fire in all cases - If for any reason the inventory failed to open, the method now returns null instead of returned the previous inventory they had open (or the default inventory, if none) By: Celtic Minstrel <celtic.minstrel.ca@some.place>
This commit is contained in:
parent
5f0bee3860
commit
7e41baa24b
2 changed files with 100 additions and 33 deletions
|
@ -3,6 +3,8 @@ package org.bukkit.craftbukkit.entity;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import net.minecraft.server.Container;
|
import net.minecraft.server.Container;
|
||||||
|
import net.minecraft.server.ContainerBrewingStand;
|
||||||
|
import net.minecraft.server.ContainerWorkbench;
|
||||||
import net.minecraft.server.EntityHuman;
|
import net.minecraft.server.EntityHuman;
|
||||||
import net.minecraft.server.EntityPlayer;
|
import net.minecraft.server.EntityPlayer;
|
||||||
import net.minecraft.server.ICrafting;
|
import net.minecraft.server.ICrafting;
|
||||||
|
@ -23,6 +25,7 @@ import org.bukkit.inventory.InventoryView;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.PlayerInventory;
|
import org.bukkit.inventory.PlayerInventory;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.craftbukkit.event.CraftEventFactory;
|
||||||
import org.bukkit.craftbukkit.inventory.CraftContainer;
|
import org.bukkit.craftbukkit.inventory.CraftContainer;
|
||||||
import org.bukkit.craftbukkit.inventory.CraftInventory;
|
import org.bukkit.craftbukkit.inventory.CraftInventory;
|
||||||
import org.bukkit.craftbukkit.inventory.CraftInventoryPlayer;
|
import org.bukkit.craftbukkit.inventory.CraftInventoryPlayer;
|
||||||
|
@ -168,7 +171,10 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
public InventoryView openInventory(Inventory inventory) {
|
public InventoryView openInventory(Inventory inventory) {
|
||||||
|
if(!(getHandle() instanceof EntityPlayer)) return null;
|
||||||
|
EntityPlayer player = (EntityPlayer) getHandle();
|
||||||
InventoryType type = inventory.getType();
|
InventoryType type = inventory.getType();
|
||||||
|
Container formerContainer = getHandle().activeContainer;
|
||||||
// TODO: Should we check that it really IS a CraftInventory first?
|
// TODO: Should we check that it really IS a CraftInventory first?
|
||||||
CraftInventory craftinv = (CraftInventory) inventory;
|
CraftInventory craftinv = (CraftInventory) inventory;
|
||||||
switch(type) {
|
switch(type) {
|
||||||
|
@ -177,28 +183,57 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
|
||||||
getHandle().openContainer(craftinv.getInventory());
|
getHandle().openContainer(craftinv.getInventory());
|
||||||
break;
|
break;
|
||||||
case DISPENSER:
|
case DISPENSER:
|
||||||
getHandle().openDispenser((TileEntityDispenser)craftinv.getInventory());
|
if (craftinv.getInventory() instanceof TileEntityDispenser) {
|
||||||
|
getHandle().openDispenser((TileEntityDispenser)craftinv.getInventory());
|
||||||
|
} else {
|
||||||
|
openCustomInventory(inventory, player, 3);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case FURNACE:
|
case FURNACE:
|
||||||
getHandle().openFurnace((TileEntityFurnace)craftinv.getInventory());
|
if (craftinv.getInventory() instanceof TileEntityFurnace) {
|
||||||
|
getHandle().openFurnace((TileEntityFurnace)craftinv.getInventory());
|
||||||
|
} else {
|
||||||
|
openCustomInventory(inventory, player, 2);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case WORKBENCH:
|
case WORKBENCH:
|
||||||
getHandle().startCrafting(getLocation().getBlockX(), getLocation().getBlockY(), getLocation().getBlockZ());
|
openCustomInventory(inventory, player, 1);
|
||||||
break;
|
break;
|
||||||
case BREWING:
|
case BREWING:
|
||||||
getHandle().openBrewingStand((TileEntityBrewingStand)craftinv.getInventory());
|
if (craftinv.getInventory() instanceof TileEntityBrewingStand) {
|
||||||
|
getHandle().openBrewingStand((TileEntityBrewingStand)craftinv.getInventory());
|
||||||
|
} else {
|
||||||
|
openCustomInventory(inventory, player, 5);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ENCHANTING:
|
case ENCHANTING:
|
||||||
getHandle().startEnchanting(getLocation().getBlockX(), getLocation().getBlockY(), getLocation().getBlockZ());
|
openCustomInventory(inventory, player, 4);
|
||||||
break;
|
break;
|
||||||
case CREATIVE:
|
case CREATIVE:
|
||||||
case CRAFTING:
|
case CRAFTING:
|
||||||
throw new IllegalArgumentException("Can't open a " + type + " inventory!");
|
throw new IllegalArgumentException("Can't open a " + type + " inventory!");
|
||||||
}
|
}
|
||||||
|
if (getHandle().activeContainer == formerContainer) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
getHandle().activeContainer.checkReachable = false;
|
getHandle().activeContainer.checkReachable = false;
|
||||||
return getHandle().activeContainer.getBukkitView();
|
return getHandle().activeContainer.getBukkitView();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void openCustomInventory(Inventory inventory, EntityPlayer player, int windowType) {
|
||||||
|
Container container = new CraftContainer(inventory, this, player.nextContainerCounter());
|
||||||
|
|
||||||
|
container = CraftEventFactory.callInventoryOpenEvent(player, container);
|
||||||
|
if(container == null) return;
|
||||||
|
|
||||||
|
String title = container.getBukkitView().getTitle();
|
||||||
|
int size = container.getBukkitView().getTopInventory().getSize();
|
||||||
|
|
||||||
|
player.netServerHandler.sendPacket(new Packet100OpenWindow(container.windowId, windowType, title, size));
|
||||||
|
getHandle().activeContainer = container;
|
||||||
|
getHandle().activeContainer.addSlotListener(player);
|
||||||
|
}
|
||||||
|
|
||||||
public InventoryView openWorkbench(Location location, boolean force) {
|
public InventoryView openWorkbench(Location location, boolean force) {
|
||||||
if (!force) {
|
if (!force) {
|
||||||
Block block = location.getBlock();
|
Block block = location.getBlock();
|
||||||
|
@ -248,18 +283,19 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trigger an INVENTORY_OPEN event
|
// Trigger an INVENTORY_OPEN event
|
||||||
InventoryOpenEvent event = new InventoryOpenEvent(inventory);
|
container = CraftEventFactory.callInventoryOpenEvent(player, container);
|
||||||
player.activeContainer.transferTo(container, this);
|
if (container == null) {
|
||||||
server.getPluginManager().callEvent(event);
|
|
||||||
if (event.isCancelled()) {
|
|
||||||
container.transferTo(player.activeContainer, this);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now open the window
|
// Now open the window
|
||||||
player.netServerHandler.sendPacket(new Packet100OpenWindow(container.windowId, 1, "Crafting", 9));
|
InventoryType type = inventory.getType();
|
||||||
|
int windowType = CraftContainer.getNotchInventoryType(type);
|
||||||
|
String title = inventory.getTitle();
|
||||||
|
int size = inventory.getTopInventory().getSize();
|
||||||
|
player.netServerHandler.sendPacket(new Packet100OpenWindow(container.windowId, windowType, title, size));
|
||||||
player.activeContainer = container;
|
player.activeContainer = container;
|
||||||
player.activeContainer.addSlotListener((ICrafting) player);
|
player.activeContainer.addSlotListener(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void closeInventory() {
|
public void closeInventory() {
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
package org.bukkit.craftbukkit.inventory;
|
package org.bukkit.craftbukkit.inventory;
|
||||||
|
|
||||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||||
|
import org.bukkit.entity.HumanEntity;
|
||||||
import org.bukkit.event.inventory.InventoryType;
|
import org.bukkit.event.inventory.InventoryType;
|
||||||
|
import org.bukkit.inventory.Inventory;
|
||||||
import org.bukkit.inventory.InventoryView;
|
import org.bukkit.inventory.InventoryView;
|
||||||
|
|
||||||
import net.minecraft.server.Container;
|
import net.minecraft.server.Container;
|
||||||
|
@ -28,6 +30,30 @@ public class CraftContainer extends Container {
|
||||||
setupSlots(top, bottom);
|
setupSlots(top, bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CraftContainer(final Inventory inventory, final HumanEntity player, int id) {
|
||||||
|
this(new InventoryView() {
|
||||||
|
@Override
|
||||||
|
public Inventory getTopInventory() {
|
||||||
|
return inventory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Inventory getBottomInventory() {
|
||||||
|
return player.getInventory();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HumanEntity getPlayer() {
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InventoryType getType() {
|
||||||
|
return inventory.getType();
|
||||||
|
}
|
||||||
|
}, id);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InventoryView getBukkitView() {
|
public InventoryView getBukkitView() {
|
||||||
return view;
|
return view;
|
||||||
|
@ -50,27 +76,7 @@ public class CraftContainer extends Container {
|
||||||
cachedTitle = view.getTitle();
|
cachedTitle = view.getTitle();
|
||||||
if (view.getPlayer() instanceof CraftPlayer) {
|
if (view.getPlayer() instanceof CraftPlayer) {
|
||||||
CraftPlayer player = (CraftPlayer) view.getPlayer();
|
CraftPlayer player = (CraftPlayer) view.getPlayer();
|
||||||
int type;
|
int type = getNotchInventoryType(cachedType);
|
||||||
switch(cachedType) {
|
|
||||||
case WORKBENCH:
|
|
||||||
type = 1;
|
|
||||||
break;
|
|
||||||
case FURNACE:
|
|
||||||
type = 2;
|
|
||||||
break;
|
|
||||||
case DISPENSER:
|
|
||||||
type = 3;
|
|
||||||
break;
|
|
||||||
case ENCHANTING:
|
|
||||||
type = 4;
|
|
||||||
break;
|
|
||||||
case BREWING:
|
|
||||||
type = 5;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
type = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
IInventory top = ((CraftInventory)view.getTopInventory()).getInventory();
|
IInventory top = ((CraftInventory)view.getTopInventory()).getInventory();
|
||||||
IInventory bottom = ((CraftInventory)view.getBottomInventory()).getInventory();
|
IInventory bottom = ((CraftInventory)view.getBottomInventory()).getInventory();
|
||||||
this.d.clear();
|
this.d.clear();
|
||||||
|
@ -85,6 +91,31 @@ public class CraftContainer extends Container {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int getNotchInventoryType(InventoryType type) {
|
||||||
|
int typeID;
|
||||||
|
switch(type) {
|
||||||
|
case WORKBENCH:
|
||||||
|
typeID = 1;
|
||||||
|
break;
|
||||||
|
case FURNACE:
|
||||||
|
typeID = 2;
|
||||||
|
break;
|
||||||
|
case DISPENSER:
|
||||||
|
typeID = 3;
|
||||||
|
break;
|
||||||
|
case ENCHANTING:
|
||||||
|
typeID = 4;
|
||||||
|
break;
|
||||||
|
case BREWING:
|
||||||
|
typeID = 5;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
typeID = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return typeID;
|
||||||
|
}
|
||||||
|
|
||||||
private void setupSlots(IInventory top, IInventory bottom) {
|
private void setupSlots(IInventory top, IInventory bottom) {
|
||||||
switch(cachedType) {
|
switch(cachedType) {
|
||||||
case CREATIVE:
|
case CREATIVE:
|
||||||
|
|
Loading…
Add table
Reference in a new issue