Compatibility.

This commit is contained in:
Brianna 2019-05-05 20:40:39 -04:00
parent 996e17eb96
commit 29e5834971
5 changed files with 18 additions and 415 deletions

View File

@ -3,6 +3,7 @@ package com.songoda.epicheads.gui;
import com.songoda.epicheads.EpicHeads;
import com.songoda.epicheads.head.Tag;
import com.songoda.epicheads.utils.Methods;
import com.songoda.epicheads.utils.ServerVersion;
import com.songoda.epicheads.utils.SettingsManager;
import com.songoda.epicheads.utils.gui.AbstractGUI;
import org.bukkit.Material;
@ -66,7 +67,8 @@ public class GUIOverview extends AbstractGUI {
TagInfo tagInfo = TagInfo.valueOf(tag.getName().toUpperCase());
createButton(i + 10 + add, Methods.addTexture(new ItemStack(Material.PLAYER_HEAD, 1, (byte) 3),
createButton(i + 10 + add, Methods.addTexture(new ItemStack(plugin.isServerVersionAtLeast(ServerVersion.V1_13)
? Material.PLAYER_HEAD : Material.valueOf("SKULL_ITEM"), 1, (byte) 3),
tagInfo.getUrl()),
plugin.getLocale().getMessage("gui.overview.headname", tagInfo.getName()),
plugin.getLocale().getMessage("gui.overview.headlore", tag.getCount()));
@ -85,7 +87,8 @@ public class GUIOverview extends AbstractGUI {
for (String line : parts2)
lore2.add(Methods.formatText(line));
createButton(41, Methods.addTexture(new ItemStack(Material.PLAYER_HEAD, 1, (byte) 3),
createButton(41, Methods.addTexture(new ItemStack(plugin.isServerVersionAtLeast(ServerVersion.V1_13)
? Material.PLAYER_HEAD : Material.valueOf("SKULL_ITEM"), 1, (byte) 3),
"a3b183b148b9b4e2b158334aff3b5bb6c2c2dbbc4d67f76a7be856687a2b623"),
plugin.getLocale().getMessage("gui.overview.discord"),
lore2);

View File

@ -3,6 +3,7 @@ package com.songoda.epicheads.head;
import com.songoda.epicheads.EpicHeads;
import com.songoda.epicheads.utils.Methods;
import com.songoda.epicheads.utils.ServerVersion;
import com.songoda.epicheads.utils.SettingsManager;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
@ -55,18 +56,19 @@ public class Head {
public ItemStack asItemStack(boolean favorite) { return asItemStack(favorite, false); }
public ItemStack asItemStack(boolean favorite, boolean includeCost) {
ItemStack item = Methods.addTexture(new ItemStack(Material.PLAYER_HEAD, 1, (byte) 3),
this.URL);
EpicHeads plugin = EpicHeads.getInstance();
ItemStack item = Methods.addTexture(new ItemStack(plugin.isServerVersionAtLeast(ServerVersion.V1_13)
? Material.PLAYER_HEAD : Material.valueOf("SKULL_ITEM"), 1, (byte) 3), this.URL);
double cost = SettingsManager.Setting.PRICE.getDouble();
ItemMeta meta = item.getItemMeta();
meta.setDisplayName(Methods.formatText((favorite ? "&6⭐ " : "") + "&9" + name));
List<String> lore = new ArrayList<>();
if (this.staffPicked == 1)
lore.add(Methods.formatText(EpicHeads.getInstance().getLocale().getMessage("general.head.staffpicked")));
lore.add(Methods.formatText(EpicHeads.getInstance().getLocale().getMessage("general.head.id", this.id)));
lore.add(Methods.formatText(plugin.getLocale().getMessage("general.head.staffpicked")));
lore.add(Methods.formatText(plugin.getLocale().getMessage("general.head.id", this.id)));
if (includeCost)
lore.add(EpicHeads.getInstance().getLocale().getMessage("general.head.cost", cost));
lore.add(plugin.getLocale().getMessage("general.head.cost", cost));
meta.setLore(lore);
item.setItemMeta(meta);

View File

@ -3,10 +3,11 @@ package com.songoda.epicheads.listeners;
import com.songoda.epicheads.EpicHeads;
import com.songoda.epicheads.head.Head;
import com.songoda.epicheads.utils.Methods;
import com.songoda.epicheads.utils.ServerVersion;
import org.bukkit.Material;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityPickupItemEvent;
import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.metadata.FixedMetadataValue;
@ -23,11 +24,12 @@ public class ItemListeners implements Listener {
}
@EventHandler
public void itemPickupEvent(EntityPickupItemEvent event) {
public void itemPickupEvent(PlayerPickupItemEvent event) {
ItemStack item = event.getItem().getItemStack();
if (item.getType() != Material.PLAYER_HEAD || event.getItem().hasMetadata("EHE")) return;
if (item.getType() != (plugin.isServerVersionAtLeast(ServerVersion.V1_13) ? Material.PLAYER_HEAD : Material.valueOf("SKULL_ITEM"))
|| event.getItem().hasMetadata("EHE")) return;
event.getItem().removeMetadata("EHE", plugin);
@ -48,7 +50,7 @@ public class ItemListeners implements Listener {
meta.setLore(new ArrayList<>());
itemNew.setItemMeta(meta);
event.getItem().getWorld().dropItemNaturally(event.getEntity().getLocation().add(1, 1, 0), itemNew.clone());
event.getItem().getWorld().dropItemNaturally(event.getPlayer().getLocation().add(1, 1, 0), itemNew.clone());
event.getItem().setItemStack(itemNew);
}

View File

@ -1,304 +0,0 @@
package com.songoda.epicheads.utils.gui;
import com.songoda.epicheads.EpicHeads;
import com.songoda.epicheads.utils.version.NMSUtil;
import org.bukkit.Bukkit;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
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 java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
public class AbstractAnvilGUI {
private static Class<?> BlockPositionClass;
private static Class<?> PacketPlayOutOpenWindowClass;
private static Class<?> IChatBaseComponentClass;
private static Class<?> ICraftingClass;
private static Class<?> ContainerAnvilClass;
private static Class<?> ChatMessageClass;
private static Class<?> EntityHumanClass;
private static Class<?> ContainerClass;
private static Class<?> ContainerAccessClass;
private static Class<?> WorldClass;
private static Class<?> PlayerInventoryClass;
private static Class<?> ContainersClass;
private Player player;
private Map<AnvilSlot, ItemStack> items = new HashMap<>();
private OnClose onClose = null;
private Inventory inv;
private Listener listener;
private Sound closeSound = Sound.ENTITY_PLAYER_LEVELUP;
static {
BlockPositionClass = NMSUtil.getNMSClass("BlockPosition");
PacketPlayOutOpenWindowClass = NMSUtil.getNMSClass("PacketPlayOutOpenWindow");
IChatBaseComponentClass = NMSUtil.getNMSClass("IChatBaseComponent");
ICraftingClass = NMSUtil.getNMSClass("ICrafting");
ContainerAnvilClass = NMSUtil.getNMSClass("ContainerAnvil");
EntityHumanClass = NMSUtil.getNMSClass("EntityHuman");
ChatMessageClass = NMSUtil.getNMSClass("ChatMessage");
ContainerClass = NMSUtil.getNMSClass("Container");
WorldClass = NMSUtil.getNMSClass("World");
PlayerInventoryClass = NMSUtil.getNMSClass("PlayerInventory");
if (NMSUtil.getVersionNumber() > 13) {
ContainerAccessClass = NMSUtil.getNMSClass("ContainerAccess");
ContainersClass = NMSUtil.getNMSClass("Containers");
}
}
public AbstractAnvilGUI(final Player player, final AnvilClickEventHandler handler) {
this.player = player;
this.listener = new Listener() {
@EventHandler(priority = EventPriority.LOWEST)
public void onInventoryClick(InventoryClickEvent event) {
if (event.getWhoClicked() instanceof Player) {
if (event.getInventory().equals(inv)) {
event.setCancelled(true);
ItemStack item = event.getCurrentItem();
int slot = event.getRawSlot();
String name = "";
if (item != null) {
if (item.hasItemMeta()) {
ItemMeta meta = item.getItemMeta();
if (meta != null && meta.hasDisplayName()) {
name = meta.getDisplayName();
}
}
}
AnvilClickEvent clickEvent = new AnvilClickEvent(AnvilSlot.bySlot(slot), name);
handler.onAnvilClick(clickEvent);
if (clickEvent.getWillClose()) {
event.getWhoClicked().closeInventory();
}
if (clickEvent.getWillDestroy()) {
destroy();
}
}
}
}
@EventHandler(priority = EventPriority.LOWEST)
public void onInventoryClose(InventoryCloseEvent event) {
if (event.getPlayer() instanceof Player) {
Inventory inv = event.getInventory();
player.setLevel(player.getLevel() - 1);
if (inv.equals(inv)) {
inv.clear();
player.playSound(player.getLocation(), closeSound, 1F, 1F);
Bukkit.getScheduler().scheduleSyncDelayedTask(EpicHeads.getInstance(), () -> {
if (onClose != null) onClose.OnClose(player, inv);
destroy();
}, 1L);
}
}
}
@EventHandler(priority = EventPriority.LOWEST)
public void onPlayerQuit(PlayerQuitEvent event) {
if (event.getPlayer().equals(getPlayer())) {
player.setLevel(player.getLevel() - 1);
destroy();
}
}
};
Bukkit.getPluginManager().registerEvents(listener, EpicHeads.getInstance());
}
public Player getPlayer() {
return player;
}
public void setSlot(AnvilSlot slot, ItemStack item) {
items.put(slot, item);
}
public void open() {
player.setLevel(player.getLevel() + 1);
try {
Object craftPlayer = NMSUtil.getCraftClass("entity.CraftPlayer").cast(player);
Method getHandleMethod = craftPlayer.getClass().getMethod("getHandle");
Object entityPlayer = getHandleMethod.invoke(craftPlayer);
Object playerInventory = NMSUtil.getFieldObject(entityPlayer, NMSUtil.getField(entityPlayer.getClass(), "inventory", false));
Object world = NMSUtil.getFieldObject(entityPlayer, NMSUtil.getField(entityPlayer.getClass(), "world", false));
Object blockPosition = BlockPositionClass.getConstructor(int.class, int.class, int.class).newInstance(0, 0, 0);
Object container;
if (NMSUtil.getVersionNumber() > 13) {
container = ContainerAnvilClass
.getConstructor(int.class, PlayerInventoryClass, ContainerAccessClass)
.newInstance(7, playerInventory, ContainerAccessClass.getMethod("at", WorldClass, BlockPositionClass).invoke(null, world, blockPosition));
} else {
container = ContainerAnvilClass
.getConstructor(PlayerInventoryClass, WorldClass, BlockPositionClass, EntityHumanClass)
.newInstance(playerInventory, world, blockPosition, entityPlayer);
}
NMSUtil.getField(ContainerClass, "checkReachable", true).set(container, false);
Method getBukkitViewMethod = container.getClass().getMethod("getBukkitView");
Object bukkitView = getBukkitViewMethod.invoke(container);
Method getTopInventoryMethod = bukkitView.getClass().getMethod("getTopInventory");
inv = (Inventory) getTopInventoryMethod.invoke(bukkitView);
for (AnvilSlot slot : items.keySet()) {
inv.setItem(slot.getSlot(), items.get(slot));
}
Method nextContainerCounterMethod = entityPlayer.getClass().getMethod("nextContainerCounter");
int c = (int) nextContainerCounterMethod.invoke(entityPlayer);
Constructor<?> chatMessageConstructor = ChatMessageClass.getConstructor(String.class, Object[].class);
Object inventoryTitle = chatMessageConstructor.newInstance("Repairing", new Object[]{});
Object packet;
if (NMSUtil.getVersionNumber() > 13) {
packet = PacketPlayOutOpenWindowClass
.getConstructor(int.class, ContainersClass, IChatBaseComponentClass)
.newInstance(c, ContainersClass.getField("ANVIL").get(null), inventoryTitle);
} else {
packet = PacketPlayOutOpenWindowClass
.getConstructor(int.class, String.class, IChatBaseComponentClass, int.class)
.newInstance(c, "minecraft:anvil", inventoryTitle, 0);
}
NMSUtil.sendPacket(player, packet);
Field activeContainerField = NMSUtil.getField(EntityHumanClass, "activeContainer", true);
if (activeContainerField != null) {
activeContainerField.set(entityPlayer, container);
NMSUtil.getField(ContainerClass, "windowId", true).set(activeContainerField.get(entityPlayer), c);
Method addSlotListenerMethod = activeContainerField.get(entityPlayer).getClass().getMethod("addSlotListener", ICraftingClass);
addSlotListenerMethod.invoke(activeContainerField.get(entityPlayer), entityPlayer);
if (NMSUtil.getVersionNumber() > 13) {
ContainerClass.getMethod("setTitle", IChatBaseComponentClass).invoke(container, inventoryTitle);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void destroy() {
player = null;
items = null;
HandlerList.unregisterAll(listener);
listener = null;
}
private OnClose getOnClose() {
return onClose;
}
public void setOnClose(OnClose onClose) {
this.onClose = onClose;
}
public void setCloseSound(Sound sound) {
closeSound = sound;
}
public enum AnvilSlot {
INPUT_LEFT(0),
INPUT_RIGHT(1),
OUTPUT(2);
private int slot;
AnvilSlot(int slot) {
this.slot = slot;
}
public static AnvilSlot bySlot(int slot) {
for (AnvilSlot anvilSlot : values()) {
if (anvilSlot.getSlot() == slot) {
return anvilSlot;
}
}
return null;
}
public int getSlot() {
return slot;
}
}
@FunctionalInterface
public interface AnvilClickEventHandler {
void onAnvilClick(AnvilClickEvent event);
}
public class AnvilClickEvent {
private AnvilSlot slot;
private String name;
private boolean close = true;
private boolean destroy = true;
public AnvilClickEvent(AnvilSlot slot, String name) {
this.slot = slot;
this.name = name;
}
public AnvilSlot getSlot() {
return slot;
}
public String getName() {
return name;
}
public boolean getWillClose() {
return close;
}
public void setWillClose(boolean close) {
this.close = close;
}
public boolean getWillDestroy() {
return destroy;
}
public void setWillDestroy(boolean destroy) {
this.destroy = destroy;
}
}
}

View File

@ -1,100 +0,0 @@
package com.songoda.epicheads.utils.version;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.lang.reflect.Field;
public class NMSUtil {
public static String getVersion() {
String name = Bukkit.getServer().getClass().getPackage().getName();
return name.substring(name.lastIndexOf('.') + 1) + ".";
}
public static int getVersionNumber() {
String name = getVersion().substring(3);
return Integer.valueOf(name.substring(0, name.length() - 4));
}
public static int getVersionReleaseNumber() {
String NMSVersion = getVersion();
return Integer.valueOf(NMSVersion.substring(NMSVersion.length() - 2).replace(".", ""));
}
public static Class<?> getNMSClass(String className) {
try {
String fullName = "net.minecraft.server." + getVersion() + className;
Class<?> clazz = Class.forName(fullName);
return clazz;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static Class<?> getCraftClass(String className) throws ClassNotFoundException {
try {
String fullName = "org.bukkit.craftbukkit." + getVersion() + className;
Class<?> clazz = Class.forName(fullName);
return clazz;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static Field getField(Class<?> clazz, String name, boolean declared) {
try {
Field field;
if (declared) {
field = clazz.getDeclaredField(name);
} else {
field = clazz.getField(name);
}
field.setAccessible(true);
return field;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static Object getFieldObject(Object object, Field field) {
try {
return field.get(object);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static void setField(Object object, String fieldName, Object fieldValue, boolean declared) {
try {
Field field;
if (declared) {
field = object.getClass().getDeclaredField(fieldName);
} else {
field = object.getClass().getField(fieldName);
}
field.setAccessible(true);
field.set(object, fieldValue);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void sendPacket(Player player, Object packet) {
try {
Object handle = player.getClass().getMethod("getHandle").invoke(player);
Object playerConnection = handle.getClass().getField("playerConnection").get(handle);
playerConnection.getClass().getMethod("sendPacket", getNMSClass("Packet")).invoke(playerConnection, packet);
} catch (Exception e) {
e.printStackTrace();
}
}
}