Update for 1.8, experimental.

This commit is contained in:
filoghost 2014-11-28 13:48:32 +01:00
parent f0d6c306c3
commit 85c34eef54
27 changed files with 1167 additions and 79 deletions

View File

@ -41,6 +41,8 @@ public class HolographicDisplays extends JavaPlugin {
private HologramsCommandHandler mainCommandHandler;
private static PlaceholderManager placeholderManager;
public static boolean is1_8;
public void onEnable() {
if (instance != null) {
@ -102,6 +104,8 @@ public class HolographicDisplays extends JavaPlugin {
version = "v1_7_R3";
} else if ("1.7.10".equals(version)) {
version = "v1_7_R4";
} else if ("1.8".equals(version)) {
version = "v1_8_R1";
} else {
// Cannot definitely get the version. This will cause HD to disable itself.
version = null;
@ -119,12 +123,15 @@ public class HolographicDisplays extends JavaPlugin {
nmsManager = new com.gmail.filoghost.holograms.nms.v1_7_R3.NmsManagerImpl();
} else if ("v1_7_R4".equals(version)) {
nmsManager = new com.gmail.filoghost.holograms.nms.v1_7_R4.NmsManagerImpl();
} else if ("v1_8_R1".equals(version)) {
is1_8 = true;
nmsManager = new com.gmail.filoghost.holograms.nms.v1_8_R1.NmsManagerImpl();
} else {
printWarnAndDisable(
"******************************************************",
" This version of HolographicDisplays can",
" only work on these server versions:",
" 1.6.4, from 1.7.2 to 1.7.10.",
" 1.6.4, from 1.7 to 1.8.1.",
" The plugin will be disabled.",
"******************************************************"
);

View File

@ -65,6 +65,7 @@ public class BungeeChannel implements PluginMessageListener {
}
}
@SuppressWarnings("deprecation")
public void askPlayerCount(String server) {
ByteArrayOutputStream b = new ByteArrayOutputStream();
DataOutputStream out = new DataOutputStream(b);

View File

@ -277,7 +277,8 @@ public class MetricsLite {
/**
* Generic method that posts a plugin to the metrics website
*/
private void postPlugin(boolean isPing) throws IOException {
@SuppressWarnings("deprecation")
private void postPlugin(boolean isPing) throws IOException {
// Server software specific section
PluginDescriptionFile description = plugin.getDescription();
String pluginName = description.getName();

View File

@ -1,9 +1,5 @@
package com.gmail.filoghost.holograms.nms.interfaces;
public interface HologramHorse extends HologramComponent {
public void forceSetCustomName(String name);
public String getCustomNameNMS();
public interface HologramHorse extends NameableEntityNMS {
}

View File

@ -8,6 +8,8 @@ import com.gmail.filoghost.holograms.object.HologramBase;
public interface NmsManager {
public void registerCustomEntities() throws Exception;
public HologramArmorStand spawnHologramArmorStand(org.bukkit.World world, double x, double y, double z, HologramBase parent) throws SpawnFailedException;
public HologramHorse spawnHologramHorse(org.bukkit.World world, double x, double y, double z, HologramBase parent) throws SpawnFailedException;

View File

@ -1,5 +1,11 @@
package com.gmail.filoghost.holograms.nms.v1_6_R3;
import net.minecraft.server.v1_6_R3.Entity;
import net.minecraft.server.v1_6_R3.EntityTypes;
import net.minecraft.server.v1_6_R3.WorldServer;
import org.apache.commons.lang.NotImplementedException;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_6_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_6_R3.entity.CraftEntity;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
@ -9,18 +15,15 @@ import com.gmail.filoghost.holograms.exception.SpawnFailedException;
import com.gmail.filoghost.holograms.nms.interfaces.BasicEntityNMS;
import com.gmail.filoghost.holograms.nms.interfaces.CustomItem;
import com.gmail.filoghost.holograms.nms.interfaces.FancyMessage;
import com.gmail.filoghost.holograms.nms.interfaces.HologramArmorStand;
import com.gmail.filoghost.holograms.nms.interfaces.HologramComponent;
import com.gmail.filoghost.holograms.nms.interfaces.HologramHorse;
import com.gmail.filoghost.holograms.nms.interfaces.HologramWitherSkull;
import com.gmail.filoghost.holograms.nms.interfaces.HologramComponent;
import com.gmail.filoghost.holograms.nms.interfaces.NmsManager;
import com.gmail.filoghost.holograms.object.HologramBase;
import com.gmail.filoghost.holograms.utils.ReflectionUtils;
import com.gmail.filoghost.holograms.utils.VersionUtils;
import net.minecraft.server.v1_6_R3.Entity;
import net.minecraft.server.v1_6_R3.EntityTypes;
import net.minecraft.server.v1_6_R3.WorldServer;
public class NmsManagerImpl implements NmsManager {
@Override
@ -125,4 +128,9 @@ public class NmsManagerImpl implements NmsManager {
public boolean hasChatHoverFeature() {
return false;
}
@Override
public HologramArmorStand spawnHologramArmorStand(World world, double x, double y, double z, HologramBase parent) throws SpawnFailedException {
throw new NotImplementedException("Method can only be used on 1.8 or greater");
}
}

View File

@ -1,5 +1,11 @@
package com.gmail.filoghost.holograms.nms.v1_7_R1;
import net.minecraft.server.v1_7_R1.Entity;
import net.minecraft.server.v1_7_R1.EntityTypes;
import net.minecraft.server.v1_7_R1.WorldServer;
import org.apache.commons.lang.NotImplementedException;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_7_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_7_R1.entity.CraftEntity;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
@ -9,18 +15,15 @@ import com.gmail.filoghost.holograms.exception.SpawnFailedException;
import com.gmail.filoghost.holograms.nms.interfaces.BasicEntityNMS;
import com.gmail.filoghost.holograms.nms.interfaces.CustomItem;
import com.gmail.filoghost.holograms.nms.interfaces.FancyMessage;
import com.gmail.filoghost.holograms.nms.interfaces.HologramArmorStand;
import com.gmail.filoghost.holograms.nms.interfaces.HologramComponent;
import com.gmail.filoghost.holograms.nms.interfaces.HologramHorse;
import com.gmail.filoghost.holograms.nms.interfaces.HologramWitherSkull;
import com.gmail.filoghost.holograms.nms.interfaces.HologramComponent;
import com.gmail.filoghost.holograms.nms.interfaces.NmsManager;
import com.gmail.filoghost.holograms.object.HologramBase;
import com.gmail.filoghost.holograms.utils.ReflectionUtils;
import com.gmail.filoghost.holograms.utils.VersionUtils;
import net.minecraft.server.v1_7_R1.EntityTypes;
import net.minecraft.server.v1_7_R1.WorldServer;
import net.minecraft.server.v1_7_R1.Entity;
public class NmsManagerImpl implements NmsManager {
@Override
@ -124,4 +127,9 @@ public class NmsManagerImpl implements NmsManager {
public boolean hasChatHoverFeature() {
return true;
}
@Override
public HologramArmorStand spawnHologramArmorStand(World world, double x, double y, double z, HologramBase parent) throws SpawnFailedException {
throw new NotImplementedException("Method can only be used on 1.8 or greater");
}
}

View File

@ -4,6 +4,8 @@ import net.minecraft.server.v1_7_R2.Entity;
import net.minecraft.server.v1_7_R2.EntityTypes;
import net.minecraft.server.v1_7_R2.WorldServer;
import org.apache.commons.lang.NotImplementedException;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_7_R2.CraftWorld;
import org.bukkit.craftbukkit.v1_7_R2.entity.CraftEntity;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
@ -13,6 +15,7 @@ import com.gmail.filoghost.holograms.exception.SpawnFailedException;
import com.gmail.filoghost.holograms.nms.interfaces.BasicEntityNMS;
import com.gmail.filoghost.holograms.nms.interfaces.CustomItem;
import com.gmail.filoghost.holograms.nms.interfaces.FancyMessage;
import com.gmail.filoghost.holograms.nms.interfaces.HologramArmorStand;
import com.gmail.filoghost.holograms.nms.interfaces.HologramComponent;
import com.gmail.filoghost.holograms.nms.interfaces.HologramHorse;
import com.gmail.filoghost.holograms.nms.interfaces.HologramWitherSkull;
@ -128,4 +131,9 @@ public class NmsManagerImpl implements NmsManager {
public boolean hasChatHoverFeature() {
return true;
}
@Override
public HologramArmorStand spawnHologramArmorStand(World world, double x, double y, double z, HologramBase parent) throws SpawnFailedException {
throw new NotImplementedException("Method can only be used on 1.8 or greater");
}
}

View File

@ -4,6 +4,8 @@ import net.minecraft.server.v1_7_R3.Entity;
import net.minecraft.server.v1_7_R3.EntityTypes;
import net.minecraft.server.v1_7_R3.WorldServer;
import org.apache.commons.lang.NotImplementedException;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_7_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_7_R3.entity.CraftEntity;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
@ -13,6 +15,7 @@ import com.gmail.filoghost.holograms.exception.SpawnFailedException;
import com.gmail.filoghost.holograms.nms.interfaces.BasicEntityNMS;
import com.gmail.filoghost.holograms.nms.interfaces.CustomItem;
import com.gmail.filoghost.holograms.nms.interfaces.FancyMessage;
import com.gmail.filoghost.holograms.nms.interfaces.HologramArmorStand;
import com.gmail.filoghost.holograms.nms.interfaces.HologramComponent;
import com.gmail.filoghost.holograms.nms.interfaces.HologramHorse;
import com.gmail.filoghost.holograms.nms.interfaces.HologramWitherSkull;
@ -127,5 +130,10 @@ public class NmsManagerImpl implements NmsManager {
@Override
public boolean hasChatHoverFeature() {
return true;
}
}
@Override
public HologramArmorStand spawnHologramArmorStand(World world, double x, double y, double z, HologramBase parent) throws SpawnFailedException {
throw new NotImplementedException("Method can only be used on 1.8 or greater");
}
}

View File

@ -4,6 +4,8 @@ import net.minecraft.server.v1_7_R4.Entity;
import net.minecraft.server.v1_7_R4.EntityTypes;
import net.minecraft.server.v1_7_R4.WorldServer;
import org.apache.commons.lang.NotImplementedException;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_7_R4.CraftWorld;
import org.bukkit.craftbukkit.v1_7_R4.entity.CraftEntity;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
@ -13,6 +15,7 @@ import com.gmail.filoghost.holograms.exception.SpawnFailedException;
import com.gmail.filoghost.holograms.nms.interfaces.BasicEntityNMS;
import com.gmail.filoghost.holograms.nms.interfaces.CustomItem;
import com.gmail.filoghost.holograms.nms.interfaces.FancyMessage;
import com.gmail.filoghost.holograms.nms.interfaces.HologramArmorStand;
import com.gmail.filoghost.holograms.nms.interfaces.HologramComponent;
import com.gmail.filoghost.holograms.nms.interfaces.HologramHorse;
import com.gmail.filoghost.holograms.nms.interfaces.HologramWitherSkull;
@ -127,5 +130,10 @@ public class NmsManagerImpl implements NmsManager {
@Override
public boolean hasChatHoverFeature() {
return true;
}
}
@Override
public HologramArmorStand spawnHologramArmorStand(World world, double x, double y, double z, HologramBase parent) throws SpawnFailedException {
throw new NotImplementedException("Method can only be used on 1.8 or greater");
}
}

View File

@ -0,0 +1,40 @@
package com.gmail.filoghost.holograms.nms.v1_8_R1;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_8_R1.CraftServer;
import org.bukkit.craftbukkit.v1_8_R1.entity.CraftItem;
import org.bukkit.entity.Entity;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
public class CraftCustomItem extends CraftItem {
public CraftCustomItem(CraftServer server, EntityCustomItem entity) {
super(server, entity);
}
// Disallow all the bukkit methods.
@Override
public void remove() {
// Cannot be removed, this is the most important to override.
}
// Methods from Entity
@Override public void setVelocity(Vector vel) { }
@Override public boolean teleport(Location loc) { return false; }
@Override public boolean teleport(Entity entity) { return false; }
@Override public boolean teleport(Location loc, TeleportCause cause) { return false; }
@Override public boolean teleport(Entity entity, TeleportCause cause) { return false; }
@Override public void setFireTicks(int ticks) { }
@Override public boolean setPassenger(Entity entity) { return false; }
@Override public boolean eject() { return false; }
@Override public boolean leaveVehicle() { return false; }
@Override public void playEffect(EntityEffect effect) { }
// Methods from Item
@Override public void setItemStack(ItemStack stack) { }
@Override public void setPickupDelay(int delay) { }
}

View File

@ -0,0 +1,65 @@
package com.gmail.filoghost.holograms.nms.v1_8_R1;
import java.util.Collection;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_8_R1.CraftServer;
import org.bukkit.craftbukkit.v1_8_R1.entity.CraftArmorStand;
import org.bukkit.entity.Entity;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
import org.bukkit.util.EulerAngle;
import org.bukkit.util.Vector;
public class CraftHologramArmorStand extends CraftArmorStand {
public CraftHologramArmorStand(CraftServer server, EntityHologramArmorStand entity) {
super(server, entity);
}
// Disallow all the bukkit methods.
@Override
public void remove() {
// Cannot be removed, this is the most important to override.
}
// Methods from Armor stand class
@Override public void setArms(boolean arms) { }
@Override public void setBasePlate(boolean basePlate) { }
@Override public void setBodyPose(EulerAngle pose) { }
@Override public void setBoots(ItemStack item) { }
@Override public void setChestplate(ItemStack item) { }
@Override public void setGravity(boolean gravity) { }
@Override public void setHeadPose(EulerAngle pose) { }
@Override public void setHelmet(ItemStack item) { }
@Override public void setItemInHand(ItemStack item) { }
@Override public void setLeftArmPose(EulerAngle pose) { }
@Override public void setLeftLegPose(EulerAngle pose) { }
@Override public void setLeggings(ItemStack item) { }
@Override public void setRightArmPose(EulerAngle pose) { }
@Override public void setRightLegPose(EulerAngle pose) { }
@Override public void setSmall(boolean small) { }
@Override public void setVisible(boolean visible) { }
// Methods from LivingEntity class
@Override public boolean addPotionEffect(PotionEffect effect) { return false; }
@Override public boolean addPotionEffect(PotionEffect effect, boolean param) { return false; }
@Override public boolean addPotionEffects(Collection<PotionEffect> effects) { return false; }
@Override public void setRemoveWhenFarAway(boolean remove) { }
// Methods from Entity
@Override public void setVelocity(Vector vel) { }
@Override public boolean teleport(Location loc) { return false; }
@Override public boolean teleport(Entity entity) { return false; }
@Override public boolean teleport(Location loc, TeleportCause cause) { return false; }
@Override public boolean teleport(Entity entity, TeleportCause cause) { return false; }
@Override public void setFireTicks(int ticks) { }
@Override public boolean setPassenger(Entity entity) { return false; }
@Override public boolean eject() { return false; }
@Override public boolean leaveVehicle() { return false; }
@Override public void playEffect(EntityEffect effect) { }
}

View File

@ -0,0 +1,48 @@
package com.gmail.filoghost.holograms.nms.v1_8_R1;
import java.util.Collection;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_8_R1.CraftServer;
import org.bukkit.craftbukkit.v1_8_R1.entity.CraftSlime;
import org.bukkit.entity.Entity;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.potion.PotionEffect;
import org.bukkit.util.Vector;
public class CraftTouchSlime extends CraftSlime {
public CraftTouchSlime(CraftServer server, EntityTouchSlime entity) {
super(server, entity);
}
// Disallow all the bukkit methods.
@Override
public void remove() {
// Cannot be removed, this is the most important to override.
}
// Methods from LivingEntity class
@Override public boolean addPotionEffect(PotionEffect effect) { return false; }
@Override public boolean addPotionEffect(PotionEffect effect, boolean param) { return false; }
@Override public boolean addPotionEffects(Collection<PotionEffect> effects) { return false; }
@Override public void setRemoveWhenFarAway(boolean remove) { }
// Methods from Entity
@Override public void setVelocity(Vector vel) { }
@Override public boolean teleport(Location loc) { return false; }
@Override public boolean teleport(Entity entity) { return false; }
@Override public boolean teleport(Location loc, TeleportCause cause) { return false; }
@Override public boolean teleport(Entity entity, TeleportCause cause) { return false; }
@Override public void setFireTicks(int ticks) { }
@Override public boolean setPassenger(Entity entity) { return false; }
@Override public boolean eject() { return false; }
@Override public boolean leaveVehicle() { return false; }
@Override public void playEffect(EntityEffect effect) { }
// Methods from Slime
@Override public void setSize(int size) { }
}

View File

@ -0,0 +1,192 @@
package com.gmail.filoghost.holograms.nms.v1_8_R1;
import net.minecraft.server.v1_8_R1.Blocks;
import net.minecraft.server.v1_8_R1.DamageSource;
import net.minecraft.server.v1_8_R1.EntityHuman;
import net.minecraft.server.v1_8_R1.EntityItem;
import net.minecraft.server.v1_8_R1.EntityPlayer;
import net.minecraft.server.v1_8_R1.ItemStack;
import net.minecraft.server.v1_8_R1.NBTTagCompound;
import net.minecraft.server.v1_8_R1.NBTTagList;
import net.minecraft.server.v1_8_R1.NBTTagString;
import net.minecraft.server.v1_8_R1.World;
import org.bukkit.craftbukkit.v1_8_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_8_R1.inventory.CraftItemStack;
import org.bukkit.entity.Player;
import com.gmail.filoghost.holograms.HolographicDisplays;
import com.gmail.filoghost.holograms.api.FloatingItem;
import com.gmail.filoghost.holograms.nms.interfaces.BasicEntityNMS;
import com.gmail.filoghost.holograms.nms.interfaces.CustomItem;
import com.gmail.filoghost.holograms.object.HologramBase;
import com.gmail.filoghost.holograms.utils.ItemUtils;
public class EntityCustomItem extends EntityItem implements CustomItem, BasicEntityNMS {
private boolean lockTick;
private HologramBase parent;
public EntityCustomItem(World world) {
super(world);
super.pickupDelay = Integer.MAX_VALUE;
}
@Override
public void s_() {
// Checks every 20 ticks.
if (ticksLived % 20 == 0) {
// The item dies without a vehicle.
if (this.vehicle == null) {
die();
}
}
if (!lockTick) {
super.s_();
}
}
@Override
public ItemStack getItemStack() {
// Dirty method to check if the icon is being picked up
StackTraceElement[] stacktrace = Thread.currentThread().getStackTrace();
if (stacktrace.length > 2 && stacktrace[2].getClassName().contains("EntityInsentient")) {
return null; // Try to pickup this, dear entity ignoring the pickupDelay!
}
return super.getItemStack();
}
// Method called when a player is near.
@Override
public void d(EntityHuman human) {
if (parent instanceof FloatingItem && human instanceof EntityPlayer) {
FloatingItem floatingItemParent = (FloatingItem) parent;
if (floatingItemParent.hasPickupHandler()) {
try {
floatingItemParent.getPickupHandler().onPickup(floatingItemParent, (Player) human.getBukkitEntity());
} catch (Exception ex) {
ex.printStackTrace();
HolographicDisplays.getInstance().getLogger().warning("An exception occurred while a player picking up a floating item. It's probably caused by another plugin using Holographic Displays as library.");
}
}
// It is never added to the inventory.
}
}
@Override
public void b(NBTTagCompound nbttagcompound) {
// Do not save NBT.
}
@Override
public boolean c(NBTTagCompound nbttagcompound) {
// Do not save NBT.
return false;
}
@Override
public boolean d(NBTTagCompound nbttagcompound) {
// Do not save NBT.
return false;
}
@Override
public void e(NBTTagCompound nbttagcompound) {
// Do not save NBT.
}
@Override
public boolean isInvulnerable(DamageSource damagesource) {
/*
* The field Entity.invulnerable is private.
* It's only used while saving NBTTags, but since the entity would be killed
* on chunk unload, we prefer to override isInvulnerable().
*/
return true;
}
@Override
public void setLockTick(boolean lock) {
lockTick = lock;
}
@Override
public void die() {
setLockTick(false);
super.die();
}
@Override
public CraftEntity getBukkitEntity() {
if (super.bukkitEntity == null) {
this.bukkitEntity = new CraftCustomItem(this.world.getServer(), this);
}
return this.bukkitEntity;
}
@Override
public boolean isDeadNMS() {
return this.dead;
}
@Override
public void killEntityNMS() {
die();
}
@Override
public void setLocationNMS(double x, double y, double z) {
super.setPosition(x, y, z);
}
@Override
public void setItemStackNMS(org.bukkit.inventory.ItemStack stack) {
ItemStack newItem = CraftItemStack.asNMSCopy(stack);
if (newItem == null) {
newItem = new ItemStack(Blocks.BEDROCK);
}
if (newItem.getTag() == null) {
newItem.setTag(new NBTTagCompound());
}
NBTTagCompound display = newItem.getTag().getCompound("display");
if (!newItem.getTag().hasKey("display")) {
newItem.getTag().set("display", display);
}
NBTTagList tagList = new NBTTagList();
tagList.add(new NBTTagString(ItemUtils.ANTISTACK_LORE)); // Antistack lore
display.set("Lore", tagList);
newItem.count = 0;
setItemStack(newItem);
}
@Override
public HologramBase getParentHologram() {
return parent;
}
@Override
public void setParentHologram(HologramBase base) {
this.parent = base;
}
@Override
public void allowPickup(boolean pickup) {
if (pickup) {
super.pickupDelay = 0;
} else {
super.pickupDelay = Integer.MAX_VALUE;
}
}
}

View File

@ -0,0 +1,167 @@
package com.gmail.filoghost.holograms.nms.v1_8_R1;
import net.minecraft.server.v1_8_R1.DamageSource;
import net.minecraft.server.v1_8_R1.Entity;
import net.minecraft.server.v1_8_R1.EntityArmorStand;
import net.minecraft.server.v1_8_R1.NBTTagCompound;
import net.minecraft.server.v1_8_R1.World;
import org.bukkit.craftbukkit.v1_8_R1.entity.CraftEntity;
import com.gmail.filoghost.holograms.nms.interfaces.BasicEntityNMS;
import com.gmail.filoghost.holograms.nms.interfaces.HologramArmorStand;
import com.gmail.filoghost.holograms.object.HologramBase;
import com.gmail.filoghost.holograms.utils.ReflectionUtils;
public class EntityHologramArmorStand extends EntityArmorStand implements HologramArmorStand {
private boolean lockTick;
private HologramBase parent;
public EntityHologramArmorStand(World world) {
super(world);
setInvisible(true);
setSmall(true);
setArms(false);
setGravity(true);
setBasePlate(true);
try {
ReflectionUtils.setPrivateField(EntityArmorStand.class, this, "bg", 1);
} catch (Exception e) {
//TODO
e.printStackTrace();
}
a(0.0F, 0.0F);
}
@Override
public void b(NBTTagCompound nbttagcompound) {
// Do not save NBT.
}
@Override
public boolean c(NBTTagCompound nbttagcompound) {
// Do not save NBT.
return false;
}
@Override
public boolean d(NBTTagCompound nbttagcompound) {
// Do not save NBT.
return false;
}
@Override
public void e(NBTTagCompound nbttagcompound) {
// Do not save NBT.
}
@Override
public boolean isInvulnerable(DamageSource source) {
/*
* The field Entity.invulnerable is private.
* It's only used while saving NBTTags, but since the entity would be killed
* on chunk unload, we prefer to override isInvulnerable().
*/
return true;
}
@Override
public void setCustomName(String customName) {
// Locks the custom name.
}
@Override
public void setCustomNameVisible(boolean visible) {
// Locks the custom name.
}
@Override
public void s_() {
if (!lockTick) {
super.s_();
}
}
@Override
public void makeSound(String sound, float f1, float f2) {
// Remove sounds.
}
@Override
public void forceSetCustomName(String name) {
if (name != null && name.length() > 300) {
name = name.substring(0, 300);
}
super.setCustomName(name);
super.setCustomNameVisible(name != null);
}
@Override
public String getCustomNameNMS() {
return super.getCustomName();
}
public void callSuperTick() {
super.h();
}
@Override
public void setLockTick(boolean lock) {
lockTick = lock;
}
@Override
public void die() {
setLockTick(false);
super.die();
}
@Override
public CraftEntity getBukkitEntity() {
if (super.bukkitEntity == null) {
this.bukkitEntity = new CraftHologramArmorStand(this.world.getServer(), this);
}
return this.bukkitEntity;
}
@Override
public void killEntityNMS() {
die();
}
@Override
public void setLocationNMS(double x, double y, double z) {
super.setPosition(x, y, z);
}
@Override
public boolean isDeadNMS() {
return this.dead;
}
@Override
public void setPassengerNMS(BasicEntityNMS passenger) {
if (passenger instanceof Entity) {
((Entity) passenger).setPassengerOf(this);
}
}
@Override
public void setPassengerNMS(org.bukkit.entity.Entity bukkitEntity) {
((CraftEntity) bukkitEntity).getHandle().setPassengerOf(this);
}
@Override
public HologramBase getParentHologram() {
return parent;
}
@Override
public void setParentHologram(HologramBase base) {
this.parent = base;
}
}

View File

@ -0,0 +1,136 @@
package com.gmail.filoghost.holograms.nms.v1_8_R1;
import org.bukkit.craftbukkit.v1_8_R1.entity.CraftEntity;
import com.gmail.filoghost.holograms.nms.interfaces.TouchSlime;
import com.gmail.filoghost.holograms.object.HologramBase;
import net.minecraft.server.v1_8_R1.DamageSource;
import net.minecraft.server.v1_8_R1.EntitySlime;
import net.minecraft.server.v1_8_R1.NBTTagCompound;
import net.minecraft.server.v1_8_R1.World;
public class EntityTouchSlime extends EntitySlime implements TouchSlime {
private boolean lockTick;
private HologramBase parent;
public EntityTouchSlime(World world) {
super(world);
super.persistent = true;
a(0.0F, 0.0F);
setSize(1);
setInvisible(true);
}
@Override
public void s_() {
// Checks every 20 ticks.
if (ticksLived % 20 == 0) {
// The slime dies without a vehicle.
if (this.vehicle == null) {
die();
}
}
if (!lockTick) {
super.s_();
}
}
@Override
public void b(NBTTagCompound nbttagcompound) {
// Do not save NBT.
}
@Override
public boolean c(NBTTagCompound nbttagcompound) {
// Do not save NBT.
return false;
}
@Override
public boolean d(NBTTagCompound nbttagcompound) {
// Do not save NBT.
return false;
}
@Override
public void e(NBTTagCompound nbttagcompound) {
// Do not save NBT.
}
@Override
public boolean isInvulnerable(DamageSource source) {
/*
* The field Entity.invulnerable is private.
* It's only used while saving NBTTags, but since the entity would be killed
* on chunk unload, we prefer to override isInvulnerable().
*/
return true;
}
@Override
public void setCustomName(String customName) {
// Locks the custom name.
}
@Override
public void setCustomNameVisible(boolean visible) {
// Locks the custom name.
}
@Override
public void makeSound(String sound, float volume, float pitch) {
// Remove sounds.
}
@Override
public void setLockTick(boolean lock) {
lockTick = lock;
}
@Override
public void die() {
setLockTick(false);
super.die();
}
public HologramBase getParent() {
return parent;
}
@Override
public CraftEntity getBukkitEntity() {
if (super.bukkitEntity == null) {
this.bukkitEntity = new CraftTouchSlime(this.world.getServer(), this);
}
return this.bukkitEntity;
}
@Override
public boolean isDeadNMS() {
return super.dead;
}
@Override
public void killEntityNMS() {
die();
}
@Override
public void setLocationNMS(double x, double y, double z) {
super.setPosition(x, y, z);
}
@Override
public HologramBase getParentHologram() {
return parent;
}
@Override
public void setParentHologram(HologramBase base) {
this.parent = base;
}
}

View File

@ -0,0 +1,158 @@
package com.gmail.filoghost.holograms.nms.v1_8_R1;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.server.v1_8_R1.ChatSerializer;
import net.minecraft.server.v1_8_R1.NBTTagCompound;
import net.minecraft.server.v1_8_R1.PacketPlayOutChat;
import org.bukkit.ChatColor;
import org.bukkit.craftbukkit.libs.com.google.gson.stream.JsonWriter;
import org.bukkit.craftbukkit.v1_8_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_8_R1.inventory.CraftItemStack;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import com.gmail.filoghost.holograms.nms.interfaces.FancyMessage;
public class FancyMessageImpl implements FancyMessage {
private List<MessagePart> messageParts;
public FancyMessageImpl(String firstPartText) {
messageParts = new ArrayList<MessagePart>();
messageParts.add(new MessagePart(firstPartText));
}
public FancyMessageImpl color(ChatColor color) {
if (!color.isColor()) {
throw new IllegalArgumentException(color.name() + " is not a color");
}
latest().color = color;
return this;
}
public FancyMessageImpl style(ChatColor... styles) {
for (ChatColor style : styles) {
if (!style.isFormat()) {
throw new IllegalArgumentException(style.name() + " is not a style");
}
}
latest().styles = styles;
return this;
}
public FancyMessageImpl file(String path) {
onClick("open_file", path);
return this;
}
public FancyMessageImpl link(String url) {
onClick("open_url", url);
return this;
}
public FancyMessageImpl suggest(String command) {
onClick("suggest_command", command);
return this;
}
public FancyMessageImpl command(String command) {
onClick("run_command", command);
return this;
}
public FancyMessageImpl achievementTooltip(String name) {
onHover("show_achievement", "achievement." + name);
return this;
}
public FancyMessageImpl itemTooltip(String itemJSON) {
onHover("show_item", itemJSON);
return this;
}
public FancyMessageImpl itemTooltip(ItemStack itemStack) {
return itemTooltip(CraftItemStack.asNMSCopy(itemStack).save(new NBTTagCompound()).toString());
}
public FancyMessageImpl tooltip(String text) {
String[] lines = text.split("\\n");
if (lines.length <= 1) {
onHover("show_text", text);
} else {
itemTooltip(makeMultilineTooltip(lines));
}
return this;
}
public FancyMessageImpl then(Object obj) {
messageParts.add(new MessagePart(obj.toString()));
return this;
}
public String toJSONString() {
StringWriter stringWriter = new StringWriter();
JsonWriter json = new JsonWriter(stringWriter);
try {
if (messageParts.size() == 1) {
latest().writeJson(json);
} else {
json.beginObject().name("text").value("").name("extra").beginArray();
for (MessagePart part : messageParts) {
part.writeJson(json);
}
json.endArray().endObject();
}
} catch (IOException e) {
throw new RuntimeException("invalid message");
}
return stringWriter.toString();
}
public void send(Player player){
((CraftPlayer) player).getHandle().playerConnection.sendPacket(new PacketPlayOutChat(ChatSerializer.a(toJSONString())));
}
private MessagePart latest() {
return messageParts.get(messageParts.size() - 1);
}
private String makeMultilineTooltip(String[] lines) {
StringWriter stringWriter = new StringWriter();
JsonWriter json = new JsonWriter(stringWriter);
try {
json.beginObject().name("id").value(1);
json.name("tag").beginObject().name("display").beginObject();
json.name("Name").value("\\u00A7f" + lines[0].replace("\"", "\\\""));
json.name("Lore").beginArray();
for (int i = 1; i < lines.length; i++) {
String line = lines[i];
json.value(line.isEmpty() ? " " : line.replace("\"", "\\\""));
}
json.endArray().endObject().endObject().endObject();
json.close();
} catch (IOException e) {
throw new RuntimeException("invalid tooltip");
}
return stringWriter.toString();
}
private void onClick(String name, String data) {
MessagePart latest = latest();
latest.clickActionName = name;
latest.clickActionData = data;
}
private void onHover(String name, String data) {
MessagePart latest = latest();
latest.hoverActionName = name;
latest.hoverActionData = data;
}
}

View File

@ -0,0 +1,131 @@
package com.gmail.filoghost.holograms.nms.v1_8_R1;
import net.minecraft.server.v1_8_R1.Entity;
import net.minecraft.server.v1_8_R1.EntityTypes;
import net.minecraft.server.v1_8_R1.WorldServer;
import org.apache.commons.lang.NotImplementedException;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_8_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_8_R1.entity.CraftEntity;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
import org.bukkit.inventory.ItemStack;
import com.gmail.filoghost.holograms.exception.SpawnFailedException;
import com.gmail.filoghost.holograms.nms.interfaces.BasicEntityNMS;
import com.gmail.filoghost.holograms.nms.interfaces.CustomItem;
import com.gmail.filoghost.holograms.nms.interfaces.FancyMessage;
import com.gmail.filoghost.holograms.nms.interfaces.HologramArmorStand;
import com.gmail.filoghost.holograms.nms.interfaces.HologramComponent;
import com.gmail.filoghost.holograms.nms.interfaces.HologramHorse;
import com.gmail.filoghost.holograms.nms.interfaces.HologramWitherSkull;
import com.gmail.filoghost.holograms.nms.interfaces.NmsManager;
import com.gmail.filoghost.holograms.object.HologramBase;
import com.gmail.filoghost.holograms.utils.ReflectionUtils;
import com.gmail.filoghost.holograms.utils.VersionUtils;
public class NmsManagerImpl implements NmsManager {
@Override
public void registerCustomEntities() throws Exception {
registerCustomEntity(EntityHologramArmorStand.class, "ArmorStand", 30);
registerCustomEntity(EntityCustomItem.class, "Item", 1);
registerCustomEntity(EntityTouchSlime.class, "Slime", 55);
}
@SuppressWarnings("rawtypes")
public void registerCustomEntity(Class entityClass, String name, int id) throws Exception {
if (VersionUtils.isMCPCOrCauldron()) {
// MCPC+ / Cauldron entity registration.
Class<?> entityTypesClass = Class.forName("net.minecraft.server.v1_8_R1.EntityTypes");
ReflectionUtils.putInPrivateStaticMap(entityTypesClass, "field_75626_c", entityClass, name);
ReflectionUtils.putInPrivateStaticMap(entityTypesClass, "field_75624_e", entityClass, Integer.valueOf(id));
} else {
// Normal entity registration.
ReflectionUtils.putInPrivateStaticMap(EntityTypes.class, "d", entityClass, name);
ReflectionUtils.putInPrivateStaticMap(EntityTypes.class, "f", entityClass, Integer.valueOf(id));
}
}
@Override
public HologramArmorStand spawnHologramArmorStand(World world, double x, double y, double z, HologramBase parent) throws SpawnFailedException {
WorldServer nmsWorld = ((CraftWorld) world).getHandle();
EntityHologramArmorStand invisibleArmorStand = new EntityHologramArmorStand(nmsWorld);
invisibleArmorStand.setParentHologram(parent);
invisibleArmorStand.setLocationNMS(x, y, z);
if (!nmsWorld.addEntity(invisibleArmorStand, SpawnReason.CUSTOM)) {
throw new SpawnFailedException();
}
return invisibleArmorStand;
}
@Override
public HologramHorse spawnHologramHorse(org.bukkit.World world, double x, double y, double z, HologramBase parent) throws SpawnFailedException {
throw new NotImplementedException("Method can only be used on 1.7 or lower");
}
@Override
public HologramWitherSkull spawnHologramWitherSkull(org.bukkit.World bukkitWorld, double x, double y, double z, HologramBase parent) throws SpawnFailedException {
throw new NotImplementedException("Method can only be used on 1.7 or lower");
}
@Override
public CustomItem spawnCustomItem(org.bukkit.World bukkitWorld, double x, double y, double z, HologramBase parent, ItemStack stack) throws SpawnFailedException {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
EntityCustomItem customItem = new EntityCustomItem(nmsWorld);
customItem.setParentHologram(parent);
customItem.setLocationNMS(x, y, z);
customItem.setItemStackNMS(stack);
if (!nmsWorld.addEntity(customItem, SpawnReason.CUSTOM)) {
throw new SpawnFailedException();
}
return customItem;
}
@Override
public EntityTouchSlime spawnTouchSlime(org.bukkit.World bukkitWorld, double x, double y, double z, HologramBase parent) throws SpawnFailedException {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
EntityTouchSlime touchSlime = new EntityTouchSlime(nmsWorld);
touchSlime.setParentHologram(parent);
touchSlime.setLocationNMS(x, y, z);
if (!nmsWorld.addEntity(touchSlime, SpawnReason.CUSTOM)) {
throw new SpawnFailedException();
}
return touchSlime;
}
@Override
public boolean isHologramComponent(org.bukkit.entity.Entity bukkitEntity) {
return ((CraftEntity) bukkitEntity).getHandle() instanceof HologramComponent;
}
@Override
public boolean isBasicEntityNMS(org.bukkit.entity.Entity bukkitEntity) {
return ((CraftEntity) bukkitEntity).getHandle() instanceof BasicEntityNMS;
}
@Override
public HologramBase getParentHologram(org.bukkit.entity.Entity bukkitEntity) {
Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle();
if (nmsEntity instanceof HologramComponent) {
return ((HologramComponent) nmsEntity).getParentHologram();
}
return null;
}
@Override
public FancyMessage newFancyMessage(String text) {
return new FancyMessageImpl(text);
}
@Override
public boolean hasChatHoverFeature() {
return true;
}
}

View File

@ -149,7 +149,11 @@ public class CraftHologram extends HologramBase implements Hologram {
if (currentY != this.y) {
// Extra space for the floating item, blocks are smaller
if (ItemUtils.appearsAsBlock(icon.getType())) {
currentY -= 0.27;
if (HolographicDisplays.is1_8) {
currentY -= 0.42;
} else {
currentY -= 0.27;
}
} else {
currentY -= 0.52;
}
@ -169,7 +173,7 @@ public class CraftHologram extends HologramBase implements Hologram {
linesEntities.add(lineEntity);
// Placeholders.
HolographicDisplays.getPlaceholderManager().trackIfNecessary(lineEntity.getHorse());
HolographicDisplays.getPlaceholderManager().trackIfNecessary(lineEntity.getTextEntity());
}
currentY -= lineSpacing;

View File

@ -2,12 +2,12 @@ package com.gmail.filoghost.holograms.object;
import java.util.List;
import com.gmail.filoghost.holograms.nms.interfaces.HologramHorse;
import com.gmail.filoghost.holograms.nms.interfaces.NameableEntityNMS;
import com.gmail.filoghost.holograms.placeholders.Placeholder;
public class HologramLineData {
private HologramHorse horse;
private NameableEntityNMS nameableEntity;
private String originalName;
private Placeholder[] containedPlaceholders;
@ -16,8 +16,8 @@ public class HologramLineData {
private String[] bungeeStatuses;
private String[] worldsPlayerCount;
public HologramLineData(HologramHorse horse, String originalName) {
this.horse = horse;
public HologramLineData(NameableEntityNMS nameableEntity, String originalName) {
this.nameableEntity = nameableEntity;
this.originalName = originalName;
}
@ -41,8 +41,8 @@ public class HologramLineData {
worldsPlayerCount = list.toArray(worldsPlayerCount);
}
public HologramHorse getHorse() {
return horse;
public NameableEntityNMS getNameableEntity() {
return nameableEntity;
}
public String getSavedName() {

View File

@ -3,8 +3,10 @@ package com.gmail.filoghost.holograms.object.pieces;
import org.bukkit.World;
import org.bukkit.inventory.ItemStack;
import com.gmail.filoghost.holograms.HolographicDisplays;
import com.gmail.filoghost.holograms.exception.SpawnFailedException;
import com.gmail.filoghost.holograms.nms.interfaces.CustomItem;
import com.gmail.filoghost.holograms.nms.interfaces.HologramArmorStand;
import com.gmail.filoghost.holograms.nms.interfaces.HologramWitherSkull;
import com.gmail.filoghost.holograms.object.HologramBase;
@ -12,11 +14,13 @@ import static com.gmail.filoghost.holograms.HolographicDisplays.nmsManager;
public class FloatingItemDoubleEntity extends FloatingDoubleEntity {
private static final double VERTICAL_OFFSET = -0.21;
private static final double VERTICAL_OFFSET_SKULL = -0.21;
private static final double VERTICAL_OFFSET_ARMORSTAND = -1.48; //TODO
private ItemStack itemStack;
private CustomItem item;
private HologramWitherSkull skull;
private HologramArmorStand armorStand;
private boolean allowPickup;
@ -28,16 +32,31 @@ public class FloatingItemDoubleEntity extends FloatingDoubleEntity {
public void spawn(HologramBase parent, World bukkitWorld, double x, double y, double z) throws SpawnFailedException {
despawn();
item = nmsManager.spawnCustomItem(bukkitWorld, x, y + VERTICAL_OFFSET, z, parent, itemStack);
skull = nmsManager.spawnHologramWitherSkull(bukkitWorld, x, y + VERTICAL_OFFSET, z, parent);
if (HolographicDisplays.is1_8) {
item = nmsManager.spawnCustomItem(bukkitWorld, x, y + VERTICAL_OFFSET_ARMORSTAND, z, parent, itemStack);
armorStand = nmsManager.spawnHologramArmorStand(bukkitWorld, x, y + VERTICAL_OFFSET_ARMORSTAND, z, parent);
item.allowPickup(allowPickup);
armorStand.setPassengerNMS(item);
item.setLockTick(true);
armorStand.setLockTick(true);
} else {
item.allowPickup(allowPickup);
// Let the item ride the wither skull.
skull.setPassengerNMS(item);
item.setLockTick(true);
skull.setLockTick(true);
item = nmsManager.spawnCustomItem(bukkitWorld, x, y + VERTICAL_OFFSET_SKULL, z, parent, itemStack);
skull = nmsManager.spawnHologramWitherSkull(bukkitWorld, x, y + VERTICAL_OFFSET_SKULL, z, parent);
item.allowPickup(allowPickup);
// Let the item ride the wither skull.
skull.setPassengerNMS(item);
item.setLockTick(true);
skull.setLockTick(true);
}
}
@Override
@ -51,6 +70,11 @@ public class FloatingItemDoubleEntity extends FloatingDoubleEntity {
skull.killEntityNMS();
skull = null;
}
if (armorStand != null) {
armorStand.killEntityNMS();
armorStand = null;
}
}
public boolean isSpawned() {
@ -76,10 +100,14 @@ public class FloatingItemDoubleEntity extends FloatingDoubleEntity {
}
@Override
public void teleport(double x, double y, double z) {
public void teleport(double x, double y, double z) {
if (skull != null) {
skull.setLocationNMS(x, y + VERTICAL_OFFSET, z);
skull.setLocationNMS(x, y + VERTICAL_OFFSET_SKULL, z);
skull.sendUpdatePacketNear();
}
if (armorStand != null) {
armorStand.setLocationNMS(x, y + VERTICAL_OFFSET_ARMORSTAND, z);
}
}
}

View File

@ -2,7 +2,9 @@ package com.gmail.filoghost.holograms.object.pieces;
import org.bukkit.World;
import com.gmail.filoghost.holograms.HolographicDisplays;
import com.gmail.filoghost.holograms.exception.SpawnFailedException;
import com.gmail.filoghost.holograms.nms.interfaces.HologramArmorStand;
import com.gmail.filoghost.holograms.nms.interfaces.HologramWitherSkull;
import com.gmail.filoghost.holograms.nms.interfaces.TouchSlime;
import com.gmail.filoghost.holograms.object.HologramBase;
@ -11,10 +13,12 @@ import static com.gmail.filoghost.holograms.HolographicDisplays.nmsManager;
public class FloatingTouchSlimeDoubleEntity extends FloatingDoubleEntity {
private static final double VERTICAL_OFFSET = -0.3;
private static final double VERTICAL_OFFSET_SKULL = -0.3;
private static final double VERTICAL_OFFSET_ARMORSTAND = -1.6;
private TouchSlime slime;
private HologramWitherSkull skull;
private HologramArmorStand armorStand;
public FloatingTouchSlimeDoubleEntity() {
}
@ -23,14 +27,26 @@ public class FloatingTouchSlimeDoubleEntity extends FloatingDoubleEntity {
public void spawn(HologramBase parent, World bukkitWorld, double x, double y, double z) throws SpawnFailedException {
despawn();
slime = nmsManager.spawnTouchSlime(bukkitWorld, x, y + VERTICAL_OFFSET, z, parent);
skull = nmsManager.spawnHologramWitherSkull(bukkitWorld, x, y + VERTICAL_OFFSET, z, parent);
if (HolographicDisplays.is1_8) {
// Let the slime ride the wither skull.
skull.setPassengerNMS(slime);
slime.setLockTick(true);
skull.setLockTick(true);
slime = nmsManager.spawnTouchSlime(bukkitWorld, x, y + VERTICAL_OFFSET_ARMORSTAND, z, parent);
armorStand = nmsManager.spawnHologramArmorStand(bukkitWorld, x, y + VERTICAL_OFFSET_ARMORSTAND, z, parent);
armorStand.setPassengerNMS(slime);
slime.setLockTick(true);
armorStand.setLockTick(true);
} else {
slime = nmsManager.spawnTouchSlime(bukkitWorld, x, y + VERTICAL_OFFSET_SKULL, z, parent);
skull = nmsManager.spawnHologramWitherSkull(bukkitWorld, x, y + VERTICAL_OFFSET_SKULL, z, parent);
// Let the slime ride the wither skull.
skull.setPassengerNMS(slime);
slime.setLockTick(true);
skull.setLockTick(true);
}
}
@Override
@ -44,17 +60,26 @@ public class FloatingTouchSlimeDoubleEntity extends FloatingDoubleEntity {
skull.killEntityNMS();
skull = null;
}
if (armorStand != null) {
armorStand.killEntityNMS();
armorStand = null;
}
}
public boolean isSpawned() {
return slime != null && skull != null;
return slime != null && skull != null && armorStand != null;
}
@Override
public void teleport(double x, double y, double z) {
if (skull != null) {
skull.setLocationNMS(x, y + VERTICAL_OFFSET, z);
skull.setLocationNMS(x, y + VERTICAL_OFFSET_SKULL, z);
skull.sendUpdatePacketNear();
}
if (armorStand != null) {
armorStand.setLocationNMS(x, y + VERTICAL_OFFSET_ARMORSTAND, z);
}
}
}

View File

@ -1,46 +1,67 @@
package com.gmail.filoghost.holograms.object.pieces;
import org.bukkit.World;
import com.gmail.filoghost.holograms.exception.SpawnFailedException;
import com.gmail.filoghost.holograms.nms.interfaces.HologramHorse;
import com.gmail.filoghost.holograms.nms.interfaces.HologramWitherSkull;
import com.gmail.filoghost.holograms.object.HologramBase;
import static com.gmail.filoghost.holograms.HolographicDisplays.nmsManager;
import org.bukkit.World;
import com.gmail.filoghost.holograms.HolographicDisplays;
import com.gmail.filoghost.holograms.exception.SpawnFailedException;
import com.gmail.filoghost.holograms.nms.interfaces.HologramArmorStand;
import com.gmail.filoghost.holograms.nms.interfaces.HologramHorse;
import com.gmail.filoghost.holograms.nms.interfaces.HologramWitherSkull;
import com.gmail.filoghost.holograms.nms.interfaces.NameableEntityNMS;
import com.gmail.filoghost.holograms.object.HologramBase;
public class HologramLine extends FloatingDoubleEntity {
private static final double VERTICAL_OFFSET = 54.56;
private static final double VERTICAL_OFFSET_SKULL = 54.56;
private static final double VERTICAL_OFFSET_ARMORSTAND = -1.25;
private String text;
private HologramHorse horse;
private HologramWitherSkull skull;
private HologramArmorStand armorStand;
public HologramLine(String text) {
this.text = text;
}
public HologramHorse getHorse() {
return horse;
public NameableEntityNMS getTextEntity() {
if (HolographicDisplays.is1_8) {
return armorStand;
} else {
return horse;
}
}
@Override
public void spawn(HologramBase parent, World bukkitWorld, double x, double y, double z) throws SpawnFailedException {
despawn();
horse = nmsManager.spawnHologramHorse(bukkitWorld, x, y + VERTICAL_OFFSET, z, parent);
skull = nmsManager.spawnHologramWitherSkull(bukkitWorld, x, y + VERTICAL_OFFSET, z, parent);
if (HolographicDisplays.is1_8) {
armorStand = nmsManager.spawnHologramArmorStand(bukkitWorld, x, y + VERTICAL_OFFSET_ARMORSTAND, z, parent);
if (text.length() > 0) {
armorStand.forceSetCustomName(text);
}
armorStand.setLockTick(true);
} else {
horse = nmsManager.spawnHologramHorse(bukkitWorld, x, y + VERTICAL_OFFSET_SKULL, z, parent);
skull = nmsManager.spawnHologramWitherSkull(bukkitWorld, x, y + VERTICAL_OFFSET_SKULL, z, parent);
// Let the horse ride the wither skull.
skull.setPassengerNMS(horse);
// Let the horse ride the wither skull.
skull.setPassengerNMS(horse);
if (text.length() > 0) {
horse.forceSetCustomName(text);
if (text.length() > 0) {
horse.forceSetCustomName(text);
}
horse.setLockTick(true);
skull.setLockTick(true);
}
horse.setLockTick(true);
skull.setLockTick(true);
}
@Override
@ -54,13 +75,22 @@ public class HologramLine extends FloatingDoubleEntity {
skull.killEntityNMS();
skull = null;
}
if (armorStand != null) {
armorStand.killEntityNMS();
armorStand = null;
}
}
@Override
public void teleport(double x, double y, double z) {
if (skull != null) {
skull.setLocationNMS(x, y + VERTICAL_OFFSET, z);
skull.setLocationNMS(x, y + VERTICAL_OFFSET_SKULL, z);
skull.sendUpdatePacketNear();
}
if (armorStand != null) {
armorStand.setLocationNMS(x, y + VERTICAL_OFFSET_ARMORSTAND, z);
}
}
}

View File

@ -11,7 +11,7 @@ import org.bukkit.Bukkit;
import com.gmail.filoghost.holograms.Configuration;
import com.gmail.filoghost.holograms.HolographicDisplays;
import com.gmail.filoghost.holograms.bungee.ServerInfoTimer;
import com.gmail.filoghost.holograms.nms.interfaces.HologramHorse;
import com.gmail.filoghost.holograms.nms.interfaces.NameableEntityNMS;
import com.gmail.filoghost.holograms.object.HologramLineData;
import com.gmail.filoghost.holograms.tasks.WorldPlayerCounterTask;
@ -32,9 +32,9 @@ public class PlaceholderManager {
startTask();
}
public void trackIfNecessary(HologramHorse horse) {
public void trackIfNecessary(NameableEntityNMS nameableEntity) {
String customName = horse.getCustomNameNMS();
String customName = nameableEntity.getCustomNameNMS();
if (customName == null || customName.length() == 0) {
return;
}
@ -132,7 +132,7 @@ public class PlaceholderManager {
}
if (containedPlaceholders != null || bungeeServersOnlinePlayers != null || worldsPlayerCount != null) {
HologramLineData data = new HologramLineData(horse, customName);
HologramLineData data = new HologramLineData(nameableEntity, customName);
if (containedPlaceholders != null) {
data.setContainedPlaceholders(containedPlaceholders);
@ -152,7 +152,7 @@ public class PlaceholderManager {
// The name needs to be updated anyways.
if (updateName) {
horse.forceSetCustomName(customName);
nameableEntity.forceSetCustomName(customName);
}
}
}
@ -165,6 +165,7 @@ public class PlaceholderManager {
taskID = Bukkit.getScheduler().scheduleSyncRepeatingTask(HolographicDisplays.getInstance(), new Runnable() {
@Override
public void run() {
for (Placeholder placeholder : PlaceholdersList.getDefaults()) {
@ -186,7 +187,7 @@ public class PlaceholderManager {
while (iter.hasNext()) {
current = iter.next();
if (current.getHorse().isDeadNMS()) {
if (current.getNameableEntity().isDeadNMS()) {
iter.remove();
} else {
updatePlaceholders(current);
@ -201,7 +202,7 @@ public class PlaceholderManager {
private void updatePlaceholders(HologramLineData data) {
String oldCustomName = data.getHorse().getCustomNameNMS();
String oldCustomName = data.getNameableEntity().getCustomNameNMS();
String newCustomName = data.getSavedName();
if (data.hasPlaceholders()) {
@ -230,7 +231,7 @@ public class PlaceholderManager {
// Update only if needed, don't send useless packets.
if (!oldCustomName.equals(newCustomName)) {
data.getHorse().forceSetCustomName(newCustomName);
data.getNameableEntity().forceSetCustomName(newCustomName);
}
}
}

View File

@ -25,6 +25,7 @@ public class PlaceholdersList {
// Each second
private static final Placeholder ONLINE_PLAYERS = new Placeholder("{online}", "{o}", 10) {
@SuppressWarnings("deprecation")
@Override
public void update() {
currentReplacement = Integer.toString(Bukkit.getOnlinePlayers().length);

View File

@ -154,7 +154,15 @@ public class ProtocolLibHook {
}
private static boolean isHologramType(EntityType type) {
return type == EntityType.HORSE || type == EntityType.WITHER_SKULL || type == EntityType.DROPPED_ITEM || type == EntityType.SLIME;
return type == EntityType.HORSE || type == EntityType.WITHER_SKULL || type == EntityType.DROPPED_ITEM || type == EntityType.SLIME || isArmorstand(type); // To maintain compatibility with 1.8
}
private static boolean isArmorstand(EntityType type) {
if (!HolographicDisplays.is1_8) {
return false;
}
return type == EntityType.ARMOR_STAND;
}
// Horses are always part of a CraftHologram

View File

@ -3,6 +3,8 @@ package com.gmail.filoghost.holograms.utils;
import java.lang.reflect.Field;
import java.util.Map;
import net.minecraft.server.v1_8_R1.EntityArmorStand;
public class ReflectionUtils {
@SuppressWarnings({ "rawtypes", "unchecked" })
@ -11,6 +13,11 @@ public class ReflectionUtils {
field.setAccessible(true);
Map map = (Map) field.get(null);
map.put(key, value);
field.set(null, map);
}
public static void setPrivateField(Class<EntityArmorStand> clazz, Object handle, String fieldName, Object value) throws Exception {
Field field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(handle, value);
}
}