diff --git a/HolographicDisplays/Plugin/com/gmail/filoghost/holographicdisplays/HolographicDisplays.java b/HolographicDisplays/Plugin/com/gmail/filoghost/holographicdisplays/HolographicDisplays.java index 628f7c32..0769f7a8 100644 --- a/HolographicDisplays/Plugin/com/gmail/filoghost/holographicdisplays/HolographicDisplays.java +++ b/HolographicDisplays/Plugin/com/gmail/filoghost/holographicdisplays/HolographicDisplays.java @@ -130,7 +130,7 @@ public class HolographicDisplays extends JavaPlugin { getLogger().info("Trying to enable Cauldron/MCPC+ support..."); } - nmsManager.registerCustomEntities(); + nmsManager.setup(); if (VersionUtils.isMCPCOrCauldron()) { getLogger().info("Successfully added support for Cauldron/MCPC+!"); diff --git a/HolographicDisplays/Plugin/com/gmail/filoghost/holographicdisplays/nms/interfaces/NMSManager.java b/HolographicDisplays/Plugin/com/gmail/filoghost/holographicdisplays/nms/interfaces/NMSManager.java index ccc35ea4..5a35ac5c 100644 --- a/HolographicDisplays/Plugin/com/gmail/filoghost/holographicdisplays/nms/interfaces/NMSManager.java +++ b/HolographicDisplays/Plugin/com/gmail/filoghost/holographicdisplays/nms/interfaces/NMSManager.java @@ -15,7 +15,7 @@ import com.gmail.filoghost.holographicdisplays.object.line.CraftTouchSlimeLine; public interface NMSManager { // A method to register all the custom entities of the plugin, it may fail. - public void registerCustomEntities() throws Exception; + public void setup() throws Exception; public NMSArmorStand spawnNMSArmorStand(org.bukkit.World world, double x, double y, double z, CraftHologramLine parentPiece); diff --git a/HolographicDisplays/Plugin/com/gmail/filoghost/holographicdisplays/nms/v1_6_R3/NmsManagerImpl.java b/HolographicDisplays/Plugin/com/gmail/filoghost/holographicdisplays/nms/v1_6_R3/NmsManagerImpl.java index 620a4203..5f02a187 100644 --- a/HolographicDisplays/Plugin/com/gmail/filoghost/holographicdisplays/nms/v1_6_R3/NmsManagerImpl.java +++ b/HolographicDisplays/Plugin/com/gmail/filoghost/holographicdisplays/nms/v1_6_R3/NmsManagerImpl.java @@ -1,10 +1,14 @@ package com.gmail.filoghost.holographicdisplays.nms.v1_6_R3; +import java.lang.reflect.Method; + import net.minecraft.server.v1_6_R3.Entity; import net.minecraft.server.v1_6_R3.EntityTypes; import net.minecraft.server.v1_6_R3.WorldServer; +import net.minecraft.server.v1_8_R1.MathHelper; import org.apache.commons.lang.NotImplementedException; +import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.craftbukkit.v1_6_R3.CraftWorld; import org.bukkit.craftbukkit.v1_6_R3.entity.CraftEntity; @@ -23,16 +27,24 @@ import com.gmail.filoghost.holographicdisplays.object.line.CraftItemLine; import com.gmail.filoghost.holographicdisplays.object.line.CraftTouchSlimeLine; import com.gmail.filoghost.holographicdisplays.util.DebugHandler; import com.gmail.filoghost.holographicdisplays.util.ReflectionUtils; +import com.gmail.filoghost.holographicdisplays.util.Validator; import com.gmail.filoghost.holographicdisplays.util.VersionUtils; public class NmsManagerImpl implements NMSManager { + private Method validateEntityMethod; + @Override - public void registerCustomEntities() throws Exception { + public void setup() throws Exception { registerCustomEntity(EntityNMSHorse.class, "EntityHorse", 100); registerCustomEntity(EntityNMSWitherSkull.class, "WitherSkull", 19); registerCustomEntity(EntityNMSItem.class, "Item", 1); registerCustomEntity(EntityNMSSlime.class, "Slime", 55); + + if (!VersionUtils.isMCPCOrCauldron()) { + validateEntityMethod = World.class.getDeclaredMethod("a", Entity.class); + validateEntityMethod.setAccessible(true); + } } @SuppressWarnings("rawtypes") @@ -54,7 +66,7 @@ public class NmsManagerImpl implements NMSManager { WorldServer nmsWorld = ((CraftWorld) world).getHandle(); EntityNMSHorse invisibleHorse = new EntityNMSHorse(nmsWorld, parentPiece); invisibleHorse.setLocationNMS(x, y, z); - if (!nmsWorld.addEntity(invisibleHorse, SpawnReason.CUSTOM)) { + if (!addEntityToWorld(nmsWorld, invisibleHorse)) { DebugHandler.handleSpawnFail(parentPiece); } return invisibleHorse; @@ -65,7 +77,7 @@ public class NmsManagerImpl implements NMSManager { WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle(); EntityNMSWitherSkull staticWitherSkull = new EntityNMSWitherSkull(nmsWorld, parentPiece); staticWitherSkull.setLocationNMS(x, y, z); - if (!nmsWorld.addEntity(staticWitherSkull, SpawnReason.CUSTOM)) { + if (!addEntityToWorld(nmsWorld, staticWitherSkull)) { DebugHandler.handleSpawnFail(parentPiece); } return staticWitherSkull; @@ -77,7 +89,7 @@ public class NmsManagerImpl implements NMSManager { EntityNMSItem customItem = new EntityNMSItem(nmsWorld, parentPiece); customItem.setLocationNMS(x, y, z); customItem.setItemStackNMS(stack); - if (!nmsWorld.addEntity(customItem, SpawnReason.CUSTOM)) { + if (!addEntityToWorld(nmsWorld, customItem)) { DebugHandler.handleSpawnFail(parentPiece); } return customItem; @@ -88,12 +100,41 @@ public class NmsManagerImpl implements NMSManager { WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle(); EntityNMSSlime touchSlime = new EntityNMSSlime(nmsWorld, parentPiece); touchSlime.setLocationNMS(x, y, z); - if (!nmsWorld.addEntity(touchSlime, SpawnReason.CUSTOM)) { + if (!addEntityToWorld(nmsWorld, touchSlime)) { DebugHandler.handleSpawnFail(parentPiece); } return touchSlime; } + @SuppressWarnings("unchecked") + private boolean addEntityToWorld(WorldServer nmsWorld, Entity nmsEntity) { + Validator.isTrue(Bukkit.isPrimaryThread(), "Async entity add"); + + if (validateEntityMethod == null) { + return nmsWorld.addEntity(nmsEntity, SpawnReason.CUSTOM); + } + + final int chunkX = MathHelper.floor(nmsEntity.locX / 16.0); + final int chunkZ = MathHelper.floor(nmsEntity.locZ / 16.0); + + if (!nmsWorld.chunkProviderServer.isChunkLoaded(chunkX, chunkZ)) { + // This should never happen + nmsEntity.dead = true; + return false; + } + + nmsWorld.getChunkAt(chunkX, chunkZ).a(nmsEntity); + nmsWorld.entityList.add(nmsEntity); + + try { + validateEntityMethod.invoke(nmsWorld, nmsEntity); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + return true; + } + @Override public boolean isNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) { return ((CraftEntity) bukkitEntity).getHandle() instanceof NMSEntityBase; diff --git a/HolographicDisplays/Plugin/com/gmail/filoghost/holographicdisplays/nms/v1_7_R1/NmsManagerImpl.java b/HolographicDisplays/Plugin/com/gmail/filoghost/holographicdisplays/nms/v1_7_R1/NmsManagerImpl.java index 9bd93367..2858be82 100644 --- a/HolographicDisplays/Plugin/com/gmail/filoghost/holographicdisplays/nms/v1_7_R1/NmsManagerImpl.java +++ b/HolographicDisplays/Plugin/com/gmail/filoghost/holographicdisplays/nms/v1_7_R1/NmsManagerImpl.java @@ -1,10 +1,13 @@ package com.gmail.filoghost.holographicdisplays.nms.v1_7_R1; +import java.lang.reflect.Method; import net.minecraft.server.v1_7_R1.Entity; import net.minecraft.server.v1_7_R1.EntityTypes; import net.minecraft.server.v1_7_R1.WorldServer; +import net.minecraft.server.v1_8_R1.MathHelper; import org.apache.commons.lang.NotImplementedException; +import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.craftbukkit.v1_7_R1.CraftWorld; import org.bukkit.craftbukkit.v1_7_R1.entity.CraftEntity; @@ -23,16 +26,24 @@ import com.gmail.filoghost.holographicdisplays.object.line.CraftItemLine; import com.gmail.filoghost.holographicdisplays.object.line.CraftTouchSlimeLine; import com.gmail.filoghost.holographicdisplays.util.DebugHandler; import com.gmail.filoghost.holographicdisplays.util.ReflectionUtils; +import com.gmail.filoghost.holographicdisplays.util.Validator; import com.gmail.filoghost.holographicdisplays.util.VersionUtils; public class NmsManagerImpl implements NMSManager { + private Method validateEntityMethod; + @Override - public void registerCustomEntities() throws Exception { + public void setup() throws Exception { registerCustomEntity(EntityNMSHorse.class, "EntityHorse", 100); registerCustomEntity(EntityNMSWitherSkull.class, "WitherSkull", 19); registerCustomEntity(EntityNMSItem.class, "Item", 1); registerCustomEntity(EntityNMSSlime.class, "Slime", 55); + + if (!VersionUtils.isMCPCOrCauldron()) { + validateEntityMethod = World.class.getDeclaredMethod("a", Entity.class); + validateEntityMethod.setAccessible(true); + } } @SuppressWarnings("rawtypes") @@ -54,7 +65,7 @@ public class NmsManagerImpl implements NMSManager { WorldServer nmsWorld = ((CraftWorld) world).getHandle(); EntityNMSHorse invisibleHorse = new EntityNMSHorse(nmsWorld, parentPiece); invisibleHorse.setLocationNMS(x, y, z); - if (!nmsWorld.addEntity(invisibleHorse, SpawnReason.CUSTOM)) { + if (!addEntityToWorld(nmsWorld, invisibleHorse)) { DebugHandler.handleSpawnFail(parentPiece); } return invisibleHorse; @@ -65,7 +76,7 @@ public class NmsManagerImpl implements NMSManager { WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle(); EntityNMSWitherSkull staticWitherSkull = new EntityNMSWitherSkull(nmsWorld, parentPiece); staticWitherSkull.setLocationNMS(x, y, z); - if (!nmsWorld.addEntity(staticWitherSkull, SpawnReason.CUSTOM)) { + if (!addEntityToWorld(nmsWorld, staticWitherSkull)) { DebugHandler.handleSpawnFail(parentPiece); } return staticWitherSkull; @@ -77,7 +88,7 @@ public class NmsManagerImpl implements NMSManager { EntityNMSItem customItem = new EntityNMSItem(nmsWorld, parentPiece); customItem.setLocationNMS(x, y, z); customItem.setItemStackNMS(stack); - if (!nmsWorld.addEntity(customItem, SpawnReason.CUSTOM)) { + if (!addEntityToWorld(nmsWorld, customItem)) { DebugHandler.handleSpawnFail(parentPiece); } return customItem; @@ -88,12 +99,41 @@ public class NmsManagerImpl implements NMSManager { WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle(); EntityNMSSlime touchSlime = new EntityNMSSlime(nmsWorld, parentPiece); touchSlime.setLocationNMS(x, y, z); - if (!nmsWorld.addEntity(touchSlime, SpawnReason.CUSTOM)) { + if (!addEntityToWorld(nmsWorld, touchSlime)) { DebugHandler.handleSpawnFail(parentPiece); } return touchSlime; } + @SuppressWarnings("unchecked") + private boolean addEntityToWorld(WorldServer nmsWorld, Entity nmsEntity) { + Validator.isTrue(Bukkit.isPrimaryThread(), "Async entity add"); + + if (validateEntityMethod == null) { + return nmsWorld.addEntity(nmsEntity, SpawnReason.CUSTOM); + } + + final int chunkX = MathHelper.floor(nmsEntity.locX / 16.0); + final int chunkZ = MathHelper.floor(nmsEntity.locZ / 16.0); + + if (!nmsWorld.chunkProviderServer.isChunkLoaded(chunkX, chunkZ)) { + // This should never happen + nmsEntity.dead = true; + return false; + } + + nmsWorld.getChunkAt(chunkX, chunkZ).a(nmsEntity); + nmsWorld.entityList.add(nmsEntity); + + try { + validateEntityMethod.invoke(nmsWorld, nmsEntity); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + return true; + } + @Override public boolean isNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) { return ((CraftEntity) bukkitEntity).getHandle() instanceof NMSEntityBase; diff --git a/HolographicDisplays/Plugin/com/gmail/filoghost/holographicdisplays/nms/v1_7_R2/NmsManagerImpl.java b/HolographicDisplays/Plugin/com/gmail/filoghost/holographicdisplays/nms/v1_7_R2/NmsManagerImpl.java index e29fa1eb..750b9eb6 100644 --- a/HolographicDisplays/Plugin/com/gmail/filoghost/holographicdisplays/nms/v1_7_R2/NmsManagerImpl.java +++ b/HolographicDisplays/Plugin/com/gmail/filoghost/holographicdisplays/nms/v1_7_R2/NmsManagerImpl.java @@ -1,10 +1,13 @@ package com.gmail.filoghost.holographicdisplays.nms.v1_7_R2; +import java.lang.reflect.Method; import net.minecraft.server.v1_7_R2.Entity; import net.minecraft.server.v1_7_R2.EntityTypes; import net.minecraft.server.v1_7_R2.WorldServer; +import net.minecraft.server.v1_8_R1.MathHelper; import org.apache.commons.lang.NotImplementedException; +import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.craftbukkit.v1_7_R2.CraftWorld; import org.bukkit.craftbukkit.v1_7_R2.entity.CraftEntity; @@ -23,16 +26,24 @@ import com.gmail.filoghost.holographicdisplays.object.line.CraftItemLine; import com.gmail.filoghost.holographicdisplays.object.line.CraftTouchSlimeLine; import com.gmail.filoghost.holographicdisplays.util.DebugHandler; import com.gmail.filoghost.holographicdisplays.util.ReflectionUtils; +import com.gmail.filoghost.holographicdisplays.util.Validator; import com.gmail.filoghost.holographicdisplays.util.VersionUtils; public class NmsManagerImpl implements NMSManager { + private Method validateEntityMethod; + @Override - public void registerCustomEntities() throws Exception { + public void setup() throws Exception { registerCustomEntity(EntityNMSHorse.class, "EntityHorse", 100); registerCustomEntity(EntityNMSWitherSkull.class, "WitherSkull", 19); registerCustomEntity(EntityNMSItem.class, "Item", 1); registerCustomEntity(EntityNMSSlime.class, "Slime", 55); + + if (!VersionUtils.isMCPCOrCauldron()) { + validateEntityMethod = World.class.getDeclaredMethod("a", Entity.class); + validateEntityMethod.setAccessible(true); + } } @SuppressWarnings("rawtypes") @@ -54,7 +65,7 @@ public class NmsManagerImpl implements NMSManager { WorldServer nmsWorld = ((CraftWorld) world).getHandle(); EntityNMSHorse invisibleHorse = new EntityNMSHorse(nmsWorld, parentPiece); invisibleHorse.setLocationNMS(x, y, z); - if (!nmsWorld.addEntity(invisibleHorse, SpawnReason.CUSTOM)) { + if (!addEntityToWorld(nmsWorld, invisibleHorse)) { DebugHandler.handleSpawnFail(parentPiece); } return invisibleHorse; @@ -65,7 +76,7 @@ public class NmsManagerImpl implements NMSManager { WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle(); EntityNMSWitherSkull staticWitherSkull = new EntityNMSWitherSkull(nmsWorld, parentPiece); staticWitherSkull.setLocationNMS(x, y, z); - if (!nmsWorld.addEntity(staticWitherSkull, SpawnReason.CUSTOM)) { + if (!addEntityToWorld(nmsWorld, staticWitherSkull)) { DebugHandler.handleSpawnFail(parentPiece); } return staticWitherSkull; @@ -77,7 +88,7 @@ public class NmsManagerImpl implements NMSManager { EntityNMSItem customItem = new EntityNMSItem(nmsWorld, parentPiece); customItem.setLocationNMS(x, y, z); customItem.setItemStackNMS(stack); - if (!nmsWorld.addEntity(customItem, SpawnReason.CUSTOM)) { + if (!addEntityToWorld(nmsWorld, customItem)) { DebugHandler.handleSpawnFail(parentPiece); } return customItem; @@ -88,12 +99,41 @@ public class NmsManagerImpl implements NMSManager { WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle(); EntityNMSSlime touchSlime = new EntityNMSSlime(nmsWorld, parentPiece); touchSlime.setLocationNMS(x, y, z); - if (!nmsWorld.addEntity(touchSlime, SpawnReason.CUSTOM)) { + if (!addEntityToWorld(nmsWorld, touchSlime)) { DebugHandler.handleSpawnFail(parentPiece); } return touchSlime; } + @SuppressWarnings("unchecked") + private boolean addEntityToWorld(WorldServer nmsWorld, Entity nmsEntity) { + Validator.isTrue(Bukkit.isPrimaryThread(), "Async entity add"); + + if (validateEntityMethod == null) { + return nmsWorld.addEntity(nmsEntity, SpawnReason.CUSTOM); + } + + final int chunkX = MathHelper.floor(nmsEntity.locX / 16.0); + final int chunkZ = MathHelper.floor(nmsEntity.locZ / 16.0); + + if (!nmsWorld.chunkProviderServer.isChunkLoaded(chunkX, chunkZ)) { + // This should never happen + nmsEntity.dead = true; + return false; + } + + nmsWorld.getChunkAt(chunkX, chunkZ).a(nmsEntity); + nmsWorld.entityList.add(nmsEntity); + + try { + validateEntityMethod.invoke(nmsWorld, nmsEntity); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + return true; + } + @Override public boolean isNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) { return ((CraftEntity) bukkitEntity).getHandle() instanceof NMSEntityBase; diff --git a/HolographicDisplays/Plugin/com/gmail/filoghost/holographicdisplays/nms/v1_7_R3/NmsManagerImpl.java b/HolographicDisplays/Plugin/com/gmail/filoghost/holographicdisplays/nms/v1_7_R3/NmsManagerImpl.java index 2ea44b71..eeaa2d66 100644 --- a/HolographicDisplays/Plugin/com/gmail/filoghost/holographicdisplays/nms/v1_7_R3/NmsManagerImpl.java +++ b/HolographicDisplays/Plugin/com/gmail/filoghost/holographicdisplays/nms/v1_7_R3/NmsManagerImpl.java @@ -1,10 +1,14 @@ package com.gmail.filoghost.holographicdisplays.nms.v1_7_R3; +import java.lang.reflect.Method; + import net.minecraft.server.v1_7_R3.Entity; import net.minecraft.server.v1_7_R3.EntityTypes; import net.minecraft.server.v1_7_R3.WorldServer; +import net.minecraft.server.v1_8_R1.MathHelper; import org.apache.commons.lang.NotImplementedException; +import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.craftbukkit.v1_7_R3.CraftWorld; import org.bukkit.craftbukkit.v1_7_R3.entity.CraftEntity; @@ -23,16 +27,24 @@ import com.gmail.filoghost.holographicdisplays.object.line.CraftItemLine; import com.gmail.filoghost.holographicdisplays.object.line.CraftTouchSlimeLine; import com.gmail.filoghost.holographicdisplays.util.DebugHandler; import com.gmail.filoghost.holographicdisplays.util.ReflectionUtils; +import com.gmail.filoghost.holographicdisplays.util.Validator; import com.gmail.filoghost.holographicdisplays.util.VersionUtils; public class NmsManagerImpl implements NMSManager { + private Method validateEntityMethod; + @Override - public void registerCustomEntities() throws Exception { + public void setup() throws Exception { registerCustomEntity(EntityNMSHorse.class, "EntityHorse", 100); registerCustomEntity(EntityNMSWitherSkull.class, "WitherSkull", 19); registerCustomEntity(EntityNMSItem.class, "Item", 1); registerCustomEntity(EntityNMSSlime.class, "Slime", 55); + + if (!VersionUtils.isMCPCOrCauldron()) { + validateEntityMethod = World.class.getDeclaredMethod("a", Entity.class); + validateEntityMethod.setAccessible(true); + } } @SuppressWarnings("rawtypes") @@ -54,7 +66,7 @@ public class NmsManagerImpl implements NMSManager { WorldServer nmsWorld = ((CraftWorld) world).getHandle(); EntityNMSHorse invisibleHorse = new EntityNMSHorse(nmsWorld, parentPiece); invisibleHorse.setLocationNMS(x, y, z); - if (!nmsWorld.addEntity(invisibleHorse, SpawnReason.CUSTOM)) { + if (!addEntityToWorld(nmsWorld, invisibleHorse)) { DebugHandler.handleSpawnFail(parentPiece); } return invisibleHorse; @@ -65,7 +77,7 @@ public class NmsManagerImpl implements NMSManager { WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle(); EntityNMSWitherSkull staticWitherSkull = new EntityNMSWitherSkull(nmsWorld, parentPiece); staticWitherSkull.setLocationNMS(x, y, z); - if (!nmsWorld.addEntity(staticWitherSkull, SpawnReason.CUSTOM)) { + if (!addEntityToWorld(nmsWorld, staticWitherSkull)) { DebugHandler.handleSpawnFail(parentPiece); } return staticWitherSkull; @@ -77,7 +89,7 @@ public class NmsManagerImpl implements NMSManager { EntityNMSItem customItem = new EntityNMSItem(nmsWorld, parentPiece); customItem.setLocationNMS(x, y, z); customItem.setItemStackNMS(stack); - if (!nmsWorld.addEntity(customItem, SpawnReason.CUSTOM)) { + if (!addEntityToWorld(nmsWorld, customItem)) { DebugHandler.handleSpawnFail(parentPiece); } return customItem; @@ -88,12 +100,41 @@ public class NmsManagerImpl implements NMSManager { WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle(); EntityNMSSlime touchSlime = new EntityNMSSlime(nmsWorld, parentPiece); touchSlime.setLocationNMS(x, y, z); - if (!nmsWorld.addEntity(touchSlime, SpawnReason.CUSTOM)) { + if (!addEntityToWorld(nmsWorld, touchSlime)) { DebugHandler.handleSpawnFail(parentPiece); } return touchSlime; } + @SuppressWarnings("unchecked") + private boolean addEntityToWorld(WorldServer nmsWorld, Entity nmsEntity) { + Validator.isTrue(Bukkit.isPrimaryThread(), "Async entity add"); + + if (validateEntityMethod == null) { + return nmsWorld.addEntity(nmsEntity, SpawnReason.CUSTOM); + } + + final int chunkX = MathHelper.floor(nmsEntity.locX / 16.0); + final int chunkZ = MathHelper.floor(nmsEntity.locZ / 16.0); + + if (!nmsWorld.chunkProviderServer.isChunkLoaded(chunkX, chunkZ)) { + // This should never happen + nmsEntity.dead = true; + return false; + } + + nmsWorld.getChunkAt(chunkX, chunkZ).a(nmsEntity); + nmsWorld.entityList.add(nmsEntity); + + try { + validateEntityMethod.invoke(nmsWorld, nmsEntity); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + return true; + } + @Override public boolean isNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) { return ((CraftEntity) bukkitEntity).getHandle() instanceof NMSEntityBase; diff --git a/HolographicDisplays/Plugin/com/gmail/filoghost/holographicdisplays/nms/v1_7_R4/NmsManagerImpl.java b/HolographicDisplays/Plugin/com/gmail/filoghost/holographicdisplays/nms/v1_7_R4/NmsManagerImpl.java index c2e71d5e..87dd4f4f 100644 --- a/HolographicDisplays/Plugin/com/gmail/filoghost/holographicdisplays/nms/v1_7_R4/NmsManagerImpl.java +++ b/HolographicDisplays/Plugin/com/gmail/filoghost/holographicdisplays/nms/v1_7_R4/NmsManagerImpl.java @@ -1,10 +1,14 @@ package com.gmail.filoghost.holographicdisplays.nms.v1_7_R4; +import java.lang.reflect.Method; + import net.minecraft.server.v1_7_R4.Entity; import net.minecraft.server.v1_7_R4.EntityTypes; import net.minecraft.server.v1_7_R4.WorldServer; +import net.minecraft.server.v1_8_R1.MathHelper; import org.apache.commons.lang.NotImplementedException; +import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.craftbukkit.v1_7_R4.CraftWorld; import org.bukkit.craftbukkit.v1_7_R4.entity.CraftEntity; @@ -23,16 +27,24 @@ import com.gmail.filoghost.holographicdisplays.object.line.CraftItemLine; import com.gmail.filoghost.holographicdisplays.object.line.CraftTouchSlimeLine; import com.gmail.filoghost.holographicdisplays.util.DebugHandler; import com.gmail.filoghost.holographicdisplays.util.ReflectionUtils; +import com.gmail.filoghost.holographicdisplays.util.Validator; import com.gmail.filoghost.holographicdisplays.util.VersionUtils; public class NmsManagerImpl implements NMSManager { + private Method validateEntityMethod; + @Override - public void registerCustomEntities() throws Exception { + public void setup() throws Exception { registerCustomEntity(EntityNMSHorse.class, "EntityHorse", 100); registerCustomEntity(EntityNMSWitherSkull.class, "WitherSkull", 19); registerCustomEntity(EntityNMSItem.class, "Item", 1); registerCustomEntity(EntityNMSSlime.class, "Slime", 55); + + if (!VersionUtils.isMCPCOrCauldron()) { + validateEntityMethod = World.class.getDeclaredMethod("a", Entity.class); + validateEntityMethod.setAccessible(true); + } } @SuppressWarnings("rawtypes") @@ -54,7 +66,7 @@ public class NmsManagerImpl implements NMSManager { WorldServer nmsWorld = ((CraftWorld) world).getHandle(); EntityNMSHorse invisibleHorse = new EntityNMSHorse(nmsWorld, parentPiece); invisibleHorse.setLocationNMS(x, y, z); - if (!nmsWorld.addEntity(invisibleHorse, SpawnReason.CUSTOM)) { + if (!addEntityToWorld(nmsWorld, invisibleHorse)) { DebugHandler.handleSpawnFail(parentPiece); } return invisibleHorse; @@ -65,7 +77,7 @@ public class NmsManagerImpl implements NMSManager { WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle(); EntityNMSWitherSkull staticWitherSkull = new EntityNMSWitherSkull(nmsWorld, parentPiece); staticWitherSkull.setLocationNMS(x, y, z); - if (!nmsWorld.addEntity(staticWitherSkull, SpawnReason.CUSTOM)) { + if (!addEntityToWorld(nmsWorld, staticWitherSkull)) { DebugHandler.handleSpawnFail(parentPiece); } return staticWitherSkull; @@ -77,7 +89,7 @@ public class NmsManagerImpl implements NMSManager { EntityNMSItem customItem = new EntityNMSItem(nmsWorld, parentPiece); customItem.setLocationNMS(x, y, z); customItem.setItemStackNMS(stack); - if (!nmsWorld.addEntity(customItem, SpawnReason.CUSTOM)) { + if (!addEntityToWorld(nmsWorld, customItem)) { DebugHandler.handleSpawnFail(parentPiece); } return customItem; @@ -88,12 +100,41 @@ public class NmsManagerImpl implements NMSManager { WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle(); EntityNMSSlime touchSlime = new EntityNMSSlime(nmsWorld, parentPiece); touchSlime.setLocationNMS(x, y, z); - if (!nmsWorld.addEntity(touchSlime, SpawnReason.CUSTOM)) { + if (!addEntityToWorld(nmsWorld, touchSlime)) { DebugHandler.handleSpawnFail(parentPiece); } return touchSlime; } + @SuppressWarnings("unchecked") + private boolean addEntityToWorld(WorldServer nmsWorld, Entity nmsEntity) { + Validator.isTrue(Bukkit.isPrimaryThread(), "Async entity add"); + + if (validateEntityMethod == null) { + return nmsWorld.addEntity(nmsEntity, SpawnReason.CUSTOM); + } + + final int chunkX = MathHelper.floor(nmsEntity.locX / 16.0); + final int chunkZ = MathHelper.floor(nmsEntity.locZ / 16.0); + + if (!nmsWorld.chunkProviderServer.isChunkLoaded(chunkX, chunkZ)) { + // This should never happen + nmsEntity.dead = true; + return false; + } + + nmsWorld.getChunkAt(chunkX, chunkZ).a(nmsEntity); + nmsWorld.entityList.add(nmsEntity); + + try { + validateEntityMethod.invoke(nmsWorld, nmsEntity); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + return true; + } + @Override public boolean isNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) { return ((CraftEntity) bukkitEntity).getHandle() instanceof NMSEntityBase; diff --git a/HolographicDisplays/Plugin/com/gmail/filoghost/holographicdisplays/nms/v1_8_R1/NmsManagerImpl.java b/HolographicDisplays/Plugin/com/gmail/filoghost/holographicdisplays/nms/v1_8_R1/NmsManagerImpl.java index 7736244b..f9a35c04 100644 --- a/HolographicDisplays/Plugin/com/gmail/filoghost/holographicdisplays/nms/v1_8_R1/NmsManagerImpl.java +++ b/HolographicDisplays/Plugin/com/gmail/filoghost/holographicdisplays/nms/v1_8_R1/NmsManagerImpl.java @@ -1,11 +1,15 @@ package com.gmail.filoghost.holographicdisplays.nms.v1_8_R1; +import java.lang.reflect.Method; + import net.minecraft.server.v1_8_R1.Entity; import net.minecraft.server.v1_8_R1.EntityTypes; +import net.minecraft.server.v1_8_R1.MathHelper; +import net.minecraft.server.v1_8_R1.World; import net.minecraft.server.v1_8_R1.WorldServer; import org.apache.commons.lang.NotImplementedException; -import org.bukkit.World; +import org.bukkit.Bukkit; import org.bukkit.craftbukkit.v1_8_R1.CraftWorld; import org.bukkit.craftbukkit.v1_8_R1.entity.CraftEntity; import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; @@ -23,15 +27,23 @@ import com.gmail.filoghost.holographicdisplays.object.line.CraftItemLine; import com.gmail.filoghost.holographicdisplays.object.line.CraftTouchSlimeLine; import com.gmail.filoghost.holographicdisplays.util.DebugHandler; import com.gmail.filoghost.holographicdisplays.util.ReflectionUtils; +import com.gmail.filoghost.holographicdisplays.util.Validator; import com.gmail.filoghost.holographicdisplays.util.VersionUtils; public class NmsManagerImpl implements NMSManager { + private Method validateEntityMethod; + @Override - public void registerCustomEntities() throws Exception { + public void setup() throws Exception { registerCustomEntity(EntityNMSArmorStand.class, "ArmorStand", 30); registerCustomEntity(EntityNMSItem.class, "Item", 1); registerCustomEntity(EntityNMSSlime.class, "Slime", 55); + + if (!VersionUtils.isMCPCOrCauldron()) { + validateEntityMethod = World.class.getDeclaredMethod("a", Entity.class); + validateEntityMethod.setAccessible(true); + } } @SuppressWarnings("rawtypes") @@ -64,7 +76,7 @@ public class NmsManagerImpl implements NMSManager { EntityNMSItem customItem = new EntityNMSItem(nmsWorld, parentPiece); customItem.setLocationNMS(x, y, z); customItem.setItemStackNMS(stack); - if (!nmsWorld.addEntity(customItem, SpawnReason.CUSTOM)) { + if (!addEntityToWorld(nmsWorld, customItem)) { DebugHandler.handleSpawnFail(parentPiece); } return customItem; @@ -75,23 +87,52 @@ public class NmsManagerImpl implements NMSManager { WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle(); EntityNMSSlime touchSlime = new EntityNMSSlime(nmsWorld, parentPiece); touchSlime.setLocationNMS(x, y, z); - if (!nmsWorld.addEntity(touchSlime, SpawnReason.CUSTOM)) { + if (!addEntityToWorld(nmsWorld, touchSlime)) { DebugHandler.handleSpawnFail(parentPiece); } return touchSlime; } @Override - public NMSArmorStand spawnNMSArmorStand(World world, double x, double y, double z, CraftHologramLine parentPiece) { + public NMSArmorStand spawnNMSArmorStand(org.bukkit.World world, double x, double y, double z, CraftHologramLine parentPiece) { WorldServer nmsWorld = ((CraftWorld) world).getHandle(); EntityNMSArmorStand invisibleArmorStand = new EntityNMSArmorStand(nmsWorld, parentPiece); invisibleArmorStand.setLocationNMS(x, y, z); - if (!nmsWorld.addEntity(invisibleArmorStand, SpawnReason.CUSTOM)) { + if (!addEntityToWorld(nmsWorld, invisibleArmorStand)) { DebugHandler.handleSpawnFail(parentPiece); } return invisibleArmorStand; } + @SuppressWarnings("unchecked") + private boolean addEntityToWorld(WorldServer nmsWorld, Entity nmsEntity) { + Validator.isTrue(Bukkit.isPrimaryThread(), "Async entity add"); + + if (validateEntityMethod == null) { + return nmsWorld.addEntity(nmsEntity, SpawnReason.CUSTOM); + } + + final int chunkX = MathHelper.floor(nmsEntity.locX / 16.0); + final int chunkZ = MathHelper.floor(nmsEntity.locZ / 16.0); + + if (!nmsWorld.chunkProviderServer.isChunkLoaded(chunkX, chunkZ)) { + // This should never happen + nmsEntity.dead = true; + return false; + } + + nmsWorld.getChunkAt(chunkX, chunkZ).a(nmsEntity); + nmsWorld.entityList.add(nmsEntity); + + try { + validateEntityMethod.invoke(nmsWorld, nmsEntity); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + return true; + } + @Override public boolean isNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) { return ((CraftEntity) bukkitEntity).getHandle() instanceof NMSEntityBase;