Skip to content

Instantly share code, notes, and snippets.

@chaseking
Last active August 25, 2017 17:06
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save chaseking/a9eff3d0cd577e6c098ae59286da3961 to your computer and use it in GitHub Desktop.
Save chaseking/a9eff3d0cd577e6c098ae59286da3961 to your computer and use it in GitHub Desktop.
Anvil Menu
//Default input text
new AnvilGUI(plugin, player, new AnvilGUI.AnvilClickHandler() {
@Override
public boolean onClick(AnvilGUI menu, String text){
menu.getPlayer().sendMessage(text);
return true;
}
}).open();
//Custom input text
new AnvilGUI(plugin, player, new AnvilGUI.AnvilClickHandler() {
@Override
public boolean onClick(AnvilGUI menu, String text){
menu.getPlayer().sendMessage(text);
return true;
}
}).setInputName("Enter Pet Name").open();
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.Plugin;
/**
* Created by chasechocolate.
*/
public class AnvilGUI implements Listener {
public interface AnvilClickHandler {
boolean onClick(AnvilGUI menu, String text);
}
public static final int SLOT_INPUT_LEFT = 0;
public static final int SLOT_INPUT_RIGHT = 1;
public static final int SLOT_OUTPUT = 2;
private Player player;
private AnvilClickHandler clickHandler;
private ItemStack[] items;
private Inventory inv;
private Plugin plugin;
private Listener listener;
String itemName = "";
public AnvilGUI(Plugin plugin, Player player, AnvilClickHandler clickHandler){
this.plugin = plugin;
this.player = player;
this.clickHandler = clickHandler;
this.items = new ItemStack[3];
this.listener = new Listener(){
@EventHandler
public void onInventoryClick(InventoryClickEvent event){
if(event.getInventory().equals(inv)){
event.setCancelled(true);
if(event.getWhoClicked() instanceof Player){
Player player = (Player) event.getWhoClicked();
ItemStack item = event.getCurrentItem();
int slot = event.getRawSlot();
if(slot == SLOT_OUTPUT){
String name;
if(item != null){
if(item.hasItemMeta()){
ItemMeta meta = item.getItemMeta();
if(meta.hasDisplayName()){
name = ChatColor.stripColor(meta.getDisplayName().trim());
}
}
if(clickHandler != null){
try{
if(clickHandler.onClick(AnvilGUI.this, itemName)){
player.closeInventory();
}
} catch(Exception e){
e.printStackTrace();
player.sendMessage(ChatColor.RED + "An error occurred (" + e.getClass().getSimpleName() + "): " + e.getMessage());
}
}
}
}
}
}
}
@EventHandler
public void onInventoryClose(InventoryCloseEvent event){
if(event.getPlayer().equals(player)){
onClose();
}
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event){
if(event.getPlayer().equals(player)){
onClose();
}
}
};
}
public Player getPlayer(){
return player;
}
public AnvilClickHandler getClickHandler(){
return clickHandler;
}
public AnvilGUI setInputName(String name){
setItem(SLOT_INPUT_LEFT, new ItemStack(Material.PAPER), name);
return this;
}
public void setOutputName(String name){
ItemStack item = inv.getItem(SLOT_OUTPUT);
if(item == null){
item = inv.getItem(SLOT_INPUT_LEFT);
if(item == null){
return;
}
}
ItemMeta meta = item.getItemMeta();
meta.setDisplayName(name);
item.setItemMeta(meta);
inv.setItem(SLOT_OUTPUT, item);
}
public Inventory getInventory(){
return inv;
}
public boolean isDead(){
return player == null && clickHandler == null && items == null && inv == null && listener == null && plugin == null;
}
public AnvilGUI open(){
if(items[SLOT_INPUT_LEFT] == null){
setInputName("-");
}
inv = AnvilNMS.open(this);
Bukkit.getPluginManager().registerEvents(listener, plugin);
return this;
}
private void destroy(){
player = null;
clickHandler = null;
items = null;
inv = null;
HandlerList.unregisterAll(listener);
listener = null;
plugin = null;
}
public void setItem(int slot, ItemStack item, String name){
if(name != null){
ItemMeta meta = item.getItemMeta();
if(meta.hasDisplayName() && meta.getDisplayName().equals(name)){
if(inv != null){
return;
}
} else {
meta.setDisplayName(name);
item.setItemMeta(meta);
}
}
items[slot] = item;
if(slot != SLOT_OUTPUT){
items[SLOT_OUTPUT] = item;
}
if(inv != null){
inv.setItem(slot, item);
if(slot != SLOT_OUTPUT){
inv.setItem(SLOT_OUTPUT, item);
}
}
}
public void onClose(){
if(inv != null){
inv.clear();
}
destroy();
}
public ItemStack[] getItems(){
return items;
}
}
import net.minecraft.server.v1_8_R3.*;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
import org.bukkit.inventory.Inventory;
import java.lang.reflect.Field;
/**
* Created by chasechocolate.
*/
public class AnvilNMS {
public static class AnvilContainer extends ContainerAnvil {
private static Field fieldText;
static {
try{
fieldText = ContainerAnvil.class.getDeclaredField("l");
fieldText.setAccessible(true);
} catch(NoSuchFieldException e){
e.printStackTrace();
}
}
private AnvilGUI menu;
public AnvilContainer(EntityHuman human, AnvilGUI menu){
super(human.inventory, human.world, new BlockPosition(0, 0, 0), human);
this.menu = menu;
}
/**
* No EXP required to use
*/
@Override
public boolean a(EntityHuman human){
return true;
}
@Override
public void a(String text){
menu.itemName = text == null ? "" : text;
super.a(text);
}
}
private static final ChatMessage PACKET_MESSAGE = new ChatMessage(Blocks.ANVIL.a() + ".name");
public static Inventory open(AnvilGUI menu){
EntityPlayer nmsPlayer = ((CraftPlayer) menu.getPlayer()).getHandle();
AnvilContainer container = new AnvilContainer(nmsPlayer, menu);
Inventory inv = container.getBukkitView().getTopInventory();
for(int slot = 0; slot < menu.getItems().length; slot++){
org.bukkit.inventory.ItemStack item = menu.getItems()[slot];
if(item != null){
inv.setItem(slot, item);
}
}
int windowId = nmsPlayer.nextContainerCounter();
nmsPlayer.playerConnection.sendPacket(new PacketPlayOutOpenWindow(windowId, "minecraft:anvil", PACKET_MESSAGE, 0));
nmsPlayer.activeContainer = container;
nmsPlayer.activeContainer.windowId = windowId;
nmsPlayer.activeContainer.addSlotListener(nmsPlayer);
return inv;
}
}
@RotemAvitan
Copy link

bug while shift and click

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment