diff --git a/src/main/java/net/citizensnpcs/npc/CitizensMobNPC.java b/src/main/java/net/citizensnpcs/npc/CitizensMobNPC.java index b1ae67db4..76a1657f3 100644 --- a/src/main/java/net/citizensnpcs/npc/CitizensMobNPC.java +++ b/src/main/java/net/citizensnpcs/npc/CitizensMobNPC.java @@ -1,33 +1,27 @@ package net.citizensnpcs.npc; import java.lang.reflect.Constructor; -import java.lang.reflect.Field; import java.util.Map; import net.citizensnpcs.api.npc.NPC; +import net.citizensnpcs.util.NMSReflection; import net.minecraft.server.Block; -import net.minecraft.server.Entity; import net.minecraft.server.EntityLiving; -import net.minecraft.server.EntityTypes; import net.minecraft.server.World; import org.bukkit.Location; import org.bukkit.block.BlockFace; import org.bukkit.craftbukkit.CraftWorld; -@SuppressWarnings("unchecked") +import com.google.common.collect.Maps; + public abstract class CitizensMobNPC extends CitizensNPC { private final Constructor constructor; - protected CitizensMobNPC(int id, String name, Class clazz) { super(id, name); - try { - this.constructor = clazz.getConstructor(World.class, NPC.class); - } catch (Exception ex) { - throw new IllegalStateException("unable to find an entity constructor"); - } - if (!classToInt.containsKey(clazz)) - registerEntityClass(clazz); + this.constructor = getConstructor(clazz); + + NMSReflection.registerEntityClass(clazz); } private EntityLiving createEntityFromClass(World world) { @@ -56,32 +50,17 @@ public abstract class CitizensMobNPC extends CitizensNPC { return entity; } - private static Map, Integer> classToInt; - private static Map> intToClass; + private static final Map, Constructor> CONSTRUCTOR_CACHE = Maps + .newHashMap(); - private static void registerEntityClass(Class clazz) { - Class search = clazz; - while ((search = search.getSuperclass()) != null && Entity.class.isAssignableFrom(search)) { - if (!classToInt.containsKey(search)) - continue; - int code = classToInt.get(search); - intToClass.put(code, clazz); - classToInt.put(clazz, code); - return; - } - throw new IllegalArgumentException("unable to find valid entity superclass"); - } - - static { + private static Constructor getConstructor(Class clazz) { + Constructor constructor = CONSTRUCTOR_CACHE.get(clazz); + if (constructor != null) + return constructor; try { - Field field = EntityTypes.class.getDeclaredField("d"); - field.setAccessible(true); - intToClass = (Map>) field.get(null); - field = EntityTypes.class.getDeclaredField("e"); - field.setAccessible(true); - classToInt = (Map, Integer>) field.get(null); + return clazz.getConstructor(World.class, NPC.class); } catch (Exception ex) { - ex.printStackTrace(); + throw new IllegalStateException("unable to find an entity constructor"); } } } \ No newline at end of file diff --git a/src/main/java/net/citizensnpcs/npc/ai/CitizensNavigator.java b/src/main/java/net/citizensnpcs/npc/ai/CitizensNavigator.java index bd6d8bdd1..467d8be98 100644 --- a/src/main/java/net/citizensnpcs/npc/ai/CitizensNavigator.java +++ b/src/main/java/net/citizensnpcs/npc/ai/CitizensNavigator.java @@ -1,8 +1,5 @@ package net.citizensnpcs.npc.ai; -import java.lang.reflect.Field; -import java.util.Map; - import net.citizensnpcs.Settings.Setting; import net.citizensnpcs.api.ai.EntityTarget; import net.citizensnpcs.api.ai.Navigator; @@ -11,17 +8,12 @@ import net.citizensnpcs.api.ai.event.NavigationBeginEvent; import net.citizensnpcs.api.ai.event.NavigationCancelEvent; import net.citizensnpcs.api.ai.event.NavigationReplaceEvent; import net.citizensnpcs.npc.CitizensNPC; -import net.citizensnpcs.util.Messaging; -import net.minecraft.server.EntityLiving; -import net.minecraft.server.Navigation; +import net.citizensnpcs.util.NMSReflection; import org.bukkit.Bukkit; import org.bukkit.Location; -import org.bukkit.entity.EntityType; import org.bukkit.entity.LivingEntity; -import com.google.common.collect.Maps; - public class CitizensNavigator implements Navigator { private PathStrategy executing; private final CitizensNPC npc; @@ -55,25 +47,6 @@ public class CitizensNavigator implements Navigator { return speed; } - private float getSpeedFor(EntityLiving from) { - EntityType entityType = from.getBukkitEntity().getType(); - Float cached = MOVEMENT_SPEEDS.get(entityType); - if (cached != null) - return cached; - if (SPEED_FIELD == null) { - MOVEMENT_SPEEDS.put(entityType, DEFAULT_SPEED); - return DEFAULT_SPEED; - } - try { - float speed = SPEED_FIELD.getFloat(from); - MOVEMENT_SPEEDS.put(entityType, speed); - return speed; - } catch (IllegalAccessException ex) { - ex.printStackTrace(); - return DEFAULT_SPEED; - } - } - @Override public Location getTargetAsLocation() { return executing.getTargetAsLocation(); @@ -91,7 +64,7 @@ public class CitizensNavigator implements Navigator { public void onSpawn() { if (speed == -1) - this.speed = getSpeedFor(npc.getHandle()); + this.speed = NMSReflection.getSpeedFor(npc.getHandle()); updatePathfindingRange(); } @@ -139,43 +112,6 @@ public class CitizensNavigator implements Navigator { } private void updatePathfindingRange() { - if (PATHFINDING_RANGE == null) - return; - Navigation navigation = npc.getHandle().getNavigation(); - try { - PATHFINDING_RANGE.set(navigation, pathfindingRange); - } catch (Exception ex) { - Messaging.logF("Could not update pathfinding range: %s.", ex.getMessage()); - } - } - - private static final float DEFAULT_SPEED = 0.4F; - - private static final Map MOVEMENT_SPEEDS = Maps.newEnumMap(EntityType.class); - private static Field PATHFINDING_RANGE; - private static Field SPEED_FIELD; - static { - // constants taken from source code - MOVEMENT_SPEEDS.put(EntityType.CHICKEN, 0.25F); - MOVEMENT_SPEEDS.put(EntityType.COW, 0.2F); - MOVEMENT_SPEEDS.put(EntityType.CREEPER, 0.3F); - MOVEMENT_SPEEDS.put(EntityType.IRON_GOLEM, 0.15F); - MOVEMENT_SPEEDS.put(EntityType.MUSHROOM_COW, 0.2F); - MOVEMENT_SPEEDS.put(EntityType.OCELOT, 0.23F); - MOVEMENT_SPEEDS.put(EntityType.SHEEP, 0.25F); - MOVEMENT_SPEEDS.put(EntityType.SNOWMAN, 0.25F); - MOVEMENT_SPEEDS.put(EntityType.PIG, 0.27F); - MOVEMENT_SPEEDS.put(EntityType.PLAYER, 1F); - MOVEMENT_SPEEDS.put(EntityType.VILLAGER, 0.3F); - try { - SPEED_FIELD = EntityLiving.class.getDeclaredField("bw"); - SPEED_FIELD.setAccessible(true); - PATHFINDING_RANGE = Navigation.class.getDeclaredField("e"); - PATHFINDING_RANGE.setAccessible(true); - } catch (Exception ex) { - ex.printStackTrace(); - PATHFINDING_RANGE = null; - SPEED_FIELD = null; - } + NMSReflection.updatePathfindingRange(npc, pathfindingRange); } } diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensBlazeNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensBlazeNPC.java index 42b343406..f09bb3618 100644 --- a/src/main/java/net/citizensnpcs/npc/entity/CitizensBlazeNPC.java +++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensBlazeNPC.java @@ -5,6 +5,7 @@ import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.npc.CitizensMobNPC; import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.ai.NPCHolder; +import net.citizensnpcs.util.NMSReflection; import net.citizensnpcs.util.Util; import net.minecraft.server.EntityBlaze; import net.minecraft.server.World; @@ -34,7 +35,7 @@ public class CitizensBlazeNPC extends CitizensMobNPC { super(world); this.npc = (CitizensNPC) npc; if (npc != null) { - Util.clearGoals(goalSelector, targetSelector); + NMSReflection.clearGoals(goalSelector, targetSelector); } } diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensCaveSpiderNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensCaveSpiderNPC.java index b7c7f59bc..372f68537 100644 --- a/src/main/java/net/citizensnpcs/npc/entity/CitizensCaveSpiderNPC.java +++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensCaveSpiderNPC.java @@ -5,6 +5,7 @@ import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.npc.CitizensMobNPC; import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.ai.NPCHolder; +import net.citizensnpcs.util.NMSReflection; import net.citizensnpcs.util.Util; import net.minecraft.server.EntityCaveSpider; import net.minecraft.server.World; @@ -30,7 +31,7 @@ public class CitizensCaveSpiderNPC extends CitizensMobNPC { super(world); this.npc = (CitizensNPC) npc; if (npc != null) { - Util.clearGoals(goalSelector, targetSelector); + NMSReflection.clearGoals(goalSelector, targetSelector); } } diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensChickenNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensChickenNPC.java index af946224a..49d216b92 100644 --- a/src/main/java/net/citizensnpcs/npc/entity/CitizensChickenNPC.java +++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensChickenNPC.java @@ -5,6 +5,7 @@ import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.npc.CitizensMobNPC; import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.ai.NPCHolder; +import net.citizensnpcs.util.NMSReflection; import net.citizensnpcs.util.Util; import net.minecraft.server.EntityChicken; import net.minecraft.server.World; @@ -34,7 +35,7 @@ public class CitizensChickenNPC extends CitizensMobNPC { super(world); this.npc = (CitizensNPC) npc; if (npc != null) { - Util.clearGoals(goalSelector, targetSelector); + NMSReflection.clearGoals(goalSelector, targetSelector); } } diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensCowNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensCowNPC.java index d7257a473..1564af098 100644 --- a/src/main/java/net/citizensnpcs/npc/entity/CitizensCowNPC.java +++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensCowNPC.java @@ -5,6 +5,7 @@ import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.npc.CitizensMobNPC; import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.ai.NPCHolder; +import net.citizensnpcs.util.NMSReflection; import net.citizensnpcs.util.Util; import net.minecraft.server.EntityCow; import net.minecraft.server.World; @@ -34,7 +35,7 @@ public class CitizensCowNPC extends CitizensMobNPC { super(world); this.npc = (CitizensNPC) npc; if (npc != null) { - Util.clearGoals(goalSelector, targetSelector); + NMSReflection.clearGoals(goalSelector, targetSelector); } } diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensCreeperNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensCreeperNPC.java index 91073fb46..e405f1a87 100644 --- a/src/main/java/net/citizensnpcs/npc/entity/CitizensCreeperNPC.java +++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensCreeperNPC.java @@ -5,6 +5,7 @@ import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.npc.CitizensMobNPC; import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.ai.NPCHolder; +import net.citizensnpcs.util.NMSReflection; import net.citizensnpcs.util.Util; import net.minecraft.server.EntityCreeper; import net.minecraft.server.EntityLightning; @@ -35,7 +36,7 @@ public class CitizensCreeperNPC extends CitizensMobNPC { super(world); this.npc = (CitizensNPC) npc; if (npc != null) { - Util.clearGoals(goalSelector, targetSelector); + NMSReflection.clearGoals(goalSelector, targetSelector); } } diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensEnderDragonNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensEnderDragonNPC.java index 704c38799..ecbe80993 100644 --- a/src/main/java/net/citizensnpcs/npc/entity/CitizensEnderDragonNPC.java +++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensEnderDragonNPC.java @@ -5,6 +5,7 @@ import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.npc.CitizensMobNPC; import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.ai.NPCHolder; +import net.citizensnpcs.util.NMSReflection; import net.citizensnpcs.util.Util; import net.minecraft.server.EntityEnderDragon; import net.minecraft.server.World; @@ -30,7 +31,7 @@ public class CitizensEnderDragonNPC extends CitizensMobNPC { super(world); this.npc = (CitizensNPC) npc; if (npc != null) { - Util.clearGoals(goalSelector, targetSelector); + NMSReflection.clearGoals(goalSelector, targetSelector); } } diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensEndermanNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensEndermanNPC.java index 305c5fb0c..d31bd7b11 100644 --- a/src/main/java/net/citizensnpcs/npc/entity/CitizensEndermanNPC.java +++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensEndermanNPC.java @@ -8,6 +8,7 @@ import net.citizensnpcs.npc.CitizensMobNPC; import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.ai.NPCHolder; import net.citizensnpcs.util.Messaging; +import net.citizensnpcs.util.NMSReflection; import net.citizensnpcs.util.Util; import net.minecraft.server.EntityEnderman; import net.minecraft.server.World; @@ -72,7 +73,7 @@ public class CitizensEndermanNPC extends CitizensMobNPC implements Equipable { super(world); this.npc = (CitizensNPC) npc; if (npc != null) { - Util.clearGoals(goalSelector, targetSelector); + NMSReflection.clearGoals(goalSelector, targetSelector); } } diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensGhastNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensGhastNPC.java index f3cfc53e4..f3997b962 100644 --- a/src/main/java/net/citizensnpcs/npc/entity/CitizensGhastNPC.java +++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensGhastNPC.java @@ -5,6 +5,7 @@ import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.npc.CitizensMobNPC; import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.ai.NPCHolder; +import net.citizensnpcs.util.NMSReflection; import net.citizensnpcs.util.Util; import net.minecraft.server.EntityGhast; import net.minecraft.server.World; @@ -34,7 +35,7 @@ public class CitizensGhastNPC extends CitizensMobNPC { super(world); this.npc = (CitizensNPC) npc; if (npc != null) { - Util.clearGoals(goalSelector, targetSelector); + NMSReflection.clearGoals(goalSelector, targetSelector); } } diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensGiantNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensGiantNPC.java index b974cbff5..c0c8dda94 100644 --- a/src/main/java/net/citizensnpcs/npc/entity/CitizensGiantNPC.java +++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensGiantNPC.java @@ -5,6 +5,7 @@ import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.npc.CitizensMobNPC; import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.ai.NPCHolder; +import net.citizensnpcs.util.NMSReflection; import net.citizensnpcs.util.Util; import net.minecraft.server.EntityGiantZombie; import net.minecraft.server.World; @@ -30,7 +31,7 @@ public class CitizensGiantNPC extends CitizensMobNPC { super(world); this.npc = (CitizensNPC) npc; if (npc != null) { - Util.clearGoals(goalSelector, targetSelector); + NMSReflection.clearGoals(goalSelector, targetSelector); } } diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensIronGolemNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensIronGolemNPC.java index 92ec202a7..2b6de8294 100644 --- a/src/main/java/net/citizensnpcs/npc/entity/CitizensIronGolemNPC.java +++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensIronGolemNPC.java @@ -5,6 +5,7 @@ import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.npc.CitizensMobNPC; import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.ai.NPCHolder; +import net.citizensnpcs.util.NMSReflection; import net.citizensnpcs.util.Util; import net.minecraft.server.EntityIronGolem; import net.minecraft.server.World; @@ -30,7 +31,7 @@ public class CitizensIronGolemNPC extends CitizensMobNPC { super(world); this.npc = (CitizensNPC) npc; if (npc != null) { - Util.clearGoals(goalSelector, targetSelector); + NMSReflection.clearGoals(goalSelector, targetSelector); } } diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensMagmaCubeNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensMagmaCubeNPC.java index aa3f5ec87..00cc0ed2a 100644 --- a/src/main/java/net/citizensnpcs/npc/entity/CitizensMagmaCubeNPC.java +++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensMagmaCubeNPC.java @@ -5,6 +5,7 @@ import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.npc.CitizensMobNPC; import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.ai.NPCHolder; +import net.citizensnpcs.util.NMSReflection; import net.citizensnpcs.util.Util; import net.minecraft.server.EntityMagmaCube; import net.minecraft.server.World; @@ -35,7 +36,7 @@ public class CitizensMagmaCubeNPC extends CitizensMobNPC { this.npc = (CitizensNPC) npc; if (npc != null) { setSize(3); - Util.clearGoals(goalSelector, targetSelector); + NMSReflection.clearGoals(goalSelector, targetSelector); } } diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensMushroomCowNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensMushroomCowNPC.java index 59f998bb9..9c192d768 100644 --- a/src/main/java/net/citizensnpcs/npc/entity/CitizensMushroomCowNPC.java +++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensMushroomCowNPC.java @@ -5,6 +5,7 @@ import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.npc.CitizensMobNPC; import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.ai.NPCHolder; +import net.citizensnpcs.util.NMSReflection; import net.citizensnpcs.util.Util; import net.minecraft.server.EntityMushroomCow; import net.minecraft.server.World; @@ -34,7 +35,7 @@ public class CitizensMushroomCowNPC extends CitizensMobNPC { super(world); this.npc = (CitizensNPC) npc; if (npc != null) { - Util.clearGoals(goalSelector, targetSelector); + NMSReflection.clearGoals(goalSelector, targetSelector); } } diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensOcelotNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensOcelotNPC.java index 7ec76133f..4de61ddfc 100644 --- a/src/main/java/net/citizensnpcs/npc/entity/CitizensOcelotNPC.java +++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensOcelotNPC.java @@ -5,6 +5,7 @@ import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.npc.CitizensMobNPC; import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.ai.NPCHolder; +import net.citizensnpcs.util.NMSReflection; import net.citizensnpcs.util.Util; import net.minecraft.server.EntityOcelot; import net.minecraft.server.World; @@ -34,7 +35,7 @@ public class CitizensOcelotNPC extends CitizensMobNPC { super(world); this.npc = (CitizensNPC) npc; if (npc != null) { - Util.clearGoals(goalSelector, targetSelector); + NMSReflection.clearGoals(goalSelector, targetSelector); } } diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensPigNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensPigNPC.java index 2c443e645..6ee041e25 100644 --- a/src/main/java/net/citizensnpcs/npc/entity/CitizensPigNPC.java +++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensPigNPC.java @@ -8,6 +8,7 @@ import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.ai.NPCHolder; import net.citizensnpcs.trait.Saddle; import net.citizensnpcs.util.Messaging; +import net.citizensnpcs.util.NMSReflection; import net.citizensnpcs.util.StringHelper; import net.citizensnpcs.util.Util; import net.minecraft.server.EntityLightning; @@ -61,7 +62,7 @@ public class CitizensPigNPC extends CitizensMobNPC implements Equipable { super(world); this.npc = (CitizensNPC) npc; if (npc != null) { - Util.clearGoals(goalSelector, targetSelector); + NMSReflection.clearGoals(goalSelector, targetSelector); } } diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensPigZombieNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensPigZombieNPC.java index 2c2b79152..a5895c94f 100644 --- a/src/main/java/net/citizensnpcs/npc/entity/CitizensPigZombieNPC.java +++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensPigZombieNPC.java @@ -5,6 +5,7 @@ import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.npc.CitizensMobNPC; import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.ai.NPCHolder; +import net.citizensnpcs.util.NMSReflection; import net.citizensnpcs.util.Util; import net.minecraft.server.EntityPigZombie; import net.minecraft.server.World; @@ -34,7 +35,7 @@ public class CitizensPigZombieNPC extends CitizensMobNPC { super(world); this.npc = (CitizensNPC) npc; if (npc != null) { - Util.clearGoals(goalSelector, targetSelector); + NMSReflection.clearGoals(goalSelector, targetSelector); } } diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensSheepNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensSheepNPC.java index be5131bfb..c46b448be 100644 --- a/src/main/java/net/citizensnpcs/npc/entity/CitizensSheepNPC.java +++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensSheepNPC.java @@ -9,6 +9,7 @@ import net.citizensnpcs.npc.ai.NPCHolder; import net.citizensnpcs.trait.Sheared; import net.citizensnpcs.trait.WoolColor; import net.citizensnpcs.util.Messaging; +import net.citizensnpcs.util.NMSReflection; import net.citizensnpcs.util.StringHelper; import net.citizensnpcs.util.Util; import net.minecraft.server.EntitySheep; @@ -72,7 +73,7 @@ public class CitizensSheepNPC extends CitizensMobNPC implements Equipable { super(world); this.npc = (CitizensNPC) npc; if (npc != null) { - Util.clearGoals(goalSelector, targetSelector); + NMSReflection.clearGoals(goalSelector, targetSelector); } } diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensSilverfishNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensSilverfishNPC.java index c3fbdf674..adb81774c 100644 --- a/src/main/java/net/citizensnpcs/npc/entity/CitizensSilverfishNPC.java +++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensSilverfishNPC.java @@ -5,6 +5,7 @@ import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.npc.CitizensMobNPC; import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.ai.NPCHolder; +import net.citizensnpcs.util.NMSReflection; import net.citizensnpcs.util.Util; import net.minecraft.server.EntitySilverfish; import net.minecraft.server.World; @@ -34,7 +35,7 @@ public class CitizensSilverfishNPC extends CitizensMobNPC { super(world); this.npc = (CitizensNPC) npc; if (npc != null) { - Util.clearGoals(goalSelector, targetSelector); + NMSReflection.clearGoals(goalSelector, targetSelector); } } diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensSkeletonNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensSkeletonNPC.java index ef038a2f6..71f6f69bb 100644 --- a/src/main/java/net/citizensnpcs/npc/entity/CitizensSkeletonNPC.java +++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensSkeletonNPC.java @@ -5,6 +5,7 @@ import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.npc.CitizensMobNPC; import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.ai.NPCHolder; +import net.citizensnpcs.util.NMSReflection; import net.citizensnpcs.util.Util; import net.minecraft.server.EntitySkeleton; import net.minecraft.server.World; @@ -34,7 +35,7 @@ public class CitizensSkeletonNPC extends CitizensMobNPC { super(world); this.npc = (CitizensNPC) npc; if (npc != null) { - Util.clearGoals(goalSelector, targetSelector); + NMSReflection.clearGoals(goalSelector, targetSelector); } } diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensSlimeNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensSlimeNPC.java index 60bf5c273..8d49332ff 100644 --- a/src/main/java/net/citizensnpcs/npc/entity/CitizensSlimeNPC.java +++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensSlimeNPC.java @@ -5,6 +5,7 @@ import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.npc.CitizensMobNPC; import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.ai.NPCHolder; +import net.citizensnpcs.util.NMSReflection; import net.citizensnpcs.util.Util; import net.minecraft.server.EntitySlime; import net.minecraft.server.World; @@ -35,7 +36,7 @@ public class CitizensSlimeNPC extends CitizensMobNPC { this.npc = (CitizensNPC) npc; if (npc != null) { setSize(3); - Util.clearGoals(goalSelector, targetSelector); + NMSReflection.clearGoals(goalSelector, targetSelector); } } diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensSnowmanNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensSnowmanNPC.java index 155499fec..f68907e3c 100644 --- a/src/main/java/net/citizensnpcs/npc/entity/CitizensSnowmanNPC.java +++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensSnowmanNPC.java @@ -5,6 +5,7 @@ import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.npc.CitizensMobNPC; import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.ai.NPCHolder; +import net.citizensnpcs.util.NMSReflection; import net.citizensnpcs.util.Util; import net.minecraft.server.EntitySnowman; import net.minecraft.server.World; @@ -30,7 +31,7 @@ public class CitizensSnowmanNPC extends CitizensMobNPC { super(world); this.npc = (CitizensNPC) npc; if (npc != null) { - Util.clearGoals(goalSelector, targetSelector); + NMSReflection.clearGoals(goalSelector, targetSelector); } } diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensSpiderNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensSpiderNPC.java index 971f292a9..9a85e15d3 100644 --- a/src/main/java/net/citizensnpcs/npc/entity/CitizensSpiderNPC.java +++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensSpiderNPC.java @@ -5,6 +5,7 @@ import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.npc.CitizensMobNPC; import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.ai.NPCHolder; +import net.citizensnpcs.util.NMSReflection; import net.citizensnpcs.util.Util; import net.minecraft.server.EntitySpider; import net.minecraft.server.World; @@ -33,7 +34,7 @@ public class CitizensSpiderNPC extends CitizensMobNPC { super(world); this.npc = (CitizensNPC) npc; if (npc != null) { - Util.clearGoals(goalSelector, targetSelector); + NMSReflection.clearGoals(goalSelector, targetSelector); } } diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensSquidNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensSquidNPC.java index 6516a4007..6c3781f0a 100644 --- a/src/main/java/net/citizensnpcs/npc/entity/CitizensSquidNPC.java +++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensSquidNPC.java @@ -5,6 +5,7 @@ import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.npc.CitizensMobNPC; import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.ai.NPCHolder; +import net.citizensnpcs.util.NMSReflection; import net.citizensnpcs.util.Util; import net.minecraft.server.EntitySquid; import net.minecraft.server.World; @@ -34,7 +35,7 @@ public class CitizensSquidNPC extends CitizensMobNPC { super(world); this.npc = (CitizensNPC) npc; if (npc != null) { - Util.clearGoals(goalSelector, targetSelector); + NMSReflection.clearGoals(goalSelector, targetSelector); } } diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensVillagerNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensVillagerNPC.java index 8c2a1ca97..a5df6412b 100644 --- a/src/main/java/net/citizensnpcs/npc/entity/CitizensVillagerNPC.java +++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensVillagerNPC.java @@ -5,6 +5,7 @@ import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.npc.CitizensMobNPC; import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.ai.NPCHolder; +import net.citizensnpcs.util.NMSReflection; import net.citizensnpcs.util.Util; import net.minecraft.server.EntityHuman; import net.minecraft.server.EntityVillager; @@ -35,7 +36,7 @@ public class CitizensVillagerNPC extends CitizensMobNPC { super(world); this.npc = (CitizensNPC) npc; if (npc != null) { - Util.clearGoals(goalSelector, targetSelector); + NMSReflection.clearGoals(goalSelector, targetSelector); } } @@ -46,6 +47,13 @@ public class CitizensVillagerNPC extends CitizensMobNPC { npc.update(); } + @Override + public boolean c(EntityHuman entityhuman) { + if (npc == null) + return super.c(entityhuman); + return false; // block trades + } + @Override public void collide(net.minecraft.server.Entity entity) { // this method is called by both the entities involved - cancelling @@ -54,13 +62,6 @@ public class CitizensVillagerNPC extends CitizensMobNPC { Util.callCollisionEvent(npc, entity); } - @Override - public boolean c(EntityHuman entityhuman) { - if (npc == null) - return super.c(entityhuman); - return false; // block trades - } - @Override public void g(double x, double y, double z) { if (npc == null) { diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensWolfNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensWolfNPC.java index f01a0b19f..86977ca14 100644 --- a/src/main/java/net/citizensnpcs/npc/entity/CitizensWolfNPC.java +++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensWolfNPC.java @@ -5,6 +5,7 @@ import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.npc.CitizensMobNPC; import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.ai.NPCHolder; +import net.citizensnpcs.util.NMSReflection; import net.citizensnpcs.util.Util; import net.minecraft.server.EntityWolf; import net.minecraft.server.World; @@ -34,7 +35,7 @@ public class CitizensWolfNPC extends CitizensMobNPC { super(world); this.npc = (CitizensNPC) npc; if (npc != null) { - Util.clearGoals(goalSelector, targetSelector); + NMSReflection.clearGoals(goalSelector, targetSelector); } } diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensZombieNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensZombieNPC.java index 4ba89137a..d393f6221 100644 --- a/src/main/java/net/citizensnpcs/npc/entity/CitizensZombieNPC.java +++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensZombieNPC.java @@ -5,6 +5,7 @@ import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.npc.CitizensMobNPC; import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.ai.NPCHolder; +import net.citizensnpcs.util.NMSReflection; import net.citizensnpcs.util.Util; import net.minecraft.server.EntityZombie; import net.minecraft.server.World; @@ -34,7 +35,7 @@ public class CitizensZombieNPC extends CitizensMobNPC { super(world); this.npc = (CitizensNPC) npc; if (npc != null) { - Util.clearGoals(goalSelector, targetSelector); + NMSReflection.clearGoals(goalSelector, targetSelector); } } diff --git a/src/main/java/net/citizensnpcs/npc/entity/EntityHumanNPC.java b/src/main/java/net/citizensnpcs/npc/entity/EntityHumanNPC.java index dc4419540..48a775ebe 100644 --- a/src/main/java/net/citizensnpcs/npc/entity/EntityHumanNPC.java +++ b/src/main/java/net/citizensnpcs/npc/entity/EntityHumanNPC.java @@ -8,7 +8,7 @@ import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.ai.NPCHolder; import net.citizensnpcs.npc.network.EmptyNetHandler; import net.citizensnpcs.npc.network.EmptyNetworkManager; -import net.citizensnpcs.npc.network.NPCSocket; +import net.citizensnpcs.npc.network.EmptySocket; import net.citizensnpcs.util.Util; import net.minecraft.server.EntityPlayer; import net.minecraft.server.EnumGamemode; @@ -30,7 +30,7 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder { this.npc = (CitizensNPC) npc; itemInWorldManager.setGameMode(EnumGamemode.SURVIVAL); - NPCSocket socket = new NPCSocket(); + EmptySocket socket = new EmptySocket(); NetworkManager netMgr = new EmptyNetworkManager(socket, "npc mgr", new NetHandler() { @Override public boolean a() { diff --git a/src/main/java/net/citizensnpcs/npc/network/EmptyNetworkManager.java b/src/main/java/net/citizensnpcs/npc/network/EmptyNetworkManager.java index 45a5852bf..2f92803e9 100644 --- a/src/main/java/net/citizensnpcs/npc/network/EmptyNetworkManager.java +++ b/src/main/java/net/citizensnpcs/npc/network/EmptyNetworkManager.java @@ -1,9 +1,9 @@ package net.citizensnpcs.npc.network; -import java.lang.reflect.Field; import java.net.Socket; import java.security.PrivateKey; +import net.citizensnpcs.util.NMSReflection; import net.minecraft.server.NetHandler; import net.minecraft.server.NetworkManager; import net.minecraft.server.Packet; @@ -13,13 +13,7 @@ public class EmptyNetworkManager extends NetworkManager { public EmptyNetworkManager(Socket socket, String string, NetHandler netHandler, PrivateKey key) { super(socket, string, netHandler, key); - try { - // the field above the 3 synchronized lists - Field f = NetworkManager.class.getDeclaredField("l"); - f.setAccessible(true); - f.set(this, false); - } catch (Exception e) { - } + NMSReflection.stopNetworkThreads(this); } @Override diff --git a/src/main/java/net/citizensnpcs/npc/network/NPCSocket.java b/src/main/java/net/citizensnpcs/npc/network/NPCSocket.java deleted file mode 100644 index f6409fdc1..000000000 --- a/src/main/java/net/citizensnpcs/npc/network/NPCSocket.java +++ /dev/null @@ -1,20 +0,0 @@ -package net.citizensnpcs.npc.network; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.Socket; - -public class NPCSocket extends Socket { - - @Override - public InputStream getInputStream() { - return new ByteArrayInputStream(new byte[10]); - } - - @Override - public OutputStream getOutputStream() { - return new ByteArrayOutputStream(); - } -} \ No newline at end of file diff --git a/src/main/java/net/citizensnpcs/util/NMSReflection.java b/src/main/java/net/citizensnpcs/util/NMSReflection.java new file mode 100644 index 000000000..77759e03b --- /dev/null +++ b/src/main/java/net/citizensnpcs/util/NMSReflection.java @@ -0,0 +1,141 @@ +package net.citizensnpcs.util; + +import java.lang.reflect.Field; +import java.util.List; +import java.util.Map; + +import net.citizensnpcs.npc.CitizensNPC; +import net.minecraft.server.Entity; +import net.minecraft.server.EntityLiving; +import net.minecraft.server.EntityTypes; +import net.minecraft.server.Navigation; +import net.minecraft.server.NetworkManager; +import net.minecraft.server.PathfinderGoalSelector; + +import org.bukkit.entity.EntityType; + +import com.google.common.collect.Maps; + +@SuppressWarnings("unchecked") +public class NMSReflection { + private NMSReflection() { + // util class + } + + private static final float DEFAULT_SPEED = 0.4F; + private static Map, Integer> ENTITY_CLASS_TO_INT; + private static Map> ENTITY_INT_TO_CLASS; + private static Field GOAL_FIELD; + private static final Map MOVEMENT_SPEEDS = Maps.newEnumMap(EntityType.class); + private static Field PATHFINDING_RANGE; + + private static Field SPEED_FIELD; + + private static Field THREAD_STOPPER; + + public static void clearGoals(PathfinderGoalSelector... goalSelectors) { + if (NMSReflection.GOAL_FIELD == null || goalSelectors == null) + return; + for (PathfinderGoalSelector selector : goalSelectors) { + try { + List list = (List) NMSReflection.GOAL_FIELD.get(selector); + list.clear(); + } catch (Exception e) { + } + } + } + + private static Field getField(Class clazz, String field) { + Field f = null; + try { + f = clazz.getDeclaredField(field); + f.setAccessible(true); + } catch (Exception e) { + } + return f; + } + + public static float getSpeedFor(EntityLiving from) { + EntityType entityType = from.getBukkitEntity().getType(); + Float cached = MOVEMENT_SPEEDS.get(entityType); + if (cached != null) + return cached; + if (SPEED_FIELD == null) { + MOVEMENT_SPEEDS.put(entityType, DEFAULT_SPEED); + return DEFAULT_SPEED; + } + try { + float speed = SPEED_FIELD.getFloat(from); + MOVEMENT_SPEEDS.put(entityType, speed); + return speed; + } catch (IllegalAccessException ex) { + ex.printStackTrace(); + return DEFAULT_SPEED; + } + } + + public static void registerEntityClass(Class clazz) { + if (ENTITY_CLASS_TO_INT.containsKey(clazz)) + return; + Class search = clazz; + while ((search = search.getSuperclass()) != null && Entity.class.isAssignableFrom(search)) { + if (!ENTITY_CLASS_TO_INT.containsKey(search)) + continue; + int code = ENTITY_CLASS_TO_INT.get(search); + ENTITY_INT_TO_CLASS.put(code, clazz); + ENTITY_CLASS_TO_INT.put(clazz, code); + return; + } + throw new IllegalArgumentException("unable to find valid entity superclass"); + } + public static void stopNetworkThreads(NetworkManager manager) { + if (THREAD_STOPPER == null) + return; + try { + THREAD_STOPPER.set(manager, false); + } catch (Exception e) { + } + } + public static void updatePathfindingRange(CitizensNPC npc, float pathfindingRange) { + if (PATHFINDING_RANGE == null) + return; + Navigation navigation = npc.getHandle().getNavigation(); + try { + PATHFINDING_RANGE.set(navigation, pathfindingRange); + } catch (Exception ex) { + Messaging.logF("Could not update pathfinding range: %s.", ex.getMessage()); + } + } + + static { + // true field above false and three synchronised lists + THREAD_STOPPER = getField(NetworkManager.class, "m"); + + // constants taken from source code + MOVEMENT_SPEEDS.put(EntityType.CHICKEN, 0.25F); + MOVEMENT_SPEEDS.put(EntityType.COW, 0.2F); + MOVEMENT_SPEEDS.put(EntityType.CREEPER, 0.3F); + MOVEMENT_SPEEDS.put(EntityType.IRON_GOLEM, 0.15F); + MOVEMENT_SPEEDS.put(EntityType.MUSHROOM_COW, 0.2F); + MOVEMENT_SPEEDS.put(EntityType.OCELOT, 0.23F); + MOVEMENT_SPEEDS.put(EntityType.SHEEP, 0.25F); + MOVEMENT_SPEEDS.put(EntityType.SNOWMAN, 0.25F); + MOVEMENT_SPEEDS.put(EntityType.PIG, 0.27F); + MOVEMENT_SPEEDS.put(EntityType.PLAYER, 1F); + MOVEMENT_SPEEDS.put(EntityType.VILLAGER, 0.3F); + + SPEED_FIELD = getField(EntityLiving.class, "bw"); + PATHFINDING_RANGE = getField(Navigation.class, "e"); + GOAL_FIELD = getField(PathfinderGoalSelector.class, "a"); + + try { + Field field = getField(EntityTypes.class, "d"); + field.setAccessible(true); + ENTITY_INT_TO_CLASS = (Map>) field.get(null); + field = getField(EntityTypes.class, "e"); + field.setAccessible(true); + ENTITY_CLASS_TO_INT = (Map, Integer>) field.get(null); + } catch (Exception e) { + } + } +} diff --git a/src/main/java/net/citizensnpcs/util/Util.java b/src/main/java/net/citizensnpcs/util/Util.java index 749fe1aae..6f196fa94 100644 --- a/src/main/java/net/citizensnpcs/util/Util.java +++ b/src/main/java/net/citizensnpcs/util/Util.java @@ -1,19 +1,10 @@ package net.citizensnpcs.util; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; -import java.util.Map; - import net.citizensnpcs.Settings.Setting; import net.citizensnpcs.api.event.NPCCollisionEvent; import net.citizensnpcs.api.event.NPCPushEvent; import net.citizensnpcs.api.npc.NPC; import net.minecraft.server.Packet; -import net.minecraft.server.PathfinderGoalSelector; import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; @@ -26,18 +17,12 @@ import org.bukkit.entity.Player; import org.bukkit.util.Vector; import com.google.common.base.Splitter; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; public class Util { // Static class for small (emphasis small) utility methods private Util() { } - private static Field GOAL_FIELD; - - private static final Map, Class> primitiveClassMap = Maps.newHashMap(); - public static void callCollisionEvent(NPC npc, net.minecraft.server.Entity entity) { if (NPCCollisionEvent.getHandlerList().getRegisteredListeners().length > 0) Bukkit.getPluginManager().callEvent(new NPCCollisionEvent(npc, entity.getBukkitEntity())); @@ -49,78 +34,6 @@ public class Util { return event; } - public static void clearGoals(PathfinderGoalSelector... goalSelectors) { - if (GOAL_FIELD == null || goalSelectors == null) - return; - for (PathfinderGoalSelector selector : goalSelectors) { - try { - List list = (List) GOAL_FIELD.get(selector); - list.clear(); - } catch (Exception e) { - } - } - } - - /** - * Given a set of instantiation parameters, attempts to find a matching - * constructor with the greatest number of matching class parameters and - * invokes it. - * - * @param clazz - * @param params - * @return null if no instance could be created with the given parameters - */ - public static T createInstance(Class clazz, Object... params) { - Validate.notNull(params); - Validate.noNullElements(params); - try { - if (params.length == 0) { - return clazz.newInstance(); - } - return createInstance0(clazz, params); - } catch (Exception e) { - return null; - } - } - - private static T createInstance0(Class clazz, Object[] params) - throws InstantiationException, IllegalAccessException, IllegalArgumentException, - InvocationTargetException { - - @SuppressWarnings("unchecked") - Constructor[] constructors = (Constructor[]) clazz.getConstructors(); - Arrays.sort(constructors, new Comparator>() { - @Override - public int compare(Constructor o1, Constructor o2) { - return o2.getParameterTypes().length - o1.getParameterTypes().length; - } - }); - constructorLoop: for (Constructor constructor : constructors) { - Class[] types = constructor.getParameterTypes(); - if (Sets.newHashSet(types).size() != types.length) - continue; - // we can't resolve the order of the constructor parameters - if (types.length == 0) - return clazz.newInstance(); - Object[] rebuild = new Object[types.length]; - for (Object param : params) { - for (int i = 0; i < types.length; ++i) { - if (param.getClass() == types[i] || primitiveClassMap.get(param.getClass()) == types[i] - || searchInterfaces(param.getClass(), types[i])) { - rebuild[i] = param; - } - } - } - for (Object constructorParam : rebuild) { - if (constructorParam == null) - continue constructorLoop; - } - - return constructor.newInstance(rebuild); - } - return null; - } - public static boolean isSettingFulfilled(Player player, Setting setting) { String parts = setting.asString(); if (parts.contains("*")) @@ -146,13 +59,6 @@ public class Util { return type; } - private static boolean searchInterfaces(Class class1, Class class2) { - for (Class test : class1.getInterfaces()) - if (test == class2) - return true; - return false; - } - public static void sendPacketNearby(Location location, Packet packet, double radius) { radius *= radius; final World world = location.getWorld(); @@ -177,28 +83,4 @@ public class Util { } } } - - static { - primitiveClassMap.put(Boolean.class, boolean.class); - primitiveClassMap.put(Byte.class, byte.class); - primitiveClassMap.put(Short.class, short.class); - primitiveClassMap.put(Character.class, char.class); - primitiveClassMap.put(Integer.class, int.class); - primitiveClassMap.put(Long.class, long.class); - primitiveClassMap.put(Float.class, float.class); - primitiveClassMap.put(Double.class, double.class); - primitiveClassMap.put(boolean.class, Boolean.class); - primitiveClassMap.put(byte.class, Byte.class); - primitiveClassMap.put(short.class, Short.class); - primitiveClassMap.put(char.class, Character.class); - primitiveClassMap.put(int.class, Integer.class); - primitiveClassMap.put(long.class, Long.class); - primitiveClassMap.put(float.class, Float.class); - primitiveClassMap.put(double.class, Double.class); - try { - GOAL_FIELD = PathfinderGoalSelector.class.getDeclaredField("a"); - } catch (Exception e) { - GOAL_FIELD = null; - } - } }