Skip to content

Instantly share code, notes, and snippets.

@WesJD
Last active November 8, 2016 16:05
Show Gist options
  • Save WesJD/f61dbb000aebd9870ec479c22af3aaa9 to your computer and use it in GitHub Desktop.
Save WesJD/f61dbb000aebd9870ec479c22af3aaa9 to your computer and use it in GitHub Desktop.
Really easy Bukkit inventories.
public abstract class AbstractInventory {
private static final String SERVER_VERSION = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
private static Method handleInventoryCloseEvent;
private static Method getHandle;
private static Field defaultContainer;
private static Field activeContainer;
static {
try {
final Class<?> entityHuman = Class.forName("net.minecraft.server." + SERVER_VERSION + ".EntityHuman");
handleInventoryCloseEvent = Class.forName("org.bukkit.craftbukkit." + SERVER_VERSION + ".event.CraftEventFactory")
.getDeclaredMethod("handleInventoryCloseEvent", entityHuman);
getHandle = Class.forName("org.bukkit.craftbukkit." + SERVER_VERSION + ".entity.CraftPlayer").getDeclaredMethod("getHandle");
defaultContainer = entityHuman.getDeclaredField("defaultContainer");
activeContainer = entityHuman.getDeclaredField("activeContainer");
} catch (ClassNotFoundException | NoSuchMethodException | NoSuchFieldException ex) {
ex.printStackTrace();
}
}
private final Map<Integer, Button> buttons = new HashMap<>();
private final Listeners listeners = new Listeners();
private final Inventory inventory;
protected final Player player;
public AbstractInventory(Player player, int size, String name) {
this(player, size, name, false);
}
public AbstractInventory(Player player, int size, String name, boolean manualOpen) {
this.inventory = Bukkit.createInventory(player, size, name);
this.player = player;
if (!manualOpen) open();
}
protected void open() {
try {
inventory.clear();
build();
final Object entityHuman = getHandle.invoke(player);
handleInventoryCloseEvent.invoke(null, entityHuman);
activeContainer.set(entityHuman, defaultContainer.get(entityHuman));
player.openInventory(inventory);
Bukkit.getPluginManager().registerEvents(listeners, PLUGIN_INSTANCE);
onOpen();
} catch (IllegalAccessException | InvocationTargetException ex) {
ex.printStackTrace();
}
}
protected void close() {
onClose();
HandlerList.unregisterAll(listeners);
}
protected void onOpen() {
}
protected void onClose() {
}
protected abstract void build();
protected void set(int slot, ItemStack stack) {
inventory.setItem(slot, stack);
}
protected void set(int slot, ItemStack stack, Button button) {
set(slot, stack);
buttons.put(slot, button);
}
protected abstract class Button {
public abstract void onClick(Player clicker, ClickType type);
}
private class Listeners implements Listener {
@EventHandler
public void onInventoryItemDrag(InventoryDragEvent e) {
e.setCancelled(e.getInventory().getName().equals(inventory.getName()) && e.getInventory().getHolder().equals(player));
}
@EventHandler
public void onInventoryClick(InventoryClickEvent e) {
if (e.getInventory().getName().equals(inventory.getName()) && e.getInventory().getHolder().equals(player)) {
e.setCancelled(true);
if (buttons.containsKey(e.getRawSlot())) buttons.get(e.getRawSlot()).onClick((Player) e.getWhoClicked(), e.getClick());
}
}
@EventHandler
public void onInventoryClose(InventoryCloseEvent e) {
if (e.getInventory().getName().equals(inventory.getName()) && e.getInventory().getHolder().equals(player)) close();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment