From 765c42cb452451656d17a7ff4c3978205a0c4306 Mon Sep 17 00:00:00 2001 From: fullwall Date: Tue, 22 Nov 2016 01:00:52 +0800 Subject: [PATCH] Modify EntityTypes hooks to be less invasive --- main/pom.xml | 2 +- .../main/java/net/citizensnpcs/Citizens.java | 1 + .../main/java/net/citizensnpcs/util/NMS.java | 4 ++ .../java/net/citizensnpcs/util/NMSBridge.java | 2 + .../nms/v1_10_R1/util/NMSImpl.java | 5 ++ .../nms/v1_11_R1/entity/EntityHumanNPC.java | 3 + .../v1_11_R1/util/CustomEntityRegistry.java | 58 +++++++++++++++++++ .../nms/v1_11_R1/util/NMSImpl.java | 27 +++++++-- 8 files changed, 97 insertions(+), 5 deletions(-) create mode 100644 v1_11_R1/src/main/java/net/citizensnpcs/nms/v1_11_R1/util/CustomEntityRegistry.java diff --git a/main/pom.xml b/main/pom.xml index cc9d87438..a2698723c 100644 --- a/main/pom.xml +++ b/main/pom.xml @@ -31,7 +31,7 @@ vault-repo - http://nexus.theyeticave.net/content/repositories/pub_releases + http://nexus.hc.to/content/repositories/pub_releases diff --git a/main/src/main/java/net/citizensnpcs/Citizens.java b/main/src/main/java/net/citizensnpcs/Citizens.java index 7154b46ad..5de6f333a 100644 --- a/main/src/main/java/net/citizensnpcs/Citizens.java +++ b/main/src/main/java/net/citizensnpcs/Citizens.java @@ -247,6 +247,7 @@ public class Citizens extends JavaPlugin implements CitizensPlugin { saves.saveToDiskImmediate(); despawnNPCs(); npcRegistry = null; + NMS.shutdown(); } CitizensAPI.shutdown(); diff --git a/main/src/main/java/net/citizensnpcs/util/NMS.java b/main/src/main/java/net/citizensnpcs/util/NMS.java index a9a6e9e70..1ec8667ac 100644 --- a/main/src/main/java/net/citizensnpcs/util/NMS.java +++ b/main/src/main/java/net/citizensnpcs/util/NMS.java @@ -249,6 +249,10 @@ public class NMS { return BRIDGE.shouldJump(entity); } + public static void shutdown() { + BRIDGE.shutdown(); + } + public static boolean tick(Entity next) { return BRIDGE.tick(next); } diff --git a/main/src/main/java/net/citizensnpcs/util/NMSBridge.java b/main/src/main/java/net/citizensnpcs/util/NMSBridge.java index 24791f8ba..039719a0c 100644 --- a/main/src/main/java/net/citizensnpcs/util/NMSBridge.java +++ b/main/src/main/java/net/citizensnpcs/util/NMSBridge.java @@ -126,6 +126,8 @@ public interface NMSBridge { public boolean shouldJump(Entity entity); + public void shutdown(); + public boolean tick(Entity next); public void trySwim(Entity entity); diff --git a/v1_10_R1/src/main/java/net/citizensnpcs/nms/v1_10_R1/util/NMSImpl.java b/v1_10_R1/src/main/java/net/citizensnpcs/nms/v1_10_R1/util/NMSImpl.java index da0279480..5666b83be 100644 --- a/v1_10_R1/src/main/java/net/citizensnpcs/nms/v1_10_R1/util/NMSImpl.java +++ b/v1_10_R1/src/main/java/net/citizensnpcs/nms/v1_10_R1/util/NMSImpl.java @@ -829,6 +829,10 @@ public class NMSImpl implements NMSBridge { return false; } + @Override + public void shutdown() { + } + @Override public boolean tick(org.bukkit.entity.Entity next) { Entity entity = NMSImpl.getHandle(next); @@ -1326,6 +1330,7 @@ public class NMSImpl implements NMSBridge { private static final Field RABBIT_FIELD = NMS.getField(EntityRabbit.class, "bx"); private static final Random RANDOM = Util.getFastRandom(); private static Field SKULL_PROFILE_FIELD; + private static Field TRACKED_ENTITY_SET = NMS.getField(EntityTracker.class, "c"); private static final Field WITHER_BOSS_BAR_FIELD = NMS.getField(EntityWither.class, "bG"); diff --git a/v1_11_R1/src/main/java/net/citizensnpcs/nms/v1_11_R1/entity/EntityHumanNPC.java b/v1_11_R1/src/main/java/net/citizensnpcs/nms/v1_11_R1/entity/EntityHumanNPC.java index f0435a6b1..8d1d1c781 100644 --- a/v1_11_R1/src/main/java/net/citizensnpcs/nms/v1_11_R1/entity/EntityHumanNPC.java +++ b/v1_11_R1/src/main/java/net/citizensnpcs/nms/v1_11_R1/entity/EntityHumanNPC.java @@ -47,6 +47,8 @@ import net.minecraft.server.v1_11_R1.DamageSource; import net.minecraft.server.v1_11_R1.Entity; import net.minecraft.server.v1_11_R1.EntityHuman; import net.minecraft.server.v1_11_R1.EntityPlayer; +import net.minecraft.server.v1_11_R1.EntityTypes; +import net.minecraft.server.v1_11_R1.EntityVillager; import net.minecraft.server.v1_11_R1.EnumGamemode; import net.minecraft.server.v1_11_R1.EnumItemSlot; import net.minecraft.server.v1_11_R1.EnumProtocolDirection; @@ -109,6 +111,7 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable super.A_(); if (npc == null) return; + System.out.println(EntityTypes.getName(EntityVillager.class)); if (updateCounter + 1 > Setting.PACKET_UPDATE_DELAY.asInt()) { updateEffects = true; } diff --git a/v1_11_R1/src/main/java/net/citizensnpcs/nms/v1_11_R1/util/CustomEntityRegistry.java b/v1_11_R1/src/main/java/net/citizensnpcs/nms/v1_11_R1/util/CustomEntityRegistry.java new file mode 100644 index 000000000..ee23b96be --- /dev/null +++ b/v1_11_R1/src/main/java/net/citizensnpcs/nms/v1_11_R1/util/CustomEntityRegistry.java @@ -0,0 +1,58 @@ +package net.citizensnpcs.nms.v1_11_R1.util; + +import java.util.Map; + +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; +import com.google.common.collect.Maps; + +import net.minecraft.server.v1_11_R1.Entity; +import net.minecraft.server.v1_11_R1.MinecraftKey; +import net.minecraft.server.v1_11_R1.RegistryMaterials; + +public class CustomEntityRegistry extends RegistryMaterials> { + private final BiMap> entities = HashBiMap.create(); + private final BiMap, MinecraftKey> entityClasses = this.entities.inverse(); + private final Map, Integer> entityIds = Maps.newHashMap(); + private final RegistryMaterials> wrapped; + + public CustomEntityRegistry(RegistryMaterials> original) { + this.wrapped = original; + } + + @Override + public int a(Class key) { + if (this.entityIds.containsKey(key)) { + return this.entityIds.get(key); + } + + return this.wrapped.a(key); + } + + @Override + public MinecraftKey b(Class value) { + if (entityClasses.containsKey(value)) { + return entityClasses.get(value); + } + + return wrapped.b(value); + } + + @Override + public Class get(MinecraftKey key) { + if (entities.containsKey(key)) { + return entities.get(key); + } + + return wrapped.get(key); + } + + public RegistryMaterials> getWrapped() { + return wrapped; + } + + public void put(int entityId, MinecraftKey key, Class entityClass) { + this.entities.put(key, entityClass); + this.entityIds.put(entityClass, entityId); + } +} \ No newline at end of file diff --git a/v1_11_R1/src/main/java/net/citizensnpcs/nms/v1_11_R1/util/NMSImpl.java b/v1_11_R1/src/main/java/net/citizensnpcs/nms/v1_11_R1/util/NMSImpl.java index a322a0b7f..03cab8505 100644 --- a/v1_11_R1/src/main/java/net/citizensnpcs/nms/v1_11_R1/util/NMSImpl.java +++ b/v1_11_R1/src/main/java/net/citizensnpcs/nms/v1_11_R1/util/NMSImpl.java @@ -2,6 +2,7 @@ package net.citizensnpcs.nms.v1_11_R1.util; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.net.SocketAddress; import java.net.URL; import java.util.ArrayList; @@ -652,7 +653,7 @@ public class NMSImpl implements NMSBridge { @Override public void registerEntityClass(Class clazz) { - if (ENTITY_REGISTRY == null || ENTITY_REGISTRY.b((Class) clazz) != null) + if (ENTITY_REGISTRY == null) return; Class search = clazz; @@ -661,7 +662,7 @@ public class NMSImpl implements NMSBridge { if (key == null) continue; int code = ENTITY_REGISTRY.a((Class) search); - ENTITY_REGISTRY.a(code, key, (Class) clazz); + ENTITY_REGISTRY.put(code, key, (Class) clazz); return; } throw new IllegalArgumentException("unable to find valid entity superclass for class " + clazz.toString()); @@ -861,6 +862,20 @@ public class NMSImpl implements NMSBridge { return false; } + @Override + public void shutdown() { + if (ENTITY_REGISTRY == null) + return; + Field field = NMS.getField(EntityTypes.class, "b"); + Field modifiersField = NMS.getField(Field.class, "modifiers"); + try { + modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); + field.set(null, ENTITY_REGISTRY.getWrapped()); + } catch (Exception e) { + + } + } + @Override public boolean tick(org.bukkit.entity.Entity next) { Entity entity = NMSImpl.getHandle(next); @@ -1345,7 +1360,7 @@ public class NMSImpl implements NMSBridge { private static final float DEFAULT_SPEED = 1F; private static final Field ENDERDRAGON_BATTLE_BAR_FIELD = NMS.getField(EnderDragonBattle.class, "c"); private static final Field ENDERDRAGON_BATTLE_FIELD = NMS.getField(EntityEnderDragon.class, "bJ"); - private static RegistryMaterials> ENTITY_REGISTRY; + private static CustomEntityRegistry ENTITY_REGISTRY; public static Field GOAL_FIELD = NMS.getField(PathfinderGoalSelector.class, "b"); private static final Field JUMP_FIELD = NMS.getField(EntityLiving.class, "bd"); private static Method MAKE_REQUEST; @@ -1362,7 +1377,11 @@ public class NMSImpl implements NMSBridge { static { try { Field field = NMS.getField(EntityTypes.class, "b"); - ENTITY_REGISTRY = (RegistryMaterials>) field.get(null); + Field modifiersField = NMS.getField(Field.class, "modifiers"); + modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); + ENTITY_REGISTRY = new CustomEntityRegistry( + (RegistryMaterials>) field.get(null)); + field.set(null, ENTITY_REGISTRY); } catch (Exception e) { Messaging.logTr(Messages.ERROR_GETTING_ID_MAPPING, e.getMessage()); }