Updated AnvilGUI

- uhhhhhhhh
This commit is contained in:
LikeWhat 2021-07-19 22:00:39 +02:00
parent a3c4246424
commit 51f0499f68
3 changed files with 67 additions and 28 deletions

View File

@ -208,7 +208,7 @@ public class InventoryListener implements Listener {
String menuID = null; String menuID = null;
if (itemTags.contains("menuID")) { if (itemTags.contains("menuID")) {
menuID = itemTags.get(itemTags.indexOf("menuID") + 1).toLowerCase(); menuID = itemTags.get(itemTags.indexOf("menuID") + 1).toLowerCase();
player.sendMessage("menuID present: " + menuID); //player.sendMessage("menuID present: " + menuID);
lastActiveMenu.put(player.getUniqueId(), menuID); lastActiveMenu.put(player.getUniqueId(), menuID);
} }

View File

@ -138,8 +138,8 @@ public class Utils {
} }
}); });
gui.setSlot(AnvilGUI.AnvilSlot.OUTPUT, new ItemEditor(Material.PAPER).setDisplayName(itemName).setLore(CustomHeads.getLanguageManager().SEARCH_LORE).getItem());
gui.setSlot(AnvilGUI.AnvilSlot.INPUT_LEFT, new ItemEditor(Material.PAPER).setDisplayName(itemName).setLore(CustomHeads.getLanguageManager().SEARCH_LORE).getItem()); gui.setSlot(AnvilGUI.AnvilSlot.INPUT_LEFT, new ItemEditor(Material.PAPER).setDisplayName(itemName).setLore(CustomHeads.getLanguageManager().SEARCH_LORE).getItem());
gui.setSlot(AnvilGUI.AnvilSlot.OUTPUT, new ItemEditor(Material.PAPER).setDisplayName(itemName).setLore(CustomHeads.getLanguageManager().SEARCH_LORE).getItem());
gui.open(); gui.open();
player.updateInventory(); player.updateInventory();
} }

View File

@ -30,6 +30,14 @@ import java.util.logging.Level;
*/ */
public class AnvilGUI { public class AnvilGUI {
private static final Class<?> containerAnvilClass;
private static final Class<?> packetPlayOutOpenWindowClass;
static {
containerAnvilClass = Utils.getMCServerClassByName("ContainerAnvil", "world.inventory");
packetPlayOutOpenWindowClass = Utils.getMCServerClassByName("PacketPlayOutOpenWindow", "network.protocol.game");
}
private HashMap<AnvilSlot, ItemStack> items = new HashMap<>(); private HashMap<AnvilSlot, ItemStack> items = new HashMap<>();
private AnvilClickEventHandler handler; private AnvilClickEventHandler handler;
private ItemStack currentitem = null; private ItemStack currentitem = null;
@ -130,14 +138,17 @@ public class AnvilGUI {
try { try {
Object p = player.getClass().getMethod("getHandle").invoke(player); Object p = player.getClass().getMethod("getHandle").invoke(player);
Class<?> playerHandleClass = p.getClass();
int nextContainerId = (int) p.getClass().getMethod("nextContainerCounter").invoke(p); int nextContainerId = (int) playerHandleClass.getMethod("nextContainerCounter").invoke(p);
Location location = player.getLocation(); Location location = player.getLocation();
Constructor<?> chatMessageConstructor = Utils.getMCServerClassByName("ChatMessage", "network.chat").getConstructor(String.class, Object[].class); Constructor<?> chatMessageConstructor = Utils.getMCServerClassByName("ChatMessage", "network.chat").getConstructor(String.class, Object[].class);
Object container; Object container;
Object packet; Object packet;
Object playerConnection;
Field windowIdField;
Field activeContainerField;
switch (NBTTagUtils.MC_VERSION) { switch (NBTTagUtils.MC_VERSION) {
case 8: case 8:
case 9: case 9:
@ -145,39 +156,72 @@ public class AnvilGUI {
case 11: case 11:
case 12: case 12:
case 13: case 13:
container = getClassbyName("ContainerAnvil").getConstructor(getClassbyName("PlayerInventory"), getClassbyName("World"), getClassbyName("BlockPosition"), getClassbyName("EntityHuman")).newInstance(p.getClass().getField("inventory").get(p), p.getClass().getField("world").get(p), getClassbyName("BlockPosition").getConstructor(int.class, int.class, int.class).newInstance(location.getBlockX(), location.getBlockY(), location.getBlockZ()), p); container = containerAnvilClass.getConstructor(getClassbyName("PlayerInventory"), getClassbyName("World"), getClassbyName("BlockPosition"), getClassbyName("EntityHuman")).newInstance(playerHandleClass.getField("inventory").get(p), playerHandleClass.getField("world").get(p), getClassbyName("BlockPosition").getConstructor(int.class, int.class, int.class).newInstance(location.getBlockX(), location.getBlockY(), location.getBlockZ()), p);
packet = getClassbyName("PacketPlayOutOpenWindow").getConstructor(int.class, String.class, getClassbyName("IChatBaseComponent"), int.class).newInstance(nextContainerId, "minecraft:anvil", chatMessageConstructor.newInstance(title, new Object[]{}), 0); packet = packetPlayOutOpenWindowClass.getConstructor(int.class, String.class, getClassbyName("IChatBaseComponent"), int.class).newInstance(nextContainerId, "minecraft:anvil", chatMessageConstructor.newInstance(title, new Object[]{}), 0);
playerConnection = playerHandleClass.getField("playerConnection").get(p);
windowIdField = Utils.getMCServerClassByName("Container", "world.inventory").getField("windowId");;
activeContainerField = playerHandleClass.getDeclaredField("activeContainer");
break; break;
case 14: case 14:
case 15: case 15:
case 16: case 16:
container = Utils.getMCServerClassByName("ContainerAnvil", "world.inventory").getConstructor(int.class, Utils.getMCServerClassByName("PlayerInventory", "world.entity.player"), getClassbyName("ContainerAccess")).newInstance(nextContainerId, p.getClass().getField("inventory").get(p), getClassbyName("ContainerAccess").getMethod("at", Utils.getMCServerClassByName("World", "world.level"), Utils.getMCServerClassByName("BlockPosition", "core")).invoke(Utils.getMCServerClassByName("ContainerAccess", "world.inventory"), p.getClass().getField("world").get(p), Utils.getMCServerClassByName("BlockPosition", "core").getConstructor(int.class, int.class, int.class).newInstance(location.getBlockX(), location.getBlockY(), location.getBlockZ()))); container = containerAnvilClass.getConstructor(int.class, Utils.getMCServerClassByName("PlayerInventory", "world.entity.player"), Utils.getMCServerClassByName("ContainerAccess", "world.inventory")).newInstance(nextContainerId, playerHandleClass.getField("inventory").get(p), Utils.getMCServerClassByName("ContainerAccess", "world.inventory").getMethod("at", Utils.getMCServerClassByName("World", "world.level"), Utils.getMCServerClassByName("BlockPosition", "core")).invoke(Utils.getMCServerClassByName("ContainerAccess", "world.inventory"), playerHandleClass.getField("world").get(p), Utils.getMCServerClassByName("BlockPosition", "core").getConstructor(int.class, int.class, int.class).newInstance(location.getBlockX(), location.getBlockY(), location.getBlockZ())));
packet = Utils.getMCServerClassByName("PacketPlayOutOpenWindow", "network.protocol.game").getConstructor(int.class, Utils.getMCServerClassByName("Container", "world.inventory"), Utils.getMCServerClassByName("IChatBaseComponent", "network.chat")).newInstance(nextContainerId, Utils.getMCServerClassByName("Containers", "world.inventory").getField("ANVIL").get(Utils.getMCServerClassByName("Containers", "world.inventory")), chatMessageConstructor.newInstance(title, new Object[]{})); packet = packetPlayOutOpenWindowClass.getConstructor(int.class, Utils.getMCServerClassByName("Container", "world.inventory"), Utils.getMCServerClassByName("IChatBaseComponent", "network.chat")).newInstance(nextContainerId, Utils.getMCServerClassByName("Containers", "world.inventory").getField("ANVIL").get(Utils.getMCServerClassByName("Containers", "world.inventory")), chatMessageConstructor.newInstance(title, new Object[]{}));
break; playerConnection = playerHandleClass.getField("playerConnection").get(p);
case 17: windowIdField = Utils.getMCServerClassByName("Container", "world.inventory").getField("windowId");;
container = Utils.getMCServerClassByName("ContainerAnvil", "world.inventory").getConstructor(int.class, Utils.getMCServerClassByName("PlayerInventory", "world.entity.player"), getClassbyName("ContainerAccess")).newInstance(nextContainerId, p.getClass().getField("inventory").get(p), getClassbyName("ContainerAccess").getMethod("at", Utils.getMCServerClassByName("World", "world.level"), Utils.getMCServerClassByName("BlockPosition", "core")).invoke(Utils.getMCServerClassByName("ContainerAccess", "world.inventory"), p.getClass().getField("world").get(p), Utils.getMCServerClassByName("BlockPosition", "core").getConstructor(int.class, int.class, int.class).newInstance(location.getBlockX(), location.getBlockY(), location.getBlockZ()))); activeContainerField = playerHandleClass.getDeclaredField("activeContainer");
packet = Utils.getMCServerClassByName("PacketPlayOutOpenWindow", "network.protocol.game").getConstructor(int.class, Utils.getMCServerClassByName("Container", "world.inventory"), Utils.getMCServerClassByName("IChatBaseComponent", "network.chat")).newInstance(nextContainerId, Utils.getMCServerClassByName("Containers", "world.inventory").getField("h").get(Utils.getMCServerClassByName("Containers", "world.inventory")), chatMessageConstructor.newInstance(title, new Object[]{}));
break; break;
/*case 17:
Class<?> containersClass = Utils.getMCServerClassByName("Containers", "world.inventory");
Class<?> containerAccessClass = Utils.getMCServerClassByName("ContainerAccess", "world.inventory");
container = containerAnvilClass
.getConstructor(int.class, Utils.getMCServerClassByName("PlayerInventory", "world.entity.player"), containerAccessClass)
.newInstance(nextContainerId, playerHandleClass.getMethod("getInventory").invoke(p),
containerAccessClass
.getMethod("at", Utils.getMCServerClassByName("World", "world.level"), Utils.getMCServerClassByName("BlockPosition", "core"))
.invoke(containerAccessClass, playerHandleClass.getField("t").get(p), Utils.getMCServerClassByName("BlockPosition", "core")
.getConstructor(int.class, int.class, int.class)
.newInstance(location.getBlockX(), location.getBlockY(), location.getBlockZ())));
packet = packetPlayOutOpenWindowClass
.getConstructor(int.class, containersClass, Utils.getMCServerClassByName("IChatBaseComponent", "network.chat"))
.newInstance(nextContainerId, containersClass
.getField("h").get(containersClass), chatMessageConstructor
.newInstance(title, new Object[]{}));
playerConnection = playerHandleClass.getField("b").get(p);
windowIdField = Utils.getMCServerClassByName("Container", "world.inventory").getDeclaredField("j");
activeContainerField = playerHandleClass.getField("bV");
break;*/
default: default:
throw new UnsupportedOperationException("Current MC Version (" + CustomHeads.version + ") isn't supported for AnvilGUI"); throw new UnsupportedOperationException("Current MC Version (" + CustomHeads.version + ") isn't supported for AnvilGUI");
} }
Object bukkitView = container.getClass().getMethod("getBukkitView").invoke(container); Object bukkitView = container.getClass().getMethod("getBukkitView").invoke(container);
inventory = (Inventory) bukkitView.getClass().getMethod("getTopInventory").invoke(bukkitView); inventory = (Inventory) bukkitView.getClass().getMethod("getTopInventory").invoke(bukkitView);
/*if(NBTTagUtils.MC_VERSION >= 17) {
Field iInventoryField = container.getClass().getSuperclass().getDeclaredField("p");
if(!iInventoryField.isAccessible()) {
iInventoryField.setAccessible(true);
}
Utils.printMethods(iInventoryField.getType());
Object iInventoryObject = iInventoryField.get(container);
Method setItemMethod = iInventoryField.getType().getDeclaredMethod("setItem", int.class, Utils.getMCServerClassByName("ItemStack", "world.item"));
for (AnvilSlot slot : items.keySet()) {
if(slot == AnvilSlot.OUTPUT) {
continue;
}
setItemMethod.invoke(iInventoryObject, slot.getSlot(), TagEditor.getAsMNSCopy(items.get(slot)));
}
} else {*/
for (AnvilSlot slot : items.keySet()) { for (AnvilSlot slot : items.keySet()) {
inventory.setItem(slot.getSlot(), items.get(slot)); inventory.setItem(slot.getSlot(), items.get(slot));
} }
//}
Utils.getMCServerClassByName("Container", "world.inventory").getField("checkReachable").set(container, false); Utils.getMCServerClassByName("Container", "world.inventory").getField("checkReachable").set(container, false);
Object connection = p.getClass().getField("playerConnection").get(p); playerConnection.getClass().getMethod("sendPacket", Utils.getMCServerClassByName("Packet", "network.protocol")).invoke(playerConnection, packet);
connection.getClass().getMethod("sendPacket", Utils.getMCServerClassByName("Packet", "network.protocol")).invoke(connection, packet);
Field activeContainerField = Utils.getMCServerClassByName("EntityHuman", "world.entity.player").getDeclaredField("activeContainer");
activeContainerField.setAccessible(true); activeContainerField.setAccessible(true);
activeContainerField.set(p, container); activeContainerField.set(p, container);
Field windowIdField = Utils.getMCServerClassByName("Container", "world.inventory").getField("windowId");
windowIdField.setAccessible(true); windowIdField.setAccessible(true);
windowIdField.set(activeContainerField.get(p), nextContainerId); windowIdField.set(activeContainerField.get(p), nextContainerId);
player.openInventory(inventory);
} catch (Exception exception) { } catch (Exception exception) {
Bukkit.getLogger().log(Level.WARNING, "Failed to open AnvilGUI", exception); Bukkit.getLogger().log(Level.WARNING, "Failed to open AnvilGUI", exception);
} }
@ -266,10 +310,5 @@ public class AnvilGUI {
this.willDestroy = !cancel; this.willDestroy = !cancel;
this.takeout = !cancel; this.takeout = !cancel;
} }
public void setSlot(AnvilSlot slot, ItemStack item) {
inventory.setItem(2, item);
player.updateInventory();
}
} }
} }