Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package me.greenadine.scarecrow.nms;
- import java.lang.reflect.Field;
- import java.util.List;
- import java.util.Map;
- import org.bukkit.entity.EntityType;
- import net.minecraft.server.v1_12_R1.BiomeBase;
- import net.minecraft.server.v1_12_R1.BiomeBase.BiomeMeta;
- import net.minecraft.server.v1_12_R1.EntityBat;
- import net.minecraft.server.v1_12_R1.EntityChicken;
- import net.minecraft.server.v1_12_R1.EntityCow;
- import net.minecraft.server.v1_12_R1.EntityHorse;
- import net.minecraft.server.v1_12_R1.EntityHorseDonkey;
- import net.minecraft.server.v1_12_R1.EntityHorseMule;
- import net.minecraft.server.v1_12_R1.EntityHorseSkeleton;
- import net.minecraft.server.v1_12_R1.EntityInsentient;
- import net.minecraft.server.v1_12_R1.EntityLlama;
- import net.minecraft.server.v1_12_R1.EntityMushroomCow;
- import net.minecraft.server.v1_12_R1.EntityOcelot;
- import net.minecraft.server.v1_12_R1.EntityParrot;
- import net.minecraft.server.v1_12_R1.EntityPig;
- import net.minecraft.server.v1_12_R1.EntityRabbit;
- import net.minecraft.server.v1_12_R1.EntitySheep;
- import net.minecraft.server.v1_12_R1.EntitySquid;
- import net.minecraft.server.v1_12_R1.EntityTypes;
- import net.minecraft.server.v1_12_R1.EntityVillager;
- public enum CustomEntityType {
- BAT("Bat", 65, EntityType.BAT, EntityBat.class, CustomEntityBat.class),
- CHICKEN("Chicken", 93, EntityType.CHICKEN, EntityChicken.class, CustomEntityBat.class),
- COW("Cow", 92, EntityType.COW, EntityCow.class, CustomEntityBat.class),
- MUSHROOM_COW("Mooshroom", 96, EntityType.MUSHROOM_COW, EntityMushroomCow.class, CustomEntityBat.class),
- OCELOT("Ocelot", 98, EntityType.OCELOT, EntityOcelot.class, CustomEntityBat.class),
- PARROT("Parrot", 105, EntityType.PARROT, EntityParrot.class, CustomEntityBat.class),
- PIG("Pig", 90, EntityType.PIG, EntityPig.class, CustomEntityBat.class),
- RABBIT("Rabbit", 101, EntityType.RABBIT, EntityRabbit.class, CustomEntityBat.class),
- SHEEP("Sheep", 91, EntityType.SHEEP, EntitySheep.class, CustomEntityBat.class),
- SQUID("Squid", 94, EntityType.SQUID, EntitySquid.class, CustomEntityBat.class),
- HORSE("Horse", 100, EntityType.HORSE, EntityHorse.class, CustomEntityBat.class),
- HORSE_SKELETON("Skeleton Horse", 28, EntityType.SKELETON_HORSE, EntityHorseSkeleton.class, CustomEntityBat.class),
- HORSE_DONKEY("Donkey", 31, EntityType.DONKEY, EntityHorseDonkey.class, CustomEntityBat.class),
- HORSE_MULE("MULE", 32, EntityType.MULE, EntityHorseMule.class, CustomEntityBat.class),
- LLAMA("Llama", 103, EntityType.LLAMA, EntityLlama.class, CustomEntityBat.class),
- VILLAGER("Villager", 120, EntityType.VILLAGER, EntityVillager.class, CustomEntityBat.class);
- private String name;
- private int id;
- private EntityType entityType;
- private Class<? extends EntityInsentient> nmsClass;
- private Class<? extends EntityInsentient> customClass;
- private CustomEntityType(String name, int id, EntityType entityType, Class<? extends EntityInsentient> nmsClass, Class<? extends EntityInsentient> customClass)
- {
- this.name = name;
- this.id = id;
- this.entityType = entityType;
- this.nmsClass = nmsClass;
- this.customClass = customClass;
- }
- public String getName()
- {
- return name;
- }
- public int getID()
- {
- return id;
- }
- public EntityType getEntityType()
- {
- return entityType;
- }
- public Class<? extends EntityInsentient> getNMSClass()
- {
- return nmsClass;
- }
- public Class<? extends EntityInsentient> getCustomClass()
- {
- return customClass;
- }
- /**
- * Register our entities.
- */
- public static void registerEntities()
- {
- for (CustomEntityType entity : values())
- a(entity.getCustomClass(), entity.getName(), entity.getID());
- // BiomeBase#biomes became private.
- BiomeBase[] biomes;
- try
- {
- biomes = (BiomeBase[]) getPrivateStatic(BiomeBase.class, "biomes");
- } catch (Exception exc)
- {
- // Unable to fetch.
- return;
- }
- for (BiomeBase biomeBase : biomes)
- {
- if (biomeBase == null)
- break;
- // This changed names from J, K, L and M.
- for (String field : new String[] { "as", "at", "au", "av" })
- {
- try
- {
- Field list = BiomeBase.class.getDeclaredField(field);
- list.setAccessible(true);
- @SuppressWarnings("unchecked")
- List<BiomeMeta> mobList = (List<BiomeMeta>) list.get(biomeBase);
- // Write in our custom class.
- for (BiomeMeta meta : mobList)
- for (CustomEntityType entity : values())
- if (entity.getNMSClass().equals(meta.b))
- meta.b = entity.getCustomClass();
- } catch (Exception e)
- {
- e.printStackTrace();
- }
- }
- }
- }
- /**
- * Unregister our entities to prevent memory leaks. Call on disable.
- */
- @SuppressWarnings("rawtypes")
- public static void unregisterEntities() {
- for (CustomEntityType entity : values()) {
- // Remove our class references.
- try {
- ((Map) getPrivateStatic(EntityTypes.class, "d")).remove(entity.getCustomClass());
- } catch (Exception e) {
- e.printStackTrace();
- }
- try {
- ((Map) getPrivateStatic(EntityTypes.class, "f")).remove(entity.getCustomClass());
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- for (CustomEntityType entity : values())
- try {
- // Unregister each entity by writing the NMS back in place of the custom class.
- a(entity.getNMSClass(), entity.getName(), entity.getID());
- } catch (Exception e) {
- e.printStackTrace();
- }
- // Biomes#biomes was made private so use reflection to get it.
- BiomeBase[] biomes;
- try {
- biomes = (BiomeBase[]) getPrivateStatic(BiomeBase.class, "biomes");
- } catch (Exception exc) {
- // Unable to fetch.
- return;
- }
- for (BiomeBase biomeBase : biomes) {
- if (biomeBase == null)
- break;
- // The list fields changed names but update the meta regardless.
- for (String field : new String[] { "as", "at", "au", "av" })
- try {
- Field list = BiomeBase.class.getDeclaredField(field);
- list.setAccessible(true);
- @SuppressWarnings("unchecked")
- List<BiomeMeta> mobList = (List<BiomeMeta>) list.get(biomeBase);
- // Make sure the NMS class is written back over our custom class.
- for (BiomeMeta meta : mobList)
- for (CustomEntityType entity : values())
- if (entity.getCustomClass().equals(meta.b))
- meta.b = entity.getNMSClass();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- /**
- * A convenience method.
- * @param clazz The class.
- * @param f The string representation of the private static field.
- * @return The object found
- * @throws Exception if unable to get the object.
- */
- @SuppressWarnings("rawtypes")
- private static Object getPrivateStatic(Class clazz, String f) throws Exception {
- Field field = clazz.getDeclaredField(f);
- field.setAccessible(true);
- return field.get(null);
- }
- /*
- * Since 1.7.2 added a check in their entity registration, simply bypass it and write to the maps ourself.
- */
- @SuppressWarnings({ "unchecked", "rawtypes" })
- private static void a(Class paramClass, String paramString, int paramInt) {
- try {
- ((Map) getPrivateStatic(EntityTypes.class, "c")).put(paramString, paramClass);
- ((Map) getPrivateStatic(EntityTypes.class, "d")).put(paramClass, paramString);
- ((Map) getPrivateStatic(EntityTypes.class, "e")).put(Integer.valueOf(paramInt), paramClass);
- ((Map) getPrivateStatic(EntityTypes.class, "f")).put(paramClass, Integer.valueOf(paramInt));
- ((Map) getPrivateStatic(EntityTypes.class, "g")).put(paramString, Integer.valueOf(paramInt));
- } catch (Exception exc) {
- // Unable to register the new class.
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment