Reimplement precise-hologram-movement differently to fix lag issues

The `precise-hologram-movement` config option was creating lag on some servers. The option is now removed from the configuration and its functionality has been reimplemented through ProtocolLib (when installed). It now uses a different method that doesn't rely on inspecting stacktraces.

Secondly, a workaround was added to fix the Minecraft bug causing entities to not move client side when teleported shortly after spawning. The cause is EntityTrackerEntry (a NMS class) not sending the teleport packet.
This commit is contained in:
filoghost 2020-04-18 00:14:55 +02:00
parent 735c92a612
commit e5936b423d
48 changed files with 528 additions and 671 deletions

View File

@ -19,7 +19,6 @@ import java.util.Arrays;
public enum ConfigNode { public enum ConfigNode {
SPACE_BETWEEN_LINES("space-between-lines", 0.02), SPACE_BETWEEN_LINES("space-between-lines", 0.02),
PRECISE_HOLOGRAM_MOVEMENT("precise-hologram-movement", true),
QUICK_EDIT_COMMANDS("quick-edit-commands", true), QUICK_EDIT_COMMANDS("quick-edit-commands", true),
IMAGES_SYMBOL("images.symbol", "[x]"), IMAGES_SYMBOL("images.symbol", "[x]"),
TRANSPARENCY_SPACE("images.transparency.space", " [|] "), TRANSPARENCY_SPACE("images.transparency.space", " [|] "),

View File

@ -38,7 +38,6 @@ import com.gmail.filoghost.holographicdisplays.util.ConsoleLogger;
public class Configuration { public class Configuration {
public static double spaceBetweenLines; public static double spaceBetweenLines;
public static boolean preciseHologramMovement;
public static boolean quickEditCommands; public static boolean quickEditCommands;
public static String imageSymbol; public static String imageSymbol;
public static String transparencySymbol; public static String transparencySymbol;
@ -99,7 +98,8 @@ public class Configuration {
"bungee-refresh-seconds", "bungee-refresh-seconds",
"using-RedisBungee", "using-RedisBungee",
"bungee-online-format", "bungee-online-format",
"bungee-offline-format" "bungee-offline-format",
"precise-hologram-movement"
); );
for (String oldNode : nodesToRemove) { for (String oldNode : nodesToRemove) {
@ -128,7 +128,6 @@ public class Configuration {
} }
spaceBetweenLines = config.getDouble(ConfigNode.SPACE_BETWEEN_LINES.getPath()); spaceBetweenLines = config.getDouble(ConfigNode.SPACE_BETWEEN_LINES.getPath());
preciseHologramMovement = config.getBoolean(ConfigNode.PRECISE_HOLOGRAM_MOVEMENT.getPath());
quickEditCommands = config.getBoolean(ConfigNode.QUICK_EDIT_COMMANDS.getPath()); quickEditCommands = config.getBoolean(ConfigNode.QUICK_EDIT_COMMANDS.getPath());
updateNotification = config.getBoolean(ConfigNode.UPDATE_NOTIFICATION.getPath()); updateNotification = config.getBoolean(ConfigNode.UPDATE_NOTIFICATION.getPath());

View File

@ -14,6 +14,7 @@
*/ */
package com.gmail.filoghost.holographicdisplays.nms.interfaces; package com.gmail.filoghost.holographicdisplays.nms.interfaces;
import org.bukkit.World;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import com.gmail.filoghost.holographicdisplays.api.line.HologramLine; import com.gmail.filoghost.holographicdisplays.api.line.HologramLine;
@ -28,9 +29,9 @@ public interface NMSManager {
// A method to register all the custom entities of the plugin, it may fail. // A method to register all the custom entities of the plugin, it may fail.
public void setup() throws Exception; public void setup() throws Exception;
public NMSArmorStand spawnNMSArmorStand(org.bukkit.World world, double x, double y, double z, HologramLine parentPiece); public NMSArmorStand spawnNMSArmorStand(org.bukkit.World world, double x, double y, double z, HologramLine parentPiece, boolean broadcastLocationPacket);
public NMSItem spawnNMSItem(org.bukkit.World bukkitWorld, double x, double y, double z, ItemLine parentPiece, ItemStack stack, ItemPickupManager itemPickupManager); public NMSItem spawnNMSItem(org.bukkit.World bukkitWorld, double x, double y, double z, ItemLine parentPiece, ItemStack stack, ItemPickupManager itemPickupManager);
public NMSSlime spawnNMSSlime(org.bukkit.World bukkitWorld, double x, double y, double z, HologramLine parentPiece); public NMSSlime spawnNMSSlime(org.bukkit.World bukkitWorld, double x, double y, double z, HologramLine parentPiece);
@ -38,7 +39,7 @@ public interface NMSManager {
public NMSEntityBase getNMSEntityBase(org.bukkit.entity.Entity bukkitEntity); public NMSEntityBase getNMSEntityBase(org.bukkit.entity.Entity bukkitEntity);
public org.bukkit.entity.Entity getEntityFromID(org.bukkit.World bukkitWorld, int entityID); public NMSEntityBase getNMSEntityBaseFromID(World bukkitWorld, int entityID);
public Object replaceCustomNameText(Object customNameObject, String target, String replacement); public Object replaceCustomNameText(Object customNameObject, String target, String replacement);

View File

@ -15,5 +15,8 @@
package com.gmail.filoghost.holographicdisplays.nms.interfaces.entity; package com.gmail.filoghost.holographicdisplays.nms.interfaces.entity;
public interface NMSArmorStand extends NMSNameable { public interface NMSArmorStand extends NMSNameable {
// Sets the location through NMS and optionally broadcast an additional teleport packet containing the location.
public void setLocationNMS(double x, double y, double z, boolean broadcastLocationPacket);
} }

View File

@ -27,9 +27,6 @@ public interface NMSEntityBase {
// Sets if the entity should tick or not. // Sets if the entity should tick or not.
public void setLockTick(boolean lock); public void setLockTick(boolean lock);
// Sets the location through NMS.
public void setLocationNMS(double x, double y, double z);
// Returns if the entity is dead through NMS. // Returns if the entity is dead through NMS.
public boolean isDeadNMS(); public boolean isDeadNMS();

View File

@ -18,6 +18,9 @@ import org.bukkit.inventory.ItemStack;
public interface NMSItem extends NMSEntityBase, NMSCanMount { public interface NMSItem extends NMSEntityBase, NMSCanMount {
// Sets the location through NMS.
public void setLocationNMS(double x, double y, double z);
// Sets the bukkit ItemStack for this item. // Sets the bukkit ItemStack for this item.
public void setItemStackNMS(ItemStack stack); public void setItemStackNMS(ItemStack stack);

View File

@ -16,4 +16,7 @@ package com.gmail.filoghost.holographicdisplays.nms.interfaces.entity;
public interface NMSSlime extends NMSEntityBase, NMSCanMount { public interface NMSSlime extends NMSEntityBase, NMSCanMount {
// Sets the location through NMS.
public void setLocationNMS(double x, double y, double z);
} }

View File

@ -32,12 +32,6 @@
<artifactId>holographicdisplays-utils</artifactId> <artifactId>holographicdisplays-utils</artifactId>
<version>2.4.2-SNAPSHOT</version> <version>2.4.2-SNAPSHOT</version>
</dependency> </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>holographicdisplays-config</artifactId>
<version>2.4.2-SNAPSHOT</version>
</dependency>
<dependency> <dependency>
<groupId>org.spigotmc</groupId> <groupId>org.spigotmc</groupId>

View File

@ -17,11 +17,8 @@ package com.gmail.filoghost.holographicdisplays.nms.v1_10_R1;
import org.bukkit.craftbukkit.v1_10_R1.entity.CraftEntity; import org.bukkit.craftbukkit.v1_10_R1.entity.CraftEntity;
import com.gmail.filoghost.holographicdisplays.api.line.HologramLine; import com.gmail.filoghost.holographicdisplays.api.line.HologramLine;
import com.gmail.filoghost.holographicdisplays.disk.Configuration;
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSArmorStand; import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSArmorStand;
import com.gmail.filoghost.holographicdisplays.util.Utils; import com.gmail.filoghost.holographicdisplays.util.Utils;
import com.gmail.filoghost.holographicdisplays.util.reflection.ReflectionUtils;
import net.minecraft.server.v1_10_R1.AxisAlignedBB; import net.minecraft.server.v1_10_R1.AxisAlignedBB;
import net.minecraft.server.v1_10_R1.DamageSource; import net.minecraft.server.v1_10_R1.DamageSource;
import net.minecraft.server.v1_10_R1.EntityArmorStand; import net.minecraft.server.v1_10_R1.EntityArmorStand;
@ -54,6 +51,8 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
super.collides = false; super.collides = false;
this.parentPiece = parentPiece; this.parentPiece = parentPiece;
forceSetBoundingBox(new NullBoundingBox()); forceSetBoundingBox(new NullBoundingBox());
this.onGround = true; // Workaround to force EntityTrackerEntry to send a teleport packet.
} }
@ -142,16 +141,17 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
} }
@Override @Override
public int getId() { public void inactiveTick() {
if (Configuration.preciseHologramMovement) { // Check inactive ticks.
StackTraceElement element = ReflectionUtils.getStackTraceElement(2);
if (element != null && element.getFileName() != null && element.getFileName().equals("EntityTrackerEntry.java") && 158 < element.getLineNumber() && element.getLineNumber() < 168) { if (!lockTick) {
// Then this method is being called when creating a new movement packet, we return a fake ID! super.inactiveTick();
return -1;
}
} }
return super.getId(); // Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity.
if (this.onGround) {
this.onGround = false;
}
} }
@Override @Override
@ -159,6 +159,11 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
if (!lockTick) { if (!lockTick) {
super.m(); super.m();
} }
// Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity.
if (this.onGround) {
this.onGround = false;
}
} }
@Override @Override
@ -207,21 +212,23 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
} }
@Override @Override
public void setLocationNMS(double x, double y, double z) { public void setLocationNMS(double x, double y, double z, boolean broadcastLocationPacket) {
super.setPosition(x, y, z); super.setPosition(x, y, z);
if (broadcastLocationPacket) {
broadcastLocationPacketNMS();
}
}
private void broadcastLocationPacketNMS() {
PacketPlayOutEntityTeleport teleportPacket = new PacketPlayOutEntityTeleport(this);
if (Configuration.preciseHologramMovement) { for (Object obj : super.world.players) {
// Send a packet near to update the position. if (obj instanceof EntityPlayer) {
PacketPlayOutEntityTeleport teleportPacket = new PacketPlayOutEntityTeleport(this); EntityPlayer nmsPlayer = (EntityPlayer) obj;
for (Object obj : super.world.players) { double distanceSquared = Utils.square(nmsPlayer.locX - super.locX) + Utils.square(nmsPlayer.locZ - super.locZ);
if (obj instanceof EntityPlayer) { if (distanceSquared < 8192 && nmsPlayer.playerConnection != null) {
EntityPlayer nmsPlayer = (EntityPlayer) obj; nmsPlayer.playerConnection.sendPacket(teleportPacket);
double distanceSquared = Utils.square(nmsPlayer.locX - super.locX) + Utils.square(nmsPlayer.locZ - super.locZ);
if (distanceSquared < 8192 && nmsPlayer.playerConnection != null) {
nmsPlayer.playerConnection.sendPacket(teleportPacket);
}
} }
} }
} }
@ -234,7 +241,7 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
@Override @Override
public int getIdNMS() { public int getIdNMS() {
return super.getId(); // Return the real ID without checking the stack trace. return super.getId();
} }
@Override @Override

View File

@ -86,10 +86,10 @@ public class NmsManagerImpl implements NMSManager {
} }
@Override @Override
public NMSArmorStand spawnNMSArmorStand(org.bukkit.World world, double x, double y, double z, HologramLine parentPiece) { public NMSArmorStand spawnNMSArmorStand(org.bukkit.World world, double x, double y, double z, HologramLine parentPiece, boolean broadcastLocationPacket) {
WorldServer nmsWorld = ((CraftWorld) world).getHandle(); WorldServer nmsWorld = ((CraftWorld) world).getHandle();
EntityNMSArmorStand invisibleArmorStand = new EntityNMSArmorStand(nmsWorld, parentPiece); EntityNMSArmorStand invisibleArmorStand = new EntityNMSArmorStand(nmsWorld, parentPiece);
invisibleArmorStand.setLocationNMS(x, y, z); invisibleArmorStand.setLocationNMS(x, y, z, broadcastLocationPacket);
if (!addEntityToWorld(nmsWorld, invisibleArmorStand)) { if (!addEntityToWorld(nmsWorld, invisibleArmorStand)) {
ConsoleLogger.handleSpawnFail(parentPiece); ConsoleLogger.handleSpawnFail(parentPiece);
} }
@ -127,25 +127,25 @@ public class NmsManagerImpl implements NMSManager {
@Override @Override
public NMSEntityBase getNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) { public NMSEntityBase getNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) {
Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle(); Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle();
if (nmsEntity instanceof NMSEntityBase) { if (nmsEntity instanceof NMSEntityBase) {
return ((NMSEntityBase) nmsEntity); return ((NMSEntityBase) nmsEntity);
} else {
return null;
} }
return null;
} }
@Override @Override
public org.bukkit.entity.Entity getEntityFromID(org.bukkit.World bukkitWorld, int entityID) { public NMSEntityBase getNMSEntityBaseFromID(org.bukkit.World bukkitWorld, int entityID) {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle(); WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
Entity nmsEntity = nmsWorld.getEntity(entityID); Entity nmsEntity = nmsWorld.getEntity(entityID);
if (nmsEntity == null) { if (nmsEntity instanceof NMSEntityBase) {
return ((NMSEntityBase) nmsEntity);
} else {
return null; return null;
} }
return nmsEntity.getBukkitEntity();
} }
@Override @Override

View File

@ -32,12 +32,6 @@
<artifactId>holographicdisplays-utils</artifactId> <artifactId>holographicdisplays-utils</artifactId>
<version>2.4.2-SNAPSHOT</version> <version>2.4.2-SNAPSHOT</version>
</dependency> </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>holographicdisplays-config</artifactId>
<version>2.4.2-SNAPSHOT</version>
</dependency>
<dependency> <dependency>
<groupId>org.spigotmc</groupId> <groupId>org.spigotmc</groupId>

View File

@ -17,11 +17,8 @@ package com.gmail.filoghost.holographicdisplays.nms.v1_11_R1;
import org.bukkit.craftbukkit.v1_11_R1.entity.CraftEntity; import org.bukkit.craftbukkit.v1_11_R1.entity.CraftEntity;
import com.gmail.filoghost.holographicdisplays.api.line.HologramLine; import com.gmail.filoghost.holographicdisplays.api.line.HologramLine;
import com.gmail.filoghost.holographicdisplays.disk.Configuration;
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSArmorStand; import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSArmorStand;
import com.gmail.filoghost.holographicdisplays.util.Utils; import com.gmail.filoghost.holographicdisplays.util.Utils;
import com.gmail.filoghost.holographicdisplays.util.reflection.ReflectionUtils;
import net.minecraft.server.v1_11_R1.AxisAlignedBB; import net.minecraft.server.v1_11_R1.AxisAlignedBB;
import net.minecraft.server.v1_11_R1.DamageSource; import net.minecraft.server.v1_11_R1.DamageSource;
import net.minecraft.server.v1_11_R1.EntityArmorStand; import net.minecraft.server.v1_11_R1.EntityArmorStand;
@ -54,6 +51,8 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
super.collides = false; super.collides = false;
this.parentPiece = parentPiece; this.parentPiece = parentPiece;
forceSetBoundingBox(new NullBoundingBox()); forceSetBoundingBox(new NullBoundingBox());
this.onGround = true; // Workaround to force EntityTrackerEntry to send a teleport packet.
} }
@ -117,6 +116,23 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
if (!lockTick) { if (!lockTick) {
super.inactiveTick(); super.inactiveTick();
} }
// Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity.
if (this.onGround) {
this.onGround = false;
}
}
@Override
public void A_() {
if (!lockTick) {
super.A_();
}
// Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity.
if (this.onGround) {
this.onGround = false;
}
} }
@Override @Override
@ -150,26 +166,6 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
super.a(boundingBox); super.a(boundingBox);
} }
@Override
public int getId() {
if (Configuration.preciseHologramMovement) {
StackTraceElement element = ReflectionUtils.getStackTraceElement(2);
if (element != null && element.getFileName() != null && element.getFileName().equals("EntityTrackerEntry.java") && 158 < element.getLineNumber() && element.getLineNumber() < 168) {
// Then this method is being called when creating a new movement packet, we return a fake ID!
return -1;
}
}
return super.getId();
}
@Override
public void A_() {
if (!lockTick) {
super.A_();
}
}
@Override @Override
public void a(SoundEffect soundeffect, float f, float f1) { public void a(SoundEffect soundeffect, float f, float f1) {
// Remove sounds. // Remove sounds.
@ -216,21 +212,23 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
} }
@Override @Override
public void setLocationNMS(double x, double y, double z) { public void setLocationNMS(double x, double y, double z, boolean broadcastLocationPacket) {
super.setPosition(x, y, z); super.setPosition(x, y, z);
if (broadcastLocationPacket) {
broadcastLocationPacketNMS();
}
}
private void broadcastLocationPacketNMS() {
PacketPlayOutEntityTeleport teleportPacket = new PacketPlayOutEntityTeleport(this);
if (Configuration.preciseHologramMovement) { for (Object obj : super.world.players) {
// Send a packet near to update the position. if (obj instanceof EntityPlayer) {
PacketPlayOutEntityTeleport teleportPacket = new PacketPlayOutEntityTeleport(this); EntityPlayer nmsPlayer = (EntityPlayer) obj;
for (Object obj : super.world.players) { double distanceSquared = Utils.square(nmsPlayer.locX - super.locX) + Utils.square(nmsPlayer.locZ - super.locZ);
if (obj instanceof EntityPlayer) { if (distanceSquared < 8192 && nmsPlayer.playerConnection != null) {
EntityPlayer nmsPlayer = (EntityPlayer) obj; nmsPlayer.playerConnection.sendPacket(teleportPacket);
double distanceSquared = Utils.square(nmsPlayer.locX - super.locX) + Utils.square(nmsPlayer.locZ - super.locZ);
if (distanceSquared < 8192 && nmsPlayer.playerConnection != null) {
nmsPlayer.playerConnection.sendPacket(teleportPacket);
}
} }
} }
} }
@ -243,7 +241,7 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
@Override @Override
public int getIdNMS() { public int getIdNMS() {
return super.getId(); // Return the real ID without checking the stack trace. return super.getId();
} }
@Override @Override

View File

@ -95,10 +95,10 @@ public class NmsManagerImpl implements NMSManager {
} }
@Override @Override
public NMSArmorStand spawnNMSArmorStand(org.bukkit.World world, double x, double y, double z, HologramLine parentPiece) { public NMSArmorStand spawnNMSArmorStand(org.bukkit.World world, double x, double y, double z, HologramLine parentPiece, boolean broadcastLocationPacket) {
WorldServer nmsWorld = ((CraftWorld) world).getHandle(); WorldServer nmsWorld = ((CraftWorld) world).getHandle();
EntityNMSArmorStand invisibleArmorStand = new EntityNMSArmorStand(nmsWorld, parentPiece); EntityNMSArmorStand invisibleArmorStand = new EntityNMSArmorStand(nmsWorld, parentPiece);
invisibleArmorStand.setLocationNMS(x, y, z); invisibleArmorStand.setLocationNMS(x, y, z, broadcastLocationPacket);
if (!addEntityToWorld(nmsWorld, invisibleArmorStand)) { if (!addEntityToWorld(nmsWorld, invisibleArmorStand)) {
ConsoleLogger.handleSpawnFail(parentPiece); ConsoleLogger.handleSpawnFail(parentPiece);
} }
@ -136,25 +136,25 @@ public class NmsManagerImpl implements NMSManager {
@Override @Override
public NMSEntityBase getNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) { public NMSEntityBase getNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) {
Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle(); Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle();
if (nmsEntity instanceof NMSEntityBase) { if (nmsEntity instanceof NMSEntityBase) {
return ((NMSEntityBase) nmsEntity); return ((NMSEntityBase) nmsEntity);
} else {
return null;
} }
return null;
} }
@Override @Override
public org.bukkit.entity.Entity getEntityFromID(org.bukkit.World bukkitWorld, int entityID) { public NMSEntityBase getNMSEntityBaseFromID(org.bukkit.World bukkitWorld, int entityID) {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle(); WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
Entity nmsEntity = nmsWorld.getEntity(entityID); Entity nmsEntity = nmsWorld.getEntity(entityID);
if (nmsEntity == null) { if (nmsEntity instanceof NMSEntityBase) {
return ((NMSEntityBase) nmsEntity);
} else {
return null; return null;
} }
return nmsEntity.getBukkitEntity();
} }
@Override @Override

View File

@ -32,12 +32,6 @@
<artifactId>holographicdisplays-utils</artifactId> <artifactId>holographicdisplays-utils</artifactId>
<version>2.4.2-SNAPSHOT</version> <version>2.4.2-SNAPSHOT</version>
</dependency> </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>holographicdisplays-config</artifactId>
<version>2.4.2-SNAPSHOT</version>
</dependency>
<dependency> <dependency>
<groupId>org.spigotmc</groupId> <groupId>org.spigotmc</groupId>

View File

@ -17,11 +17,8 @@ package com.gmail.filoghost.holographicdisplays.nms.v1_12_R1;
import org.bukkit.craftbukkit.v1_12_R1.entity.CraftEntity; import org.bukkit.craftbukkit.v1_12_R1.entity.CraftEntity;
import com.gmail.filoghost.holographicdisplays.api.line.HologramLine; import com.gmail.filoghost.holographicdisplays.api.line.HologramLine;
import com.gmail.filoghost.holographicdisplays.disk.Configuration;
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSArmorStand; import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSArmorStand;
import com.gmail.filoghost.holographicdisplays.util.Utils; import com.gmail.filoghost.holographicdisplays.util.Utils;
import com.gmail.filoghost.holographicdisplays.util.reflection.ReflectionUtils;
import net.minecraft.server.v1_12_R1.AxisAlignedBB; import net.minecraft.server.v1_12_R1.AxisAlignedBB;
import net.minecraft.server.v1_12_R1.DamageSource; import net.minecraft.server.v1_12_R1.DamageSource;
import net.minecraft.server.v1_12_R1.EntityArmorStand; import net.minecraft.server.v1_12_R1.EntityArmorStand;
@ -54,6 +51,8 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
super.collides = false; super.collides = false;
this.parentPiece = parentPiece; this.parentPiece = parentPiece;
forceSetBoundingBox(new NullBoundingBox()); forceSetBoundingBox(new NullBoundingBox());
this.onGround = true; // Workaround to force EntityTrackerEntry to send a teleport packet.
} }
@ -117,6 +116,23 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
if (!lockTick) { if (!lockTick) {
super.inactiveTick(); super.inactiveTick();
} }
// Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity.
if (this.onGround) {
this.onGround = false;
}
}
@Override
public void B_() {
if (!lockTick) {
super.B_();
}
// Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity.
if (this.onGround) {
this.onGround = false;
}
} }
@Override @Override
@ -150,26 +166,6 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
super.a(boundingBox); super.a(boundingBox);
} }
@Override
public int getId() {
if (Configuration.preciseHologramMovement) {
StackTraceElement element = ReflectionUtils.getStackTraceElement(2);
if (element != null && element.getFileName() != null && element.getFileName().equals("EntityTrackerEntry.java") && 158 < element.getLineNumber() && element.getLineNumber() < 168) {
// Then this method is being called when creating a new movement packet, we return a fake ID!
return -1;
}
}
return super.getId();
}
@Override
public void B_() {
if (!lockTick) {
super.B_();
}
}
@Override @Override
public void a(SoundEffect soundeffect, float f, float f1) { public void a(SoundEffect soundeffect, float f, float f1) {
// Remove sounds. // Remove sounds.
@ -216,21 +212,23 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
} }
@Override @Override
public void setLocationNMS(double x, double y, double z) { public void setLocationNMS(double x, double y, double z, boolean broadcastLocationPacket) {
super.setPosition(x, y, z); super.setPosition(x, y, z);
if (broadcastLocationPacket) {
broadcastLocationPacketNMS();
}
}
private void broadcastLocationPacketNMS() {
PacketPlayOutEntityTeleport teleportPacket = new PacketPlayOutEntityTeleport(this);
if (Configuration.preciseHologramMovement) { for (Object obj : super.world.players) {
// Send a packet near to update the position. if (obj instanceof EntityPlayer) {
PacketPlayOutEntityTeleport teleportPacket = new PacketPlayOutEntityTeleport(this); EntityPlayer nmsPlayer = (EntityPlayer) obj;
for (Object obj : super.world.players) { double distanceSquared = Utils.square(nmsPlayer.locX - super.locX) + Utils.square(nmsPlayer.locZ - super.locZ);
if (obj instanceof EntityPlayer) { if (distanceSquared < 8192 && nmsPlayer.playerConnection != null) {
EntityPlayer nmsPlayer = (EntityPlayer) obj; nmsPlayer.playerConnection.sendPacket(teleportPacket);
double distanceSquared = Utils.square(nmsPlayer.locX - super.locX) + Utils.square(nmsPlayer.locZ - super.locZ);
if (distanceSquared < 8192 && nmsPlayer.playerConnection != null) {
nmsPlayer.playerConnection.sendPacket(teleportPacket);
}
} }
} }
} }
@ -243,7 +241,7 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
@Override @Override
public int getIdNMS() { public int getIdNMS() {
return super.getId(); // Return the real ID without checking the stack trace. return super.getId();
} }
@Override @Override

View File

@ -95,10 +95,10 @@ public class NmsManagerImpl implements NMSManager {
} }
@Override @Override
public NMSArmorStand spawnNMSArmorStand(org.bukkit.World world, double x, double y, double z, HologramLine parentPiece) { public NMSArmorStand spawnNMSArmorStand(org.bukkit.World world, double x, double y, double z, HologramLine parentPiece, boolean broadcastLocationPacket) {
WorldServer nmsWorld = ((CraftWorld) world).getHandle(); WorldServer nmsWorld = ((CraftWorld) world).getHandle();
EntityNMSArmorStand invisibleArmorStand = new EntityNMSArmorStand(nmsWorld, parentPiece); EntityNMSArmorStand invisibleArmorStand = new EntityNMSArmorStand(nmsWorld, parentPiece);
invisibleArmorStand.setLocationNMS(x, y, z); invisibleArmorStand.setLocationNMS(x, y, z, broadcastLocationPacket);
if (!addEntityToWorld(nmsWorld, invisibleArmorStand)) { if (!addEntityToWorld(nmsWorld, invisibleArmorStand)) {
ConsoleLogger.handleSpawnFail(parentPiece); ConsoleLogger.handleSpawnFail(parentPiece);
} }
@ -136,25 +136,25 @@ public class NmsManagerImpl implements NMSManager {
@Override @Override
public NMSEntityBase getNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) { public NMSEntityBase getNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) {
Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle(); Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle();
if (nmsEntity instanceof NMSEntityBase) { if (nmsEntity instanceof NMSEntityBase) {
return ((NMSEntityBase) nmsEntity); return ((NMSEntityBase) nmsEntity);
} else {
return null;
} }
return null;
} }
@Override @Override
public org.bukkit.entity.Entity getEntityFromID(org.bukkit.World bukkitWorld, int entityID) { public NMSEntityBase getNMSEntityBaseFromID(org.bukkit.World bukkitWorld, int entityID) {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle(); WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
Entity nmsEntity = nmsWorld.getEntity(entityID); Entity nmsEntity = nmsWorld.getEntity(entityID);
if (nmsEntity == null) { if (nmsEntity instanceof NMSEntityBase) {
return ((NMSEntityBase) nmsEntity);
} else {
return null; return null;
} }
return nmsEntity.getBukkitEntity();
} }
@Override @Override

View File

@ -33,12 +33,6 @@
<version>2.4.2-SNAPSHOT</version> <version>2.4.2-SNAPSHOT</version>
</dependency> </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>holographicdisplays-config</artifactId>
<version>2.4.2-SNAPSHOT</version>
</dependency>
<dependency> <dependency>
<groupId>org.spigotmc</groupId> <groupId>org.spigotmc</groupId>
<artifactId>spigot</artifactId> <artifactId>spigot</artifactId>

View File

@ -18,10 +18,8 @@ import org.bukkit.craftbukkit.v1_13_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_13_R1.util.CraftChatMessage; import org.bukkit.craftbukkit.v1_13_R1.util.CraftChatMessage;
import com.gmail.filoghost.holographicdisplays.api.line.HologramLine; import com.gmail.filoghost.holographicdisplays.api.line.HologramLine;
import com.gmail.filoghost.holographicdisplays.disk.Configuration;
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSArmorStand; import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSArmorStand;
import com.gmail.filoghost.holographicdisplays.util.Utils; import com.gmail.filoghost.holographicdisplays.util.Utils;
import com.gmail.filoghost.holographicdisplays.util.reflection.ReflectionUtils;
import net.minecraft.server.v1_13_R1.AxisAlignedBB; import net.minecraft.server.v1_13_R1.AxisAlignedBB;
import net.minecraft.server.v1_13_R1.DamageSource; import net.minecraft.server.v1_13_R1.DamageSource;
@ -56,6 +54,8 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
super.collides = false; super.collides = false;
this.parentPiece = parentPiece; this.parentPiece = parentPiece;
forceSetBoundingBox(new NullBoundingBox()); forceSetBoundingBox(new NullBoundingBox());
this.onGround = true; // Workaround to force EntityTrackerEntry to send a teleport packet.
} }
@ -119,6 +119,23 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
if (!lockTick) { if (!lockTick) {
super.inactiveTick(); super.inactiveTick();
} }
// Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity.
if (this.onGround) {
this.onGround = false;
}
}
@Override
public void tick() {
if (!lockTick) {
super.tick();
}
// Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity.
if (this.onGround) {
this.onGround = false;
}
} }
@Override @Override
@ -152,26 +169,6 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
super.a(boundingBox); super.a(boundingBox);
} }
@Override
public int getId() {
if (Configuration.preciseHologramMovement) {
StackTraceElement element = ReflectionUtils.getStackTraceElement(2);
if (element != null && element.getFileName() != null && element.getFileName().equals("EntityTrackerEntry.java") && 158 < element.getLineNumber() && element.getLineNumber() < 168) {
// Then this method is being called when creating a new movement packet, we return a fake ID!
return -1;
}
}
return super.getId();
}
@Override
public void tick() {
if (!lockTick) {
super.tick();
}
}
@Override @Override
public void a(SoundEffect soundeffect, float f, float f1) { public void a(SoundEffect soundeffect, float f, float f1) {
// Remove sounds. // Remove sounds.
@ -218,21 +215,23 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
} }
@Override @Override
public void setLocationNMS(double x, double y, double z) { public void setLocationNMS(double x, double y, double z, boolean broadcastLocationPacket) {
super.setPosition(x, y, z); super.setPosition(x, y, z);
if (broadcastLocationPacket) {
broadcastLocationPacketNMS();
}
}
private void broadcastLocationPacketNMS() {
PacketPlayOutEntityTeleport teleportPacket = new PacketPlayOutEntityTeleport(this);
if (Configuration.preciseHologramMovement) { for (Object obj : super.world.players) {
// Send a packet near to update the position. if (obj instanceof EntityPlayer) {
PacketPlayOutEntityTeleport teleportPacket = new PacketPlayOutEntityTeleport(this); EntityPlayer nmsPlayer = (EntityPlayer) obj;
for (Object obj : super.world.players) { double distanceSquared = Utils.square(nmsPlayer.locX - super.locX) + Utils.square(nmsPlayer.locZ - super.locZ);
if (obj instanceof EntityPlayer) { if (distanceSquared < 8192 && nmsPlayer.playerConnection != null) {
EntityPlayer nmsPlayer = (EntityPlayer) obj; nmsPlayer.playerConnection.sendPacket(teleportPacket);
double distanceSquared = Utils.square(nmsPlayer.locX - super.locX) + Utils.square(nmsPlayer.locZ - super.locZ);
if (distanceSquared < 8192 && nmsPlayer.playerConnection != null) {
nmsPlayer.playerConnection.sendPacket(teleportPacket);
}
} }
} }
} }
@ -245,7 +244,7 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
@Override @Override
public int getIdNMS() { public int getIdNMS() {
return super.getId(); // Return the real ID without checking the stack trace. return super.getId();
} }
@Override @Override

View File

@ -101,10 +101,10 @@ public class NmsManagerImpl implements NMSManager {
} }
@Override @Override
public NMSArmorStand spawnNMSArmorStand(org.bukkit.World world, double x, double y, double z, HologramLine parentPiece) { public NMSArmorStand spawnNMSArmorStand(org.bukkit.World world, double x, double y, double z, HologramLine parentPiece, boolean broadcastLocationPacket) {
WorldServer nmsWorld = ((CraftWorld) world).getHandle(); WorldServer nmsWorld = ((CraftWorld) world).getHandle();
EntityNMSArmorStand invisibleArmorStand = new EntityNMSArmorStand(nmsWorld, parentPiece); EntityNMSArmorStand invisibleArmorStand = new EntityNMSArmorStand(nmsWorld, parentPiece);
invisibleArmorStand.setLocationNMS(x, y, z); invisibleArmorStand.setLocationNMS(x, y, z, broadcastLocationPacket);
if (!addEntityToWorld(nmsWorld, invisibleArmorStand)) { if (!addEntityToWorld(nmsWorld, invisibleArmorStand)) {
ConsoleLogger.handleSpawnFail(parentPiece); ConsoleLogger.handleSpawnFail(parentPiece);
} }
@ -152,25 +152,25 @@ public class NmsManagerImpl implements NMSManager {
@Override @Override
public NMSEntityBase getNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) { public NMSEntityBase getNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) {
Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle(); Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle();
if (nmsEntity instanceof NMSEntityBase) { if (nmsEntity instanceof NMSEntityBase) {
return ((NMSEntityBase) nmsEntity); return ((NMSEntityBase) nmsEntity);
} else {
return null;
} }
return null;
} }
@Override @Override
public org.bukkit.entity.Entity getEntityFromID(org.bukkit.World bukkitWorld, int entityID) { public NMSEntityBase getNMSEntityBaseFromID(org.bukkit.World bukkitWorld, int entityID) {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle(); WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
Entity nmsEntity = nmsWorld.getEntity(entityID); Entity nmsEntity = nmsWorld.getEntity(entityID);
if (nmsEntity == null) { if (nmsEntity instanceof NMSEntityBase) {
return ((NMSEntityBase) nmsEntity);
} else {
return null; return null;
} }
return nmsEntity.getBukkitEntity();
} }
@Override @Override

View File

@ -33,12 +33,6 @@
<version>2.4.2-SNAPSHOT</version> <version>2.4.2-SNAPSHOT</version>
</dependency> </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>holographicdisplays-config</artifactId>
<version>2.4.2-SNAPSHOT</version>
</dependency>
<dependency> <dependency>
<groupId>org.spigotmc</groupId> <groupId>org.spigotmc</groupId>
<artifactId>spigot</artifactId> <artifactId>spigot</artifactId>

View File

@ -18,10 +18,8 @@ import org.bukkit.craftbukkit.v1_13_R2.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_13_R2.util.CraftChatMessage; import org.bukkit.craftbukkit.v1_13_R2.util.CraftChatMessage;
import com.gmail.filoghost.holographicdisplays.api.line.HologramLine; import com.gmail.filoghost.holographicdisplays.api.line.HologramLine;
import com.gmail.filoghost.holographicdisplays.disk.Configuration;
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSArmorStand; import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSArmorStand;
import com.gmail.filoghost.holographicdisplays.util.Utils; import com.gmail.filoghost.holographicdisplays.util.Utils;
import com.gmail.filoghost.holographicdisplays.util.reflection.ReflectionUtils;
import net.minecraft.server.v1_13_R2.AxisAlignedBB; import net.minecraft.server.v1_13_R2.AxisAlignedBB;
import net.minecraft.server.v1_13_R2.DamageSource; import net.minecraft.server.v1_13_R2.DamageSource;
@ -56,6 +54,8 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
super.collides = false; super.collides = false;
this.parentPiece = parentPiece; this.parentPiece = parentPiece;
forceSetBoundingBox(new NullBoundingBox()); forceSetBoundingBox(new NullBoundingBox());
this.onGround = true; // Workaround to force EntityTrackerEntry to send a teleport packet.
} }
@ -119,6 +119,23 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
if (!lockTick) { if (!lockTick) {
super.inactiveTick(); super.inactiveTick();
} }
// Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity.
if (this.onGround) {
this.onGround = false;
}
}
@Override
public void tick() {
if (!lockTick) {
super.tick();
}
// Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity.
if (this.onGround) {
this.onGround = false;
}
} }
@Override @Override
@ -152,26 +169,6 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
super.a(boundingBox); super.a(boundingBox);
} }
@Override
public int getId() {
if (Configuration.preciseHologramMovement) {
StackTraceElement element = ReflectionUtils.getStackTraceElement(2);
if (element != null && element.getFileName() != null && element.getFileName().equals("EntityTrackerEntry.java") && 158 < element.getLineNumber() && element.getLineNumber() < 168) {
// Then this method is being called when creating a new movement packet, we return a fake ID!
return -1;
}
}
return super.getId();
}
@Override
public void tick() {
if (!lockTick) {
super.tick();
}
}
@Override @Override
public void a(SoundEffect soundeffect, float f, float f1) { public void a(SoundEffect soundeffect, float f, float f1) {
// Remove sounds. // Remove sounds.
@ -218,21 +215,23 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
} }
@Override @Override
public void setLocationNMS(double x, double y, double z) { public void setLocationNMS(double x, double y, double z, boolean broadcastLocationPacket) {
super.setPosition(x, y, z); super.setPosition(x, y, z);
if (broadcastLocationPacket) {
broadcastLocationPacketNMS();
}
}
private void broadcastLocationPacketNMS() {
PacketPlayOutEntityTeleport teleportPacket = new PacketPlayOutEntityTeleport(this);
if (Configuration.preciseHologramMovement) { for (Object obj : super.world.players) {
// Send a packet near to update the position. if (obj instanceof EntityPlayer) {
PacketPlayOutEntityTeleport teleportPacket = new PacketPlayOutEntityTeleport(this); EntityPlayer nmsPlayer = (EntityPlayer) obj;
for (Object obj : super.world.players) { double distanceSquared = Utils.square(nmsPlayer.locX - super.locX) + Utils.square(nmsPlayer.locZ - super.locZ);
if (obj instanceof EntityPlayer) { if (distanceSquared < 8192 && nmsPlayer.playerConnection != null) {
EntityPlayer nmsPlayer = (EntityPlayer) obj; nmsPlayer.playerConnection.sendPacket(teleportPacket);
double distanceSquared = Utils.square(nmsPlayer.locX - super.locX) + Utils.square(nmsPlayer.locZ - super.locZ);
if (distanceSquared < 8192 && nmsPlayer.playerConnection != null) {
nmsPlayer.playerConnection.sendPacket(teleportPacket);
}
} }
} }
} }
@ -245,7 +244,7 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
@Override @Override
public int getIdNMS() { public int getIdNMS() {
return super.getId(); // Return the real ID without checking the stack trace. return super.getId();
} }
@Override @Override

View File

@ -102,10 +102,10 @@ public class NmsManagerImpl implements NMSManager {
} }
@Override @Override
public NMSArmorStand spawnNMSArmorStand(org.bukkit.World world, double x, double y, double z, HologramLine parentPiece) { public NMSArmorStand spawnNMSArmorStand(org.bukkit.World world, double x, double y, double z, HologramLine parentPiece, boolean broadcastLocationPacket) {
WorldServer nmsWorld = ((CraftWorld) world).getHandle(); WorldServer nmsWorld = ((CraftWorld) world).getHandle();
EntityNMSArmorStand invisibleArmorStand = new EntityNMSArmorStand(nmsWorld, parentPiece); EntityNMSArmorStand invisibleArmorStand = new EntityNMSArmorStand(nmsWorld, parentPiece);
invisibleArmorStand.setLocationNMS(x, y, z); invisibleArmorStand.setLocationNMS(x, y, z, broadcastLocationPacket);
if (!addEntityToWorld(nmsWorld, invisibleArmorStand)) { if (!addEntityToWorld(nmsWorld, invisibleArmorStand)) {
ConsoleLogger.handleSpawnFail(parentPiece); ConsoleLogger.handleSpawnFail(parentPiece);
} }
@ -153,25 +153,25 @@ public class NmsManagerImpl implements NMSManager {
@Override @Override
public NMSEntityBase getNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) { public NMSEntityBase getNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) {
Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle(); Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle();
if (nmsEntity instanceof NMSEntityBase) { if (nmsEntity instanceof NMSEntityBase) {
return ((NMSEntityBase) nmsEntity); return ((NMSEntityBase) nmsEntity);
} else {
return null;
} }
return null;
} }
@Override @Override
public org.bukkit.entity.Entity getEntityFromID(org.bukkit.World bukkitWorld, int entityID) { public NMSEntityBase getNMSEntityBaseFromID(org.bukkit.World bukkitWorld, int entityID) {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle(); WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
Entity nmsEntity = nmsWorld.getEntity(entityID); Entity nmsEntity = nmsWorld.getEntity(entityID);
if (nmsEntity == null) { if (nmsEntity instanceof NMSEntityBase) {
return ((NMSEntityBase) nmsEntity);
} else {
return null; return null;
} }
return nmsEntity.getBukkitEntity();
} }
@Override @Override

View File

@ -32,13 +32,7 @@
<artifactId>holographicdisplays-utils</artifactId> <artifactId>holographicdisplays-utils</artifactId>
<version>2.4.2-SNAPSHOT</version> <version>2.4.2-SNAPSHOT</version>
</dependency> </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>holographicdisplays-config</artifactId>
<version>2.4.2-SNAPSHOT</version>
</dependency>
<dependency> <dependency>
<groupId>org.spigotmc</groupId> <groupId>org.spigotmc</groupId>
<artifactId>spigot</artifactId> <artifactId>spigot</artifactId>

View File

@ -18,10 +18,8 @@ import org.bukkit.craftbukkit.v1_14_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_14_R1.util.CraftChatMessage; import org.bukkit.craftbukkit.v1_14_R1.util.CraftChatMessage;
import com.gmail.filoghost.holographicdisplays.api.line.HologramLine; import com.gmail.filoghost.holographicdisplays.api.line.HologramLine;
import com.gmail.filoghost.holographicdisplays.disk.Configuration;
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSArmorStand; import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSArmorStand;
import com.gmail.filoghost.holographicdisplays.util.Utils; import com.gmail.filoghost.holographicdisplays.util.Utils;
import com.gmail.filoghost.holographicdisplays.util.reflection.ReflectionUtils;
import net.minecraft.server.v1_14_R1.AxisAlignedBB; import net.minecraft.server.v1_14_R1.AxisAlignedBB;
import net.minecraft.server.v1_14_R1.DamageSource; import net.minecraft.server.v1_14_R1.DamageSource;
@ -58,6 +56,8 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
super.collides = false; super.collides = false;
this.parentPiece = parentPiece; this.parentPiece = parentPiece;
forceSetBoundingBox(new NullBoundingBox()); forceSetBoundingBox(new NullBoundingBox());
this.onGround = true; // Workaround to force EntityTrackerEntry to send a teleport packet.
} }
@ -121,6 +121,23 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
if (!lockTick) { if (!lockTick) {
super.inactiveTick(); super.inactiveTick();
} }
// Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity.
if (this.onGround) {
this.onGround = false;
}
}
@Override
public void tick() {
if (!lockTick) {
super.tick();
}
// Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity.
if (this.onGround) {
this.onGround = false;
}
} }
@Override @Override
@ -154,26 +171,6 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
super.a(boundingBox); super.a(boundingBox);
} }
@Override
public int getId() {
if (Configuration.preciseHologramMovement) {
StackTraceElement element = ReflectionUtils.getStackTraceElement(2);
if (element != null && element.getFileName() != null && element.getFileName().equals("EntityTrackerEntry.java") && 128 < element.getLineNumber() && element.getLineNumber() < 151) {
// Then this method is being called when creating a new movement packet, we return a fake ID
return -1;
}
}
return super.getId();
}
@Override
public void tick() {
if (!lockTick) {
super.tick();
}
}
@Override @Override
public void a(SoundEffect soundeffect, float f, float f1) { public void a(SoundEffect soundeffect, float f, float f1) {
// Remove sounds. // Remove sounds.
@ -220,21 +217,23 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
} }
@Override @Override
public void setLocationNMS(double x, double y, double z) { public void setLocationNMS(double x, double y, double z, boolean broadcastLocationPacket) {
super.setPosition(x, y, z); super.setPosition(x, y, z);
if (broadcastLocationPacket) {
broadcastLocationPacketNMS();
}
}
private void broadcastLocationPacketNMS() {
PacketPlayOutEntityTeleport teleportPacket = new PacketPlayOutEntityTeleport(this);
if (Configuration.preciseHologramMovement) { for (Object obj : super.world.getPlayers()) {
// Send a packet near to update the position. if (obj instanceof EntityPlayer) {
PacketPlayOutEntityTeleport teleportPacket = new PacketPlayOutEntityTeleport(this); EntityPlayer nmsPlayer = (EntityPlayer) obj;
for (Object obj : super.world.getPlayers()) { double distanceSquared = Utils.square(nmsPlayer.locX - super.locX) + Utils.square(nmsPlayer.locZ - super.locZ);
if (obj instanceof EntityPlayer) { if (distanceSquared < 8192 && nmsPlayer.playerConnection != null) {
EntityPlayer nmsPlayer = (EntityPlayer) obj; nmsPlayer.playerConnection.sendPacket(teleportPacket);
double distanceSquared = Utils.square(nmsPlayer.locX - super.locX) + Utils.square(nmsPlayer.locZ - super.locZ);
if (distanceSquared < 8192 && nmsPlayer.playerConnection != null) {
nmsPlayer.playerConnection.sendPacket(teleportPacket);
}
} }
} }
} }
@ -247,7 +246,7 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
@Override @Override
public int getIdNMS() { public int getIdNMS() {
return super.getId(); // Return the real ID without checking the stack trace. return super.getId();
} }
@Override @Override

View File

@ -97,10 +97,10 @@ public class NmsManagerImpl implements NMSManager {
} }
@Override @Override
public NMSArmorStand spawnNMSArmorStand(org.bukkit.World world, double x, double y, double z, HologramLine parentPiece) { public NMSArmorStand spawnNMSArmorStand(org.bukkit.World world, double x, double y, double z, HologramLine parentPiece, boolean broadcastLocationPacket) {
WorldServer nmsWorld = ((CraftWorld) world).getHandle(); WorldServer nmsWorld = ((CraftWorld) world).getHandle();
EntityNMSArmorStand invisibleArmorStand = new EntityNMSArmorStand(nmsWorld, parentPiece); EntityNMSArmorStand invisibleArmorStand = new EntityNMSArmorStand(nmsWorld, parentPiece);
invisibleArmorStand.setLocationNMS(x, y, z); invisibleArmorStand.setLocationNMS(x, y, z, broadcastLocationPacket);
if (!addEntityToWorld(nmsWorld, invisibleArmorStand)) { if (!addEntityToWorld(nmsWorld, invisibleArmorStand)) {
ConsoleLogger.handleSpawnFail(parentPiece); ConsoleLogger.handleSpawnFail(parentPiece);
} }
@ -137,22 +137,24 @@ public class NmsManagerImpl implements NMSManager {
@Override @Override
public NMSEntityBase getNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) { public NMSEntityBase getNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) {
Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle(); Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle();
if (nmsEntity instanceof NMSEntityBase) { if (nmsEntity instanceof NMSEntityBase) {
return ((NMSEntityBase) nmsEntity); return ((NMSEntityBase) nmsEntity);
} else {
return null;
} }
return null;
} }
@Override @Override
public org.bukkit.entity.Entity getEntityFromID(org.bukkit.World bukkitWorld, int entityID) { public NMSEntityBase getNMSEntityBaseFromID(org.bukkit.World bukkitWorld, int entityID) {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle(); WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
Entity nmsEntity = nmsWorld.getEntity(entityID); Entity nmsEntity = nmsWorld.getEntity(entityID);
if (nmsEntity == null) { if (nmsEntity instanceof NMSEntityBase) {
return ((NMSEntityBase) nmsEntity);
} else {
return null; return null;
} }
return nmsEntity.getBukkitEntity();
} }
@Override @Override

View File

@ -33,11 +33,6 @@
<version>2.4.2-SNAPSHOT</version> <version>2.4.2-SNAPSHOT</version>
</dependency> </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>holographicdisplays-config</artifactId>
<version>2.4.2-SNAPSHOT</version>
</dependency>
<dependency> <dependency>
<groupId>org.spigotmc</groupId> <groupId>org.spigotmc</groupId>
<artifactId>spigot</artifactId> <artifactId>spigot</artifactId>

View File

@ -15,10 +15,8 @@
package com.gmail.filoghost.holographicdisplays.nms.v1_15_R1; package com.gmail.filoghost.holographicdisplays.nms.v1_15_R1;
import com.gmail.filoghost.holographicdisplays.api.line.HologramLine; import com.gmail.filoghost.holographicdisplays.api.line.HologramLine;
import com.gmail.filoghost.holographicdisplays.disk.Configuration;
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSArmorStand; import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSArmorStand;
import com.gmail.filoghost.holographicdisplays.util.Utils; import com.gmail.filoghost.holographicdisplays.util.Utils;
import com.gmail.filoghost.holographicdisplays.util.reflection.ReflectionUtils;
import net.minecraft.server.v1_15_R1.*; import net.minecraft.server.v1_15_R1.*;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftEntity; import org.bukkit.craftbukkit.v1_15_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_15_R1.util.CraftChatMessage; import org.bukkit.craftbukkit.v1_15_R1.util.CraftChatMessage;
@ -41,6 +39,8 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
super.collides = false; super.collides = false;
this.parentPiece = parentPiece; this.parentPiece = parentPiece;
forceSetBoundingBox(new NullBoundingBox()); forceSetBoundingBox(new NullBoundingBox());
this.onGround = true; // Workaround to force EntityTrackerEntry to send a teleport packet.
} }
@ -104,6 +104,23 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
if (!lockTick) { if (!lockTick) {
super.inactiveTick(); super.inactiveTick();
} }
// Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity.
if (this.onGround) {
this.onGround = false;
}
}
@Override
public void tick() {
if (!lockTick) {
super.tick();
}
// Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity.
if (this.onGround) {
this.onGround = false;
}
} }
@Override @Override
@ -136,27 +153,7 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
public void forceSetBoundingBox(AxisAlignedBB boundingBox) { public void forceSetBoundingBox(AxisAlignedBB boundingBox) {
super.a(boundingBox); super.a(boundingBox);
} }
@Override
public int getId() {
if (Configuration.preciseHologramMovement) {
StackTraceElement element = ReflectionUtils.getStackTraceElement(2);
if (element != null && element.getFileName() != null && element.getFileName().equals("EntityTrackerEntry.java") && 128 < element.getLineNumber() && element.getLineNumber() < 151) {
// Then this method is being called when creating a new movement packet, we return a fake ID
return -1;
}
}
return super.getId();
}
@Override
public void tick() {
if (!lockTick) {
super.tick();
}
}
@Override @Override
public void a(SoundEffect soundeffect, float f, float f1) { public void a(SoundEffect soundeffect, float f, float f1) {
// Remove sounds. // Remove sounds.
@ -203,21 +200,23 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
} }
@Override @Override
public void setLocationNMS(double x, double y, double z) { public void setLocationNMS(double x, double y, double z, boolean broadcastLocationPacket) {
super.setPosition(x, y, z); super.setPosition(x, y, z);
if (broadcastLocationPacket) {
broadcastLocationPacketNMS();
}
}
private void broadcastLocationPacketNMS() {
PacketPlayOutEntityTeleport teleportPacket = new PacketPlayOutEntityTeleport(this);
if (Configuration.preciseHologramMovement) { for (Object obj : super.world.getPlayers()) {
// Send a packet near to update the position. if (obj instanceof EntityPlayer) {
PacketPlayOutEntityTeleport teleportPacket = new PacketPlayOutEntityTeleport(this); EntityPlayer nmsPlayer = (EntityPlayer) obj;
for (Object obj : super.world.getPlayers()) { double distanceSquared = Utils.square(nmsPlayer.locX() - super.locX()) + Utils.square(nmsPlayer.locZ() - super.locZ());
if (obj instanceof EntityPlayer) { if (distanceSquared < 8192 && nmsPlayer.playerConnection != null) {
EntityPlayer nmsPlayer = (EntityPlayer) obj; nmsPlayer.playerConnection.sendPacket(teleportPacket);
double distanceSquared = Utils.square(nmsPlayer.locX() - super.locX()) + Utils.square(nmsPlayer.locZ() - super.locZ());
if (distanceSquared < 8192 && nmsPlayer.playerConnection != null) {
nmsPlayer.playerConnection.sendPacket(teleportPacket);
}
} }
} }
} }
@ -230,7 +229,7 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
@Override @Override
public int getIdNMS() { public int getIdNMS() {
return super.getId(); // Return the real ID without checking the stack trace. return super.getId();
} }
@Override @Override

View File

@ -96,10 +96,10 @@ public class NmsManagerImpl implements NMSManager {
} }
@Override @Override
public NMSArmorStand spawnNMSArmorStand(org.bukkit.World world, double x, double y, double z, HologramLine parentPiece) { public NMSArmorStand spawnNMSArmorStand(org.bukkit.World world, double x, double y, double z, HologramLine parentPiece, boolean broadcastLocationPacket) {
WorldServer nmsWorld = ((CraftWorld) world).getHandle(); WorldServer nmsWorld = ((CraftWorld) world).getHandle();
EntityNMSArmorStand invisibleArmorStand = new EntityNMSArmorStand(nmsWorld, parentPiece); EntityNMSArmorStand invisibleArmorStand = new EntityNMSArmorStand(nmsWorld, parentPiece);
invisibleArmorStand.setLocationNMS(x, y, z); invisibleArmorStand.setLocationNMS(x, y, z, broadcastLocationPacket);
if (!addEntityToWorld(nmsWorld, invisibleArmorStand)) { if (!addEntityToWorld(nmsWorld, invisibleArmorStand)) {
ConsoleLogger.handleSpawnFail(parentPiece); ConsoleLogger.handleSpawnFail(parentPiece);
} }
@ -136,22 +136,24 @@ public class NmsManagerImpl implements NMSManager {
@Override @Override
public NMSEntityBase getNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) { public NMSEntityBase getNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) {
Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle(); Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle();
if (nmsEntity instanceof NMSEntityBase) { if (nmsEntity instanceof NMSEntityBase) {
return ((NMSEntityBase) nmsEntity); return ((NMSEntityBase) nmsEntity);
} else {
return null;
} }
return null;
} }
@Override @Override
public org.bukkit.entity.Entity getEntityFromID(org.bukkit.World bukkitWorld, int entityID) { public NMSEntityBase getNMSEntityBaseFromID(org.bukkit.World bukkitWorld, int entityID) {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle(); WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
Entity nmsEntity = nmsWorld.getEntity(entityID); Entity nmsEntity = nmsWorld.getEntity(entityID);
if (nmsEntity == null) { if (nmsEntity instanceof NMSEntityBase) {
return ((NMSEntityBase) nmsEntity);
} else {
return null; return null;
} }
return nmsEntity.getBukkitEntity();
} }
@Override @Override

View File

@ -32,12 +32,6 @@
<artifactId>holographicdisplays-utils</artifactId> <artifactId>holographicdisplays-utils</artifactId>
<version>2.4.2-SNAPSHOT</version> <version>2.4.2-SNAPSHOT</version>
</dependency> </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>holographicdisplays-config</artifactId>
<version>2.4.2-SNAPSHOT</version>
</dependency>
<dependency> <dependency>
<groupId>org.spigotmc</groupId> <groupId>org.spigotmc</groupId>

View File

@ -19,21 +19,17 @@ import java.util.logging.Level;
import org.bukkit.craftbukkit.v1_8_R2.entity.CraftEntity; import org.bukkit.craftbukkit.v1_8_R2.entity.CraftEntity;
import com.gmail.filoghost.holographicdisplays.api.line.HologramLine; import com.gmail.filoghost.holographicdisplays.api.line.HologramLine;
import com.gmail.filoghost.holographicdisplays.disk.Configuration;
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSArmorStand; import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSArmorStand;
import com.gmail.filoghost.holographicdisplays.util.ConsoleLogger; import com.gmail.filoghost.holographicdisplays.util.ConsoleLogger;
import com.gmail.filoghost.holographicdisplays.util.Utils; import com.gmail.filoghost.holographicdisplays.util.Utils;
import com.gmail.filoghost.holographicdisplays.util.reflection.ReflectField; import com.gmail.filoghost.holographicdisplays.util.reflection.ReflectField;
import com.gmail.filoghost.holographicdisplays.util.reflection.ReflectMethod; import com.gmail.filoghost.holographicdisplays.util.reflection.ReflectMethod;
import com.gmail.filoghost.holographicdisplays.util.reflection.ReflectionUtils;
import net.minecraft.server.v1_8_R2.AxisAlignedBB; import net.minecraft.server.v1_8_R2.AxisAlignedBB;
import net.minecraft.server.v1_8_R2.DamageSource; import net.minecraft.server.v1_8_R2.DamageSource;
import net.minecraft.server.v1_8_R2.EntityArmorStand; import net.minecraft.server.v1_8_R2.EntityArmorStand;
import net.minecraft.server.v1_8_R2.EntityHuman; import net.minecraft.server.v1_8_R2.EntityHuman;
import net.minecraft.server.v1_8_R2.EntityPlayer; import net.minecraft.server.v1_8_R2.EntityPlayer;
import net.minecraft.server.v1_8_R2.ItemStack; import net.minecraft.server.v1_8_R2.ItemStack;
import net.minecraft.server.v1_8_R2.MathHelper;
import net.minecraft.server.v1_8_R2.NBTTagCompound; import net.minecraft.server.v1_8_R2.NBTTagCompound;
import net.minecraft.server.v1_8_R2.PacketPlayOutEntityTeleport; import net.minecraft.server.v1_8_R2.PacketPlayOutEntityTeleport;
import net.minecraft.server.v1_8_R2.Vec3D; import net.minecraft.server.v1_8_R2.Vec3D;
@ -68,6 +64,8 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
// There's still the overridden method. // There's still the overridden method.
} }
forceSetBoundingBox(new NullBoundingBox()); forceSetBoundingBox(new NullBoundingBox());
this.onGround = true; // Workaround to force EntityTrackerEntry to send a teleport packet.
} }
@ -141,16 +139,17 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
} }
@Override @Override
public int getId() { public void inactiveTick() {
if (Configuration.preciseHologramMovement) { // Check inactive ticks.
StackTraceElement element = ReflectionUtils.getStackTraceElement(2);
if (element != null && element.getFileName() != null && element.getFileName().equals("EntityTrackerEntry.java") && element.getLineNumber() > 137 && element.getLineNumber() < 147) { if (!lockTick) {
// Then this method is being called when creating a new packet, we return a fake ID! super.inactiveTick();
return -1;
}
} }
return super.getId(); // Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity.
if (this.onGround) {
this.onGround = false;
}
} }
@Override @Override
@ -158,6 +157,11 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
if (!lockTick) { if (!lockTick) {
super.t_(); super.t_();
} }
// Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity.
if (this.onGround) {
this.onGround = false;
}
} }
@Override @Override
@ -207,29 +211,23 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
} }
@Override @Override
public void setLocationNMS(double x, double y, double z) { public void setLocationNMS(double x, double y, double z, boolean broadcastLocationPacket) {
super.setPosition(x, y, z); super.setPosition(x, y, z);
if (broadcastLocationPacket) {
if (Configuration.preciseHologramMovement) { broadcastLocationPacketNMS();
// Send a packet near to update the position. }
PacketPlayOutEntityTeleport teleportPacket = new PacketPlayOutEntityTeleport( }
getIdNMS(),
MathHelper.floor(this.locX * 32.0D),
MathHelper.floor(this.locY * 32.0D),
MathHelper.floor(this.locZ * 32.0D),
(byte) (int) (this.yaw * 256.0F / 360.0F),
(byte) (int) (this.pitch * 256.0F / 360.0F),
this.onGround
);
for (Object obj : this.world.players) { private void broadcastLocationPacketNMS() {
if (obj instanceof EntityPlayer) { PacketPlayOutEntityTeleport teleportPacket = new PacketPlayOutEntityTeleport(this);
EntityPlayer nmsPlayer = (EntityPlayer) obj;
double distanceSquared = Utils.square(nmsPlayer.locX - this.locX) + Utils.square(nmsPlayer.locZ - this.locZ); for (Object obj : this.world.players) {
if (distanceSquared < 8192 && nmsPlayer.playerConnection != null) { if (obj instanceof EntityPlayer) {
nmsPlayer.playerConnection.sendPacket(teleportPacket); EntityPlayer nmsPlayer = (EntityPlayer) obj;
}
double distanceSquared = Utils.square(nmsPlayer.locX - this.locX) + Utils.square(nmsPlayer.locZ - this.locZ);
if (distanceSquared < 8192 && nmsPlayer.playerConnection != null) {
nmsPlayer.playerConnection.sendPacket(teleportPacket);
} }
} }
} }
@ -242,7 +240,7 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
@Override @Override
public int getIdNMS() { public int getIdNMS() {
return super.getId(); // Return the real ID without checking the stack trace. return super.getId();
} }
@Override @Override

View File

@ -87,10 +87,10 @@ public class NmsManagerImpl implements NMSManager {
} }
@Override @Override
public NMSArmorStand spawnNMSArmorStand(org.bukkit.World world, double x, double y, double z, HologramLine parentPiece) { public NMSArmorStand spawnNMSArmorStand(org.bukkit.World world, double x, double y, double z, HologramLine parentPiece, boolean broadcastLocationPacket) {
WorldServer nmsWorld = ((CraftWorld) world).getHandle(); WorldServer nmsWorld = ((CraftWorld) world).getHandle();
EntityNMSArmorStand invisibleArmorStand = new EntityNMSArmorStand(nmsWorld, parentPiece); EntityNMSArmorStand invisibleArmorStand = new EntityNMSArmorStand(nmsWorld, parentPiece);
invisibleArmorStand.setLocationNMS(x, y, z); invisibleArmorStand.setLocationNMS(x, y, z, broadcastLocationPacket);
if (!addEntityToWorld(nmsWorld, invisibleArmorStand)) { if (!addEntityToWorld(nmsWorld, invisibleArmorStand)) {
ConsoleLogger.handleSpawnFail(parentPiece); ConsoleLogger.handleSpawnFail(parentPiece);
} }
@ -132,25 +132,25 @@ public class NmsManagerImpl implements NMSManager {
@Override @Override
public NMSEntityBase getNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) { public NMSEntityBase getNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) {
Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle(); Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle();
if (nmsEntity instanceof NMSEntityBase) { if (nmsEntity instanceof NMSEntityBase) {
return ((NMSEntityBase) nmsEntity); return ((NMSEntityBase) nmsEntity);
} else {
return null;
} }
return null;
} }
@Override @Override
public org.bukkit.entity.Entity getEntityFromID(org.bukkit.World bukkitWorld, int entityID) { public NMSEntityBase getNMSEntityBaseFromID(org.bukkit.World bukkitWorld, int entityID) {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle(); WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
Entity nmsEntity = nmsWorld.a(entityID); Entity nmsEntity = nmsWorld.a(entityID);
if (nmsEntity == null) { if (nmsEntity instanceof NMSEntityBase) {
return ((NMSEntityBase) nmsEntity);
} else {
return null; return null;
} }
return nmsEntity.getBukkitEntity();
} }
@Override @Override

View File

@ -33,12 +33,6 @@
<version>2.4.2-SNAPSHOT</version> <version>2.4.2-SNAPSHOT</version>
</dependency> </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>holographicdisplays-config</artifactId>
<version>2.4.2-SNAPSHOT</version>
</dependency>
<dependency> <dependency>
<groupId>org.spigotmc</groupId> <groupId>org.spigotmc</groupId>
<artifactId>spigot</artifactId> <artifactId>spigot</artifactId>

View File

@ -19,21 +19,17 @@ import java.util.logging.Level;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity; import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity;
import com.gmail.filoghost.holographicdisplays.api.line.HologramLine; import com.gmail.filoghost.holographicdisplays.api.line.HologramLine;
import com.gmail.filoghost.holographicdisplays.disk.Configuration;
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSArmorStand; import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSArmorStand;
import com.gmail.filoghost.holographicdisplays.util.ConsoleLogger; import com.gmail.filoghost.holographicdisplays.util.ConsoleLogger;
import com.gmail.filoghost.holographicdisplays.util.Utils; import com.gmail.filoghost.holographicdisplays.util.Utils;
import com.gmail.filoghost.holographicdisplays.util.reflection.ReflectField; import com.gmail.filoghost.holographicdisplays.util.reflection.ReflectField;
import com.gmail.filoghost.holographicdisplays.util.reflection.ReflectMethod; import com.gmail.filoghost.holographicdisplays.util.reflection.ReflectMethod;
import com.gmail.filoghost.holographicdisplays.util.reflection.ReflectionUtils;
import net.minecraft.server.v1_8_R3.AxisAlignedBB; import net.minecraft.server.v1_8_R3.AxisAlignedBB;
import net.minecraft.server.v1_8_R3.DamageSource; import net.minecraft.server.v1_8_R3.DamageSource;
import net.minecraft.server.v1_8_R3.EntityArmorStand; import net.minecraft.server.v1_8_R3.EntityArmorStand;
import net.minecraft.server.v1_8_R3.EntityHuman; import net.minecraft.server.v1_8_R3.EntityHuman;
import net.minecraft.server.v1_8_R3.EntityPlayer; import net.minecraft.server.v1_8_R3.EntityPlayer;
import net.minecraft.server.v1_8_R3.ItemStack; import net.minecraft.server.v1_8_R3.ItemStack;
import net.minecraft.server.v1_8_R3.MathHelper;
import net.minecraft.server.v1_8_R3.NBTTagCompound; import net.minecraft.server.v1_8_R3.NBTTagCompound;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityTeleport; import net.minecraft.server.v1_8_R3.PacketPlayOutEntityTeleport;
import net.minecraft.server.v1_8_R3.Vec3D; import net.minecraft.server.v1_8_R3.Vec3D;
@ -68,6 +64,8 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
// There's still the overridden method. // There's still the overridden method.
} }
forceSetBoundingBox(new NullBoundingBox()); forceSetBoundingBox(new NullBoundingBox());
this.onGround = true; // Workaround to force EntityTrackerEntry to send a teleport packet.
} }
@ -141,16 +139,17 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
} }
@Override @Override
public int getId() { public void inactiveTick() {
if (Configuration.preciseHologramMovement) { // Check inactive ticks.
StackTraceElement element = ReflectionUtils.getStackTraceElement(2);
if (element != null && element.getFileName() != null && element.getFileName().equals("EntityTrackerEntry.java") && element.getLineNumber() > 137 && element.getLineNumber() < 147) { if (!lockTick) {
// Then this method is being called when creating a new packet, we return a fake ID! super.inactiveTick();
return -1;
}
} }
return super.getId(); // Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity.
if (this.onGround) {
this.onGround = false;
}
} }
@Override @Override
@ -158,6 +157,11 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
if (!lockTick) { if (!lockTick) {
super.t_(); super.t_();
} }
// Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity.
if (this.onGround) {
this.onGround = false;
}
} }
@Override @Override
@ -207,29 +211,23 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
} }
@Override @Override
public void setLocationNMS(double x, double y, double z) { public void setLocationNMS(double x, double y, double z, boolean broadcastLocationPacket) {
super.setPosition(x, y, z); super.setPosition(x, y, z);
if (broadcastLocationPacket) {
if (Configuration.preciseHologramMovement) { broadcastLocationPacketNMS();
// Send a packet near to update the position. }
PacketPlayOutEntityTeleport teleportPacket = new PacketPlayOutEntityTeleport( }
getIdNMS(),
MathHelper.floor(this.locX * 32.0D),
MathHelper.floor(this.locY * 32.0D),
MathHelper.floor(this.locZ * 32.0D),
(byte) (int) (this.yaw * 256.0F / 360.0F),
(byte) (int) (this.pitch * 256.0F / 360.0F),
this.onGround
);
for (Object obj : this.world.players) { private void broadcastLocationPacketNMS() {
if (obj instanceof EntityPlayer) { PacketPlayOutEntityTeleport teleportPacket = new PacketPlayOutEntityTeleport(this);
EntityPlayer nmsPlayer = (EntityPlayer) obj;
for (Object obj : this.world.players) {
double distanceSquared = Utils.square(nmsPlayer.locX - this.locX) + Utils.square(nmsPlayer.locZ - this.locZ); if (obj instanceof EntityPlayer) {
if (distanceSquared < 8192 && nmsPlayer.playerConnection != null) { EntityPlayer nmsPlayer = (EntityPlayer) obj;
nmsPlayer.playerConnection.sendPacket(teleportPacket);
} double distanceSquared = Utils.square(nmsPlayer.locX - this.locX) + Utils.square(nmsPlayer.locZ - this.locZ);
if (distanceSquared < 8192 && nmsPlayer.playerConnection != null) {
nmsPlayer.playerConnection.sendPacket(teleportPacket);
} }
} }
} }
@ -242,7 +240,7 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
@Override @Override
public int getIdNMS() { public int getIdNMS() {
return super.getId(); // Return the real ID without checking the stack trace. return super.getId();
} }
@Override @Override

View File

@ -87,10 +87,10 @@ public class NmsManagerImpl implements NMSManager {
} }
@Override @Override
public NMSArmorStand spawnNMSArmorStand(org.bukkit.World world, double x, double y, double z, HologramLine parentPiece) { public NMSArmorStand spawnNMSArmorStand(org.bukkit.World world, double x, double y, double z, HologramLine parentPiece, boolean broadcastLocationPacket) {
WorldServer nmsWorld = ((CraftWorld) world).getHandle(); WorldServer nmsWorld = ((CraftWorld) world).getHandle();
EntityNMSArmorStand invisibleArmorStand = new EntityNMSArmorStand(nmsWorld, parentPiece); EntityNMSArmorStand invisibleArmorStand = new EntityNMSArmorStand(nmsWorld, parentPiece);
invisibleArmorStand.setLocationNMS(x, y, z); invisibleArmorStand.setLocationNMS(x, y, z, broadcastLocationPacket);
if (!addEntityToWorld(nmsWorld, invisibleArmorStand)) { if (!addEntityToWorld(nmsWorld, invisibleArmorStand)) {
ConsoleLogger.handleSpawnFail(parentPiece); ConsoleLogger.handleSpawnFail(parentPiece);
} }
@ -132,25 +132,25 @@ public class NmsManagerImpl implements NMSManager {
@Override @Override
public NMSEntityBase getNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) { public NMSEntityBase getNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) {
Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle(); Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle();
if (nmsEntity instanceof NMSEntityBase) { if (nmsEntity instanceof NMSEntityBase) {
return ((NMSEntityBase) nmsEntity); return ((NMSEntityBase) nmsEntity);
} else {
return null;
} }
return null;
} }
@Override @Override
public org.bukkit.entity.Entity getEntityFromID(org.bukkit.World bukkitWorld, int entityID) { public NMSEntityBase getNMSEntityBaseFromID(org.bukkit.World bukkitWorld, int entityID) {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle(); WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
Entity nmsEntity = nmsWorld.a(entityID); Entity nmsEntity = nmsWorld.a(entityID);
if (nmsEntity == null) { if (nmsEntity instanceof NMSEntityBase) {
return ((NMSEntityBase) nmsEntity);
} else {
return null; return null;
} }
return nmsEntity.getBukkitEntity();
} }
@Override @Override

View File

@ -33,12 +33,6 @@
<version>2.4.2-SNAPSHOT</version> <version>2.4.2-SNAPSHOT</version>
</dependency> </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>holographicdisplays-config</artifactId>
<version>2.4.2-SNAPSHOT</version>
</dependency>
<dependency> <dependency>
<groupId>org.spigotmc</groupId> <groupId>org.spigotmc</groupId>
<artifactId>spigot</artifactId> <artifactId>spigot</artifactId>

View File

@ -17,12 +17,9 @@ package com.gmail.filoghost.holographicdisplays.nms.v1_9_R1;
import org.bukkit.craftbukkit.v1_9_R1.entity.CraftEntity; import org.bukkit.craftbukkit.v1_9_R1.entity.CraftEntity;
import com.gmail.filoghost.holographicdisplays.api.line.HologramLine; import com.gmail.filoghost.holographicdisplays.api.line.HologramLine;
import com.gmail.filoghost.holographicdisplays.disk.Configuration;
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSArmorStand; import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSArmorStand;
import com.gmail.filoghost.holographicdisplays.util.Utils; import com.gmail.filoghost.holographicdisplays.util.Utils;
import com.gmail.filoghost.holographicdisplays.util.reflection.ReflectField; import com.gmail.filoghost.holographicdisplays.util.reflection.ReflectField;
import com.gmail.filoghost.holographicdisplays.util.reflection.ReflectionUtils;
import net.minecraft.server.v1_9_R1.AxisAlignedBB; import net.minecraft.server.v1_9_R1.AxisAlignedBB;
import net.minecraft.server.v1_9_R1.DamageSource; import net.minecraft.server.v1_9_R1.DamageSource;
import net.minecraft.server.v1_9_R1.EntityArmorStand; import net.minecraft.server.v1_9_R1.EntityArmorStand;
@ -62,6 +59,8 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
// There's still the overridden method. // There's still the overridden method.
} }
forceSetBoundingBox(new NullBoundingBox()); forceSetBoundingBox(new NullBoundingBox());
this.onGround = true; // Workaround to force EntityTrackerEntry to send a teleport packet.
} }
@ -150,16 +149,17 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
} }
@Override @Override
public int getId() { public void inactiveTick() {
if (Configuration.preciseHologramMovement) { // Check inactive ticks.
StackTraceElement element = ReflectionUtils.getStackTraceElement(2);
if (element != null && element.getFileName() != null && element.getFileName().equals("EntityTrackerEntry.java") && element.getLineNumber() > 142 && element.getLineNumber() < 152) { if (!lockTick) {
// Then this method is being called when creating a new packet, we return a fake ID! super.inactiveTick();
return -1;
}
} }
return super.getId(); // Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity.
if (this.onGround) {
this.onGround = false;
}
} }
@Override @Override
@ -167,6 +167,11 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
if (!lockTick) { if (!lockTick) {
super.m(); super.m();
} }
// Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity.
if (this.onGround) {
this.onGround = false;
}
} }
@Override @Override
@ -215,21 +220,23 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
} }
@Override @Override
public void setLocationNMS(double x, double y, double z) { public void setLocationNMS(double x, double y, double z, boolean broadcastLocationPacket) {
super.setPosition(x, y, z); super.setPosition(x, y, z);
if (broadcastLocationPacket) {
broadcastLocationPacketNMS();
}
}
private void broadcastLocationPacketNMS() {
PacketPlayOutEntityTeleport teleportPacket = new PacketPlayOutEntityTeleport(this);
if (Configuration.preciseHologramMovement) { for (Object obj : super.world.players) {
// Send a packet near to update the position. if (obj instanceof EntityPlayer) {
PacketPlayOutEntityTeleport teleportPacket = new PacketPlayOutEntityTeleport(this); EntityPlayer nmsPlayer = (EntityPlayer) obj;
for (Object obj : super.world.players) { double distanceSquared = Utils.square(nmsPlayer.locX - super.locX) + Utils.square(nmsPlayer.locZ - super.locZ);
if (obj instanceof EntityPlayer) { if (distanceSquared < 8192 && nmsPlayer.playerConnection != null) {
EntityPlayer nmsPlayer = (EntityPlayer) obj; nmsPlayer.playerConnection.sendPacket(teleportPacket);
double distanceSquared = Utils.square(nmsPlayer.locX - super.locX) + Utils.square(nmsPlayer.locZ - super.locZ);
if (distanceSquared < 8192 && nmsPlayer.playerConnection != null) {
nmsPlayer.playerConnection.sendPacket(teleportPacket);
}
} }
} }
} }
@ -242,7 +249,7 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
@Override @Override
public int getIdNMS() { public int getIdNMS() {
return super.getId(); // Return the real ID without checking the stack trace. return super.getId();
} }
@Override @Override

View File

@ -86,10 +86,10 @@ public class NmsManagerImpl implements NMSManager {
} }
@Override @Override
public NMSArmorStand spawnNMSArmorStand(org.bukkit.World world, double x, double y, double z, HologramLine parentPiece) { public NMSArmorStand spawnNMSArmorStand(org.bukkit.World world, double x, double y, double z, HologramLine parentPiece, boolean broadcastLocationPacket) {
WorldServer nmsWorld = ((CraftWorld) world).getHandle(); WorldServer nmsWorld = ((CraftWorld) world).getHandle();
EntityNMSArmorStand invisibleArmorStand = new EntityNMSArmorStand(nmsWorld, parentPiece); EntityNMSArmorStand invisibleArmorStand = new EntityNMSArmorStand(nmsWorld, parentPiece);
invisibleArmorStand.setLocationNMS(x, y, z); invisibleArmorStand.setLocationNMS(x, y, z, broadcastLocationPacket);
if (!addEntityToWorld(nmsWorld, invisibleArmorStand)) { if (!addEntityToWorld(nmsWorld, invisibleArmorStand)) {
ConsoleLogger.handleSpawnFail(parentPiece); ConsoleLogger.handleSpawnFail(parentPiece);
} }
@ -127,25 +127,25 @@ public class NmsManagerImpl implements NMSManager {
@Override @Override
public NMSEntityBase getNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) { public NMSEntityBase getNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) {
Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle(); Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle();
if (nmsEntity instanceof NMSEntityBase) { if (nmsEntity instanceof NMSEntityBase) {
return ((NMSEntityBase) nmsEntity); return ((NMSEntityBase) nmsEntity);
} else {
return null;
} }
return null;
} }
@Override @Override
public org.bukkit.entity.Entity getEntityFromID(org.bukkit.World bukkitWorld, int entityID) { public NMSEntityBase getNMSEntityBaseFromID(org.bukkit.World bukkitWorld, int entityID) {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle(); WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
Entity nmsEntity = nmsWorld.getEntity(entityID); Entity nmsEntity = nmsWorld.getEntity(entityID);
if (nmsEntity == null) { if (nmsEntity instanceof NMSEntityBase) {
return ((NMSEntityBase) nmsEntity);
} else {
return null; return null;
} }
return nmsEntity.getBukkitEntity();
} }
@Override @Override

View File

@ -33,12 +33,6 @@
<version>2.4.2-SNAPSHOT</version> <version>2.4.2-SNAPSHOT</version>
</dependency> </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>holographicdisplays-config</artifactId>
<version>2.4.2-SNAPSHOT</version>
</dependency>
<dependency> <dependency>
<groupId>org.spigotmc</groupId> <groupId>org.spigotmc</groupId>
<artifactId>spigot</artifactId> <artifactId>spigot</artifactId>

View File

@ -17,11 +17,8 @@ package com.gmail.filoghost.holographicdisplays.nms.v1_9_R2;
import org.bukkit.craftbukkit.v1_9_R2.entity.CraftEntity; import org.bukkit.craftbukkit.v1_9_R2.entity.CraftEntity;
import com.gmail.filoghost.holographicdisplays.api.line.HologramLine; import com.gmail.filoghost.holographicdisplays.api.line.HologramLine;
import com.gmail.filoghost.holographicdisplays.disk.Configuration;
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSArmorStand; import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSArmorStand;
import com.gmail.filoghost.holographicdisplays.util.Utils; import com.gmail.filoghost.holographicdisplays.util.Utils;
import com.gmail.filoghost.holographicdisplays.util.reflection.ReflectionUtils;
import net.minecraft.server.v1_9_R2.AxisAlignedBB; import net.minecraft.server.v1_9_R2.AxisAlignedBB;
import net.minecraft.server.v1_9_R2.DamageSource; import net.minecraft.server.v1_9_R2.DamageSource;
import net.minecraft.server.v1_9_R2.EntityArmorStand; import net.minecraft.server.v1_9_R2.EntityArmorStand;
@ -53,6 +50,8 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
super.setMarker(true); super.setMarker(true);
this.parentPiece = parentPiece; this.parentPiece = parentPiece;
forceSetBoundingBox(new NullBoundingBox()); forceSetBoundingBox(new NullBoundingBox());
this.onGround = true; // Workaround to force EntityTrackerEntry to send a teleport packet.
} }
@ -142,16 +141,17 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
} }
@Override @Override
public int getId() { public void inactiveTick() {
if (Configuration.preciseHologramMovement) { // Check inactive ticks.
StackTraceElement element = ReflectionUtils.getStackTraceElement(2);
if (element != null && element.getFileName() != null && element.getFileName().equals("EntityTrackerEntry.java") && element.getLineNumber() > 142 && element.getLineNumber() < 152) { if (!lockTick) {
// Then this method is being called when creating a new packet, we return a fake ID! super.inactiveTick();
return -1;
}
} }
return super.getId(); // Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity.
if (this.onGround) {
this.onGround = false;
}
} }
@Override @Override
@ -159,6 +159,11 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
if (!lockTick) { if (!lockTick) {
super.m(); super.m();
} }
// Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity.
if (this.onGround) {
this.onGround = false;
}
} }
@Override @Override
@ -207,21 +212,23 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
} }
@Override @Override
public void setLocationNMS(double x, double y, double z) { public void setLocationNMS(double x, double y, double z, boolean broadcastLocationPacket) {
super.setPosition(x, y, z); super.setPosition(x, y, z);
if (broadcastLocationPacket) {
broadcastLocationPacketNMS();
}
}
private void broadcastLocationPacketNMS() {
PacketPlayOutEntityTeleport teleportPacket = new PacketPlayOutEntityTeleport(this);
if (Configuration.preciseHologramMovement) { for (Object obj : super.world.players) {
// Send a packet near to update the position. if (obj instanceof EntityPlayer) {
PacketPlayOutEntityTeleport teleportPacket = new PacketPlayOutEntityTeleport(this); EntityPlayer nmsPlayer = (EntityPlayer) obj;
for (Object obj : super.world.players) { double distanceSquared = Utils.square(nmsPlayer.locX - super.locX) + Utils.square(nmsPlayer.locZ - super.locZ);
if (obj instanceof EntityPlayer) { if (distanceSquared < 8192 && nmsPlayer.playerConnection != null) {
EntityPlayer nmsPlayer = (EntityPlayer) obj; nmsPlayer.playerConnection.sendPacket(teleportPacket);
double distanceSquared = Utils.square(nmsPlayer.locX - super.locX) + Utils.square(nmsPlayer.locZ - super.locZ);
if (distanceSquared < 8192 && nmsPlayer.playerConnection != null) {
nmsPlayer.playerConnection.sendPacket(teleportPacket);
}
} }
} }
} }
@ -234,7 +241,7 @@ public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorSta
@Override @Override
public int getIdNMS() { public int getIdNMS() {
return super.getId(); // Return the real ID without checking the stack trace. return super.getId();
} }
@Override @Override

View File

@ -86,10 +86,10 @@ public class NmsManagerImpl implements NMSManager {
} }
@Override @Override
public NMSArmorStand spawnNMSArmorStand(org.bukkit.World world, double x, double y, double z, HologramLine parentPiece) { public NMSArmorStand spawnNMSArmorStand(org.bukkit.World world, double x, double y, double z, HologramLine parentPiece, boolean broadcastLocationPacket) {
WorldServer nmsWorld = ((CraftWorld) world).getHandle(); WorldServer nmsWorld = ((CraftWorld) world).getHandle();
EntityNMSArmorStand invisibleArmorStand = new EntityNMSArmorStand(nmsWorld, parentPiece); EntityNMSArmorStand invisibleArmorStand = new EntityNMSArmorStand(nmsWorld, parentPiece);
invisibleArmorStand.setLocationNMS(x, y, z); invisibleArmorStand.setLocationNMS(x, y, z, broadcastLocationPacket);
if (!addEntityToWorld(nmsWorld, invisibleArmorStand)) { if (!addEntityToWorld(nmsWorld, invisibleArmorStand)) {
ConsoleLogger.handleSpawnFail(parentPiece); ConsoleLogger.handleSpawnFail(parentPiece);
} }
@ -127,25 +127,25 @@ public class NmsManagerImpl implements NMSManager {
@Override @Override
public NMSEntityBase getNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) { public NMSEntityBase getNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) {
Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle(); Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle();
if (nmsEntity instanceof NMSEntityBase) { if (nmsEntity instanceof NMSEntityBase) {
return ((NMSEntityBase) nmsEntity); return ((NMSEntityBase) nmsEntity);
} else {
return null;
} }
return null;
} }
@Override @Override
public org.bukkit.entity.Entity getEntityFromID(org.bukkit.World bukkitWorld, int entityID) { public NMSEntityBase getNMSEntityBaseFromID(org.bukkit.World bukkitWorld, int entityID) {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle(); WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
Entity nmsEntity = nmsWorld.getEntity(entityID); Entity nmsEntity = nmsWorld.getEntity(entityID);
if (nmsEntity == null) { if (nmsEntity instanceof NMSEntityBase) {
return ((NMSEntityBase) nmsEntity);
} else {
return null; return null;
} }
return nmsEntity.getBukkitEntity();
} }
@Override @Override

View File

@ -17,8 +17,8 @@ package com.gmail.filoghost.holographicdisplays.bridge.protocollib.current;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType; import org.bukkit.World;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
@ -57,7 +57,6 @@ public class ProtocolLibHookImpl implements ProtocolLibHook {
private NMSManager nmsManager; private NMSManager nmsManager;
private PacketHelper packetHelper; private PacketHelper packetHelper;
private MetadataHelper metadataHelper; private MetadataHelper metadataHelper;
private boolean useGetEntityWorkaround;
@Override @Override
@ -72,7 +71,9 @@ public class ProtocolLibHookImpl implements ProtocolLibHook {
.types( .types(
PacketType.Play.Server.SPAWN_ENTITY_LIVING, PacketType.Play.Server.SPAWN_ENTITY_LIVING,
PacketType.Play.Server.SPAWN_ENTITY, PacketType.Play.Server.SPAWN_ENTITY,
PacketType.Play.Server.ENTITY_METADATA) PacketType.Play.Server.ENTITY_METADATA,
PacketType.Play.Server.REL_ENTITY_MOVE,
PacketType.Play.Server.REL_ENTITY_MOVE_LOOK)
.serverSide() .serverSide()
.listenerPriority(ListenerPriority.NORMAL); .listenerPriority(ListenerPriority.NORMAL);
@ -80,7 +81,6 @@ public class ProtocolLibHookImpl implements ProtocolLibHook {
@Override @Override
public void onPacketSending(PacketEvent event) { public void onPacketSending(PacketEvent event) {
PacketContainer packet = event.getPacket(); PacketContainer packet = event.getPacket();
Player player = event.getPlayer(); Player player = event.getPlayer();
@ -90,11 +90,9 @@ public class ProtocolLibHookImpl implements ProtocolLibHook {
// Spawn entity packet // Spawn entity packet
if (packet.getType() == PacketType.Play.Server.SPAWN_ENTITY_LIVING) { if (packet.getType() == PacketType.Play.Server.SPAWN_ENTITY_LIVING) {
WrapperPlayServerSpawnEntityLiving spawnEntityPacket = new WrapperPlayServerSpawnEntityLiving(packet); WrapperPlayServerSpawnEntityLiving spawnEntityPacket = new WrapperPlayServerSpawnEntityLiving(packet);
Entity entity = getEntity(event, spawnEntityPacket); CraftHologramLine hologramLine = getHologramLine(event, spawnEntityPacket);
CraftHologramLine hologramLine = getHologramLine(entity);
if (hologramLine == null) { if (hologramLine == null) {
return; return;
} }
@ -124,11 +122,9 @@ public class ProtocolLibHookImpl implements ProtocolLibHook {
event.setPacket(spawnEntityPacket.getHandle()); event.setPacket(spawnEntityPacket.getHandle());
} else if (packet.getType() == PacketType.Play.Server.SPAWN_ENTITY) { } else if (packet.getType() == PacketType.Play.Server.SPAWN_ENTITY) {
WrapperPlayServerSpawnEntity spawnEntityPacket = new WrapperPlayServerSpawnEntity(packet); WrapperPlayServerSpawnEntity spawnEntityPacket = new WrapperPlayServerSpawnEntity(packet);
Entity entity = getEntity(event, spawnEntityPacket); CraftHologramLine hologramLine = getHologramLine(event, spawnEntityPacket);
CraftHologramLine hologramLine = getHologramLine(entity);
if (hologramLine == null) { if (hologramLine == null) {
return; return;
} }
@ -139,11 +135,9 @@ public class ProtocolLibHookImpl implements ProtocolLibHook {
} }
} else if (packet.getType() == PacketType.Play.Server.ENTITY_METADATA) { } else if (packet.getType() == PacketType.Play.Server.ENTITY_METADATA) {
WrapperPlayServerEntityMetadata entityMetadataPacket = new WrapperPlayServerEntityMetadata(packet); WrapperPlayServerEntityMetadata entityMetadataPacket = new WrapperPlayServerEntityMetadata(packet);
Entity entity = getEntity(event, entityMetadataPacket); CraftHologramLine hologramLine = getHologramLine(event, entityMetadataPacket);
CraftHologramLine hologramLine = getHologramLine(entity);
if (hologramLine == null) { if (hologramLine == null) {
return; return;
} }
@ -168,6 +162,14 @@ public class ProtocolLibHookImpl implements ProtocolLibHook {
if (modified) { if (modified) {
event.setPacket(entityMetadataPacket.getHandle()); event.setPacket(entityMetadataPacket.getHandle());
} }
} else if (packet.getType() == PacketType.Play.Server.REL_ENTITY_MOVE || packet.getType() == PacketType.Play.Server.REL_ENTITY_MOVE_LOOK) {
int entityID = packet.getIntegers().read(0);
NMSEntityBase nmsEntityBase = getNMSEntityBase(event.getPlayer().getWorld(), entityID);
if (nmsEntityBase instanceof NMSArmorStand) {
event.setCancelled(true); // Don't send relative movement packets for armor stands, only keep precise teleport packets.
}
} }
} }
}); });
@ -176,24 +178,6 @@ public class ProtocolLibHookImpl implements ProtocolLibHook {
} }
private Entity getEntity(PacketEvent packetEvent, EntityRelatedPacketWrapper packetWrapper) {
if (packetWrapper.getEntityID() < 0) {
return null;
}
if (!useGetEntityWorkaround) {
try {
return packetWrapper.getEntity(packetEvent);
} catch (RuntimeException e) {
useGetEntityWorkaround = true;
}
}
// Use workaround, get entity from its ID through NMS
return HolographicDisplays.getNMSManager().getEntityFromID(packetEvent.getPlayer().getWorld(), packetWrapper.getEntityID());
}
private boolean replaceRelativePlaceholders(WrappedWatchableObject customNameWatchableObject, Player player, Collection<RelativePlaceholder> relativePlaceholders) { private boolean replaceRelativePlaceholders(WrappedWatchableObject customNameWatchableObject, Player player, Collection<RelativePlaceholder> relativePlaceholders) {
if (customNameWatchableObject == null) { if (customNameWatchableObject == null) {
return false; return false;
@ -303,19 +287,25 @@ public class ProtocolLibHookImpl implements ProtocolLibHook {
} }
private CraftHologramLine getHologramLine(Entity bukkitEntity) { private CraftHologramLine getHologramLine(PacketEvent packetEvent, EntityRelatedPacketWrapper packetWrapper) {
if (bukkitEntity != null && isHologramType(bukkitEntity.getType())) { return getHologramLine(packetEvent.getPlayer().getWorld(), packetWrapper.getEntityID());
NMSEntityBase entity = nmsManager.getNMSEntityBase(bukkitEntity); }
if (entity != null) {
return (CraftHologramLine) entity.getHologramLine(); private CraftHologramLine getHologramLine(World world, int entityID) {
} if (entityID < 0) {
return null;
}
NMSEntityBase nmsEntity = getNMSEntityBase(world, entityID);
if (nmsEntity == null) {
return null; // Entity not existing or not related to holograms.
} }
return null; return (CraftHologramLine) nmsEntity.getHologramLine();
} }
private NMSEntityBase getNMSEntityBase(World world, int entityID) {
private boolean isHologramType(EntityType type) { return HolographicDisplays.getNMSManager().getNMSEntityBaseFromID(world, entityID);
return type == EntityType.ARMOR_STAND || type == EntityType.DROPPED_ITEM || type == EntityType.SLIME;
} }
} }

View File

@ -14,14 +14,8 @@
*/ */
package com.gmail.filoghost.holographicdisplays.bridge.protocollib.current.packet; package com.gmail.filoghost.holographicdisplays.bridge.protocollib.current.packet;
import org.bukkit.entity.Entity;
import com.comphenix.protocol.events.PacketEvent;
public interface EntityRelatedPacketWrapper { public interface EntityRelatedPacketWrapper {
public int getEntityID(); public int getEntityID();
public Entity getEntity(PacketEvent event);
} }

View File

@ -23,6 +23,7 @@ import com.gmail.filoghost.holographicdisplays.HolographicDisplays;
import com.gmail.filoghost.holographicdisplays.api.handler.PickupHandler; import com.gmail.filoghost.holographicdisplays.api.handler.PickupHandler;
import com.gmail.filoghost.holographicdisplays.api.handler.TouchHandler; import com.gmail.filoghost.holographicdisplays.api.handler.TouchHandler;
import com.gmail.filoghost.holographicdisplays.api.line.ItemLine; import com.gmail.filoghost.holographicdisplays.api.line.ItemLine;
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSArmorStand;
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSEntityBase; import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSEntityBase;
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSItem; import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSItem;
import com.gmail.filoghost.holographicdisplays.object.CraftHologram; import com.gmail.filoghost.holographicdisplays.object.CraftHologram;
@ -35,7 +36,7 @@ public class CraftItemLine extends CraftTouchableLine implements ItemLine {
private PickupHandler pickupHandler; private PickupHandler pickupHandler;
private NMSItem nmsItem; private NMSItem nmsItem;
private NMSEntityBase nmsVehicle; private NMSArmorStand nmsVehicle;
public CraftItemLine(CraftHologram parent, ItemStack itemStack) { public CraftItemLine(CraftHologram parent, ItemStack itemStack) {
super(0.7, parent); super(0.7, parent);
@ -86,7 +87,7 @@ public class CraftItemLine extends CraftTouchableLine implements ItemLine {
double offset = getItemOffset(); double offset = getItemOffset();
nmsItem = HolographicDisplays.getNMSManager().spawnNMSItem(world, x, y + offset, z, this, itemStack, HolographicDisplays.getMainListener()); nmsItem = HolographicDisplays.getNMSManager().spawnNMSItem(world, x, y + offset, z, this, itemStack, HolographicDisplays.getMainListener());
nmsVehicle = HolographicDisplays.getNMSManager().spawnNMSArmorStand(world, x, y + offset, z, this); nmsVehicle = HolographicDisplays.getNMSManager().spawnNMSArmorStand(world, x, y + offset, z, this, HolographicDisplays.hasProtocolLibHook());
nmsItem.setPassengerOfNMS(nmsVehicle); nmsItem.setPassengerOfNMS(nmsVehicle);
@ -118,7 +119,7 @@ public class CraftItemLine extends CraftTouchableLine implements ItemLine {
double offset = getItemOffset(); double offset = getItemOffset();
if (nmsVehicle != null) { if (nmsVehicle != null) {
nmsVehicle.setLocationNMS(x, y + offset, z); nmsVehicle.setLocationNMS(x, y + offset, z, HolographicDisplays.hasProtocolLibHook());
} }
if (nmsItem != null) { if (nmsItem != null) {

View File

@ -25,6 +25,7 @@ import org.bukkit.World;
import com.gmail.filoghost.holographicdisplays.HolographicDisplays; import com.gmail.filoghost.holographicdisplays.HolographicDisplays;
import com.gmail.filoghost.holographicdisplays.api.handler.TouchHandler; import com.gmail.filoghost.holographicdisplays.api.handler.TouchHandler;
import com.gmail.filoghost.holographicdisplays.api.line.TextLine; import com.gmail.filoghost.holographicdisplays.api.line.TextLine;
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSArmorStand;
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSNameable; import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSNameable;
import com.gmail.filoghost.holographicdisplays.object.CraftHologram; import com.gmail.filoghost.holographicdisplays.object.CraftHologram;
import com.gmail.filoghost.holographicdisplays.placeholder.PlaceholdersManager; import com.gmail.filoghost.holographicdisplays.placeholder.PlaceholdersManager;
@ -35,7 +36,7 @@ public class CraftTextLine extends CraftTouchableLine implements TextLine {
private String text; private String text;
private List<RelativePlaceholder> relativePlaceholders; private List<RelativePlaceholder> relativePlaceholders;
private NMSNameable nmsNameable; private NMSArmorStand nmsNameable;
public CraftTextLine(CraftHologram parent, String text) { public CraftTextLine(CraftHologram parent, String text) {
@ -98,7 +99,7 @@ public class CraftTextLine extends CraftTouchableLine implements TextLine {
public void spawn(World world, double x, double y, double z) { public void spawn(World world, double x, double y, double z) {
super.spawn(world, x, y, z); super.spawn(world, x, y, z);
nmsNameable = HolographicDisplays.getNMSManager().spawnNMSArmorStand(world, x, y + getTextOffset(), z, this); nmsNameable = HolographicDisplays.getNMSManager().spawnNMSArmorStand(world, x, y + getTextOffset(), z, this, HolographicDisplays.hasProtocolLibHook());
if (text != null && !text.isEmpty()) { if (text != null && !text.isEmpty()) {
nmsNameable.setCustomNameNMS(text); nmsNameable.setCustomNameNMS(text);
@ -130,7 +131,7 @@ public class CraftTextLine extends CraftTouchableLine implements TextLine {
super.teleport(x, y, z); super.teleport(x, y, z);
if (nmsNameable != null) { if (nmsNameable != null) {
nmsNameable.setLocationNMS(x, y + getTextOffset(), z); nmsNameable.setLocationNMS(x, y + getTextOffset(), z, HolographicDisplays.hasProtocolLibHook());
} }
} }

View File

@ -17,6 +17,7 @@ package com.gmail.filoghost.holographicdisplays.object.line;
import org.bukkit.World; import org.bukkit.World;
import com.gmail.filoghost.holographicdisplays.HolographicDisplays; import com.gmail.filoghost.holographicdisplays.HolographicDisplays;
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSArmorStand;
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSEntityBase; import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSEntityBase;
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSSlime; import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSSlime;
import com.gmail.filoghost.holographicdisplays.object.CraftHologram; import com.gmail.filoghost.holographicdisplays.object.CraftHologram;
@ -31,7 +32,7 @@ public class CraftTouchSlimeLine extends CraftHologramLine {
private CraftTouchableLine touchablePiece; private CraftTouchableLine touchablePiece;
private NMSSlime nmsSlime; private NMSSlime nmsSlime;
private NMSEntityBase nmsVehicle; private NMSArmorStand nmsVehicle;
protected CraftTouchSlimeLine(CraftHologram parent, CraftTouchableLine touchablePiece) { protected CraftTouchSlimeLine(CraftHologram parent, CraftTouchableLine touchablePiece) {
@ -51,7 +52,7 @@ public class CraftTouchSlimeLine extends CraftHologramLine {
double offset = getSlimeOffset(); double offset = getSlimeOffset();
nmsSlime = HolographicDisplays.getNMSManager().spawnNMSSlime(world, x, y + offset, z, this); nmsSlime = HolographicDisplays.getNMSManager().spawnNMSSlime(world, x, y + offset, z, this);
nmsVehicle = HolographicDisplays.getNMSManager().spawnNMSArmorStand(world, x, y + offset, z, this); nmsVehicle = HolographicDisplays.getNMSManager().spawnNMSArmorStand(world, x, y + offset, z, this, HolographicDisplays.hasProtocolLibHook());
nmsSlime.setPassengerOfNMS(nmsVehicle); nmsSlime.setPassengerOfNMS(nmsVehicle);
@ -82,7 +83,7 @@ public class CraftTouchSlimeLine extends CraftHologramLine {
double offset = getSlimeOffset(); double offset = getSlimeOffset();
if (nmsVehicle != null) { if (nmsVehicle != null) {
nmsVehicle.setLocationNMS(x, y + offset, z); nmsVehicle.setLocationNMS(x, y + offset, z, HolographicDisplays.hasProtocolLibHook());
} }
if (nmsSlime != null) { if (nmsSlime != null) {

View File

@ -4,7 +4,6 @@
#. Plugin created by filoghost. #. Plugin created by filoghost.
#. #.
space-between-lines: 0.02 space-between-lines: 0.02
precise-hologram-movement: true
quick-edit-commands: true quick-edit-commands: true
images: images:
symbol: '[x]' symbol: '[x]'

View File

@ -32,13 +32,6 @@
<version>${spigot-api.version}</version> <version>${spigot-api.version}</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>holographicdisplays-javacompat</artifactId>
<version>2.4.2-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -1,75 +0,0 @@
/*
* This program 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.
*
* This program 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.gmail.filoghost.holographicdisplays.util.reflection;
import java.lang.StackWalker.StackFrame;
import java.util.logging.Level;
import java.util.stream.Stream;
import com.gmail.filoghost.holographicdisplays.util.ConsoleLogger;
import com.gmail.filoghost.holographicdisplays.util.Utils;
public class ReflectionUtils {
private static final boolean HAS_JAVA9_STACKWALKER = Utils.classExists("java.lang.StackWalker");
private static final ReflectMethod<Integer> GET_STACKTRACE_DEPTH_METHOD = new ReflectMethod<>(Throwable.class, "getStackTraceDepth");
private static final ReflectMethod<StackTraceElement> GET_STACKTRACE_ELEMENT_METHOD = new ReflectMethod<>(Throwable.class, "getStackTraceElement", int.class);
private static boolean stackTraceError;
/**
* If you only need one stack trace element this is faster than Throwable.getStackTrace()[element],
* it doesn't generate the full stack trace (except as fallback).
*/
public static StackTraceElement getStackTraceElement(final int index) {
// Use the faster methods only if there hasn't been any error while executing them previously
if (!stackTraceError) {
try {
if (HAS_JAVA9_STACKWALKER) {
// Use the Java 9 StackWalker API
StackFrame result = StackWalker.getInstance().walk((Stream<StackFrame> stream) -> {
return stream.skip(index).limit(1).findFirst().orElse(null);
});
return result != null ? result.toStackTraceElement() : null;
} else {
// Use reflection to avoid generating the full stack trace
Throwable dummyThrowable = new Throwable();
int depth = GET_STACKTRACE_DEPTH_METHOD.invoke(dummyThrowable);
if (index < depth) {
return GET_STACKTRACE_ELEMENT_METHOD.invoke(dummyThrowable, index);
} else {
return null;
}
}
} catch (Throwable t) {
ConsoleLogger.logDebug(Level.WARNING, "Unable to get a stack trace element. This error will only show once and a fallback method will be used.", t);
stackTraceError = true;
}
}
// Fallback slower method, generates the full stack trace (it should never be called if everything works as expected)
StackTraceElement[] fullStackTrace = new Throwable().getStackTrace();
if (index < fullStackTrace.length) {
return fullStackTrace[index];
} else {
return null;
}
}
}