Essentials/nms/ReflectionProvider/src/net/ess3/nms/refl/SpawnEggRefl.java

156 lines
5.7 KiB
Java

/*
******************************************************************************
* This file is part of ASkyBlock.
* <p>
* ASkyBlock is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* <p>
* ASkyBlock is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* <p>
* You should have received a copy of the GNU General Public License
* along with ASkyBlock. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************
*/
package net.ess3.nms.refl;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
import org.bukkit.inventory.ItemStack;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
/**
* Represents a spawn egg that can be used to spawn mobs.
*
* @author tastybento
*/
public class SpawnEggRefl {
private EntityType type;
SpawnEggRefl(EntityType type) {
this.type = type;
}
/**
* Get the type of entity this egg will spawn.
*
* @return The entity type.
*/
EntityType getSpawnedType() {
return type;
}
/**
* Set the type of entity this egg will spawn.
*
* @param type The entity type.
*/
public void setSpawnedType(EntityType type) {
if (type.isAlive()) {
this.type = type;
}
}
@Override
public String toString() {
return "SPAWN EGG{" + getSpawnedType() + "}";
}
/**
* Get an ItemStack of one spawn egg
*
* @return ItemStack
*/
ItemStack toItemStack() throws Exception {
return toItemStack(1);
}
/**
* Get an itemstack of spawn eggs
*
* @param amount
* @return ItemStack of spawn eggs
*/
@SuppressWarnings("deprecation")
public ItemStack toItemStack(int amount) throws Exception {
ItemStack item = new ItemStack(Material.MONSTER_EGG, amount);
Class<?> craftItemStackClass = ReflUtil.getOBCClass("inventory.CraftItemStack");
Method asNMSCopyMethod = ReflUtil.getMethodCached(craftItemStackClass, "asNMSCopy", ItemStack.class);
Class<?> NMSItemStackClass = ReflUtil.getNMSClass("ItemStack");
Object stack = asNMSCopyMethod.invoke(null, item);
Object tagCompound = ReflUtil.getMethodCached(NMSItemStackClass, "getTag").invoke(stack);
Class<?> NBTTagCompoundClass = ReflUtil.getNMSClass("NBTTagCompound");
Constructor<?> NBTTagCompoundConstructor = ReflUtil.getConstructorCached(NBTTagCompoundClass);
if (tagCompound == null) {
tagCompound = NBTTagCompoundConstructor.newInstance();
}
Object id = NBTTagCompoundConstructor.newInstance();
Method tagSetString = ReflUtil.getMethodCached(NBTTagCompoundClass, "setString", String.class, String.class);
String idString = type.getName();
if (ReflUtil.getNmsVersionObject().isHigherThanOrEqualTo(ReflUtil.V1_11_R1)) {
// 1.11 requires domain prefix of minecraft.
idString = "minecraft:" + idString;
}
tagSetString.invoke(id, "id", idString);
Method tagSetTag = ReflUtil.getMethodCached(NBTTagCompoundClass, "set", String.class, NBTTagCompoundClass.getSuperclass());
tagSetTag.invoke(tagCompound, "EntityTag", id);
Method stackSetTag = ReflUtil.getMethodCached(NMSItemStackClass, "setTag", NBTTagCompoundClass);
stackSetTag.invoke(stack, tagCompound);
Method asBukkitCopyMethod = ReflUtil.getMethodCached(craftItemStackClass, "asBukkitCopy", NMSItemStackClass);
return (ItemStack) asBukkitCopyMethod.invoke(null, stack);
}
/**
* Converts from an item stack to a spawn egg
*
* @param item - ItemStack, quantity is disregarded
* @return SpawnEgg
*/
static SpawnEggRefl fromItemStack(ItemStack item) throws Exception {
if (item == null)
throw new IllegalArgumentException("Item cannot be null");
if (item.getType() != Material.MONSTER_EGG)
throw new IllegalArgumentException("Item is not a monster egg");
Class<?> NMSItemStackClass = ReflUtil.getNMSClass("ItemStack");
Class<?> craftItemStackClass = ReflUtil.getOBCClass("inventory.CraftItemStack");
Method asNMSCopyMethod = ReflUtil.getMethodCached(craftItemStackClass, "asNMSCopy", ItemStack.class);
Object stack = asNMSCopyMethod.invoke(null, item);
Object tagCompound = ReflUtil.getMethodCached(NMSItemStackClass, "getTag").invoke(stack);
if (tagCompound != null) {
Method tagGetCompound = ReflUtil.getMethodCached(tagCompound.getClass(), "getCompound", String.class);
Object entityTag = tagGetCompound.invoke(tagCompound, "EntityTag");
Method tagGetString = ReflUtil.getMethodCached(entityTag.getClass(), "getString", String.class);
String idString = (String) tagGetString.invoke(entityTag, "id");
if (ReflUtil.getNmsVersionObject().isHigherThanOrEqualTo(ReflUtil.V1_11_R1)) {
idString = idString.split("minecraft:")[1];
}
@SuppressWarnings("deprecation")
EntityType type = EntityType.fromName(idString);
if (type != null) {
return new SpawnEggRefl(type);
} else {
throw new IllegalArgumentException("Unable to parse type from item");
}
} else {
throw new IllegalArgumentException("Item is lacking tag compound");
}
}
}