Update for spigot 1.12

This commit is contained in:
filoghost 2017-06-08 14:01:07 +02:00
parent 1a41b4bd0d
commit 81fb3ef028
12 changed files with 1340 additions and 3 deletions

View File

@ -150,11 +150,15 @@ public class HolographicDisplays extends JavaPlugin {
nmsManager = new com.gmail.filoghost.holographicdisplays.nms.v1_11_R1.NmsManagerImpl();
MinecraftVersion.set(MinecraftVersion.v1_11);
} else if ("v1_12_R1".equals(version)) {
nmsManager = new com.gmail.filoghost.holographicdisplays.nms.v1_12_R1.NmsManagerImpl();
MinecraftVersion.set(MinecraftVersion.v1_12);
} else {
printWarnAndDisable(
"******************************************************",
" This version of HolographicDisplays only",
" works on server versions from 1.7 to 1.11.",
" works on server versions from 1.7 to 1.12.",
" The plugin will be disabled.",
"******************************************************"
);

View File

@ -0,0 +1,79 @@
package com.gmail.filoghost.holographicdisplays.nms.v1_12_R1;
import java.util.Collection;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_12_R1.CraftServer;
import org.bukkit.craftbukkit.v1_12_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 CraftNMSArmorStand extends CraftArmorStand {
public CraftNMSArmorStand(CraftServer server, EntityNMSArmorStand 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 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) { }
@Override public void setMarker(boolean marker) { }
// 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) { }
@Override public void setAI(boolean ai) { }
@Override public void setCanPickupItems(boolean pickup) { }
@Override public void setCollidable(boolean collidable) { }
@Override public void setGliding(boolean gliding) { }
@Override public boolean setLeashHolder(Entity holder) { return false; }
// 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) { }
@Override public void setCustomName(String name) { }
@Override public void setCustomNameVisible(boolean flag) { }
@Override public void setGlowing(boolean flag) { }
@Override public void setGravity(boolean gravity) { }
@Override public void setInvulnerable(boolean flag) { }
@Override public void setMomentum(Vector value) { }
@Override public void setSilent(boolean flag) { }
@Override public void setTicksLived(int value) { }
}

View File

@ -0,0 +1,49 @@
package com.gmail.filoghost.holographicdisplays.nms.v1_12_R1;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_12_R1.CraftServer;
import org.bukkit.craftbukkit.v1_12_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 CraftNMSItem extends CraftItem {
public CraftNMSItem(CraftServer server, EntityNMSItem 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) { }
@Override public void setCustomName(String name) { }
@Override public void setCustomNameVisible(boolean flag) { }
@Override public void setGlowing(boolean flag) { }
@Override public void setGravity(boolean gravity) { }
@Override public void setInvulnerable(boolean flag) { }
@Override public void setMomentum(Vector value) { }
@Override public void setSilent(boolean flag) { }
@Override public void setTicksLived(int value) { }
// Methods from Item
@Override public void setItemStack(ItemStack stack) { }
@Override public void setPickupDelay(int delay) { }
}

View File

@ -0,0 +1,61 @@
package com.gmail.filoghost.holographicdisplays.nms.v1_12_R1;
import java.util.Collection;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_12_R1.CraftServer;
import org.bukkit.craftbukkit.v1_12_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 CraftNMSSlime extends CraftSlime {
public CraftNMSSlime(CraftServer server, EntityNMSSlime 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) { }
@Override public void setAI(boolean ai) { }
@Override public void setCanPickupItems(boolean pickup) { }
@Override public void setCollidable(boolean collidable) { }
@Override public void setGliding(boolean gliding) { }
@Override public boolean setLeashHolder(Entity holder) { return false; }
// 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) { }
@Override public void setCustomName(String name) { }
@Override public void setCustomNameVisible(boolean flag) { }
@Override public void setGlowing(boolean flag) { }
@Override public void setGravity(boolean gravity) { }
@Override public void setInvulnerable(boolean flag) { }
@Override public void setMomentum(Vector value) { }
@Override public void setSilent(boolean flag) { }
@Override public void setTicksLived(int value) { }
// Methods from Slime
@Override public void setSize(int size) { }
}

View File

@ -0,0 +1,235 @@
package com.gmail.filoghost.holographicdisplays.nms.v1_12_R1;
import org.bukkit.craftbukkit.v1_12_R1.entity.CraftEntity;
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSArmorStand;
import com.gmail.filoghost.holographicdisplays.object.line.CraftHologramLine;
import com.gmail.filoghost.holographicdisplays.util.ReflectionUtils;
import com.gmail.filoghost.holographicdisplays.util.Utils;
import net.minecraft.server.v1_12_R1.AxisAlignedBB;
import net.minecraft.server.v1_12_R1.DamageSource;
import net.minecraft.server.v1_12_R1.EntityArmorStand;
import net.minecraft.server.v1_12_R1.EntityHuman;
import net.minecraft.server.v1_12_R1.EntityPlayer;
import net.minecraft.server.v1_12_R1.EnumHand;
import net.minecraft.server.v1_12_R1.EnumInteractionResult;
import net.minecraft.server.v1_12_R1.EnumItemSlot;
import net.minecraft.server.v1_12_R1.ItemStack;
import net.minecraft.server.v1_12_R1.NBTTagCompound;
import net.minecraft.server.v1_12_R1.PacketPlayOutEntityTeleport;
import net.minecraft.server.v1_12_R1.SoundEffect;
import net.minecraft.server.v1_12_R1.Vec3D;
import net.minecraft.server.v1_12_R1.World;
public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorStand {
private boolean lockTick;
private CraftHologramLine parentPiece;
public EntityNMSArmorStand(World world, CraftHologramLine parentPiece) {
super(world);
super.setInvisible(true);
super.setSmall(true);
super.setArms(false);
super.setNoGravity(true);
super.setBasePlate(true);
super.setMarker(true);
super.collides = false;
this.parentPiece = parentPiece;
forceSetBoundingBox(new NullBoundingBox());
}
@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 NBTTagCompound save(NBTTagCompound nbttagcompound) {
// Do not save NBT.
return nbttagcompound;
}
@Override
public void f(NBTTagCompound nbttagcompound) {
// Do not load NBT.
}
@Override
public void a(NBTTagCompound nbttagcompound) {
// Do not load 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 boolean isCollidable() {
return false;
}
@Override
public void setCustomName(String customName) {
// Locks the custom name.
}
@Override
public void inactiveTick() {
// Check inactive ticks.
if (!lockTick) {
super.inactiveTick();
}
}
@Override
public void setCustomNameVisible(boolean visible) {
// Locks the custom name.
}
@Override
public EnumInteractionResult a(EntityHuman human, Vec3D vec3d, EnumHand enumhand) {
// Prevent stand being equipped
return EnumInteractionResult.PASS;
}
@Override
public boolean c(int i, ItemStack item) {
// Prevent stand being equipped
return false;
}
@Override
public void setSlot(EnumItemSlot enumitemslot, ItemStack itemstack) {
// Prevent stand being equipped
}
@Override
public void a(AxisAlignedBB boundingBox) {
// Do not change it!
}
public void forceSetBoundingBox(AxisAlignedBB boundingBox) {
super.a(boundingBox);
}
@Override
public int getId() {
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
public void a(SoundEffect soundeffect, float f, float f1) {
// Remove sounds.
}
@Override
public void setCustomNameNMS(String name) {
if (name != null && name.length() > 300) {
name = name.substring(0, 300);
}
super.setCustomName(name);
super.setCustomNameVisible(name != null && !name.isEmpty());
}
@Override
public String getCustomNameNMS() {
return super.getCustomName();
}
@Override
public void setLockTick(boolean lock) {
lockTick = lock;
}
@Override
public void die() {
// Prevent being killed.
}
@Override
public CraftEntity getBukkitEntity() {
if (super.bukkitEntity == null) {
super.bukkitEntity = new CraftNMSArmorStand(super.world.getServer(), this);
}
return super.bukkitEntity;
}
@Override
public void killEntityNMS() {
super.dead = true;
}
@Override
public void setLocationNMS(double x, double y, double z) {
super.setPosition(x, y, z);
// Send a packet near to update the position.
PacketPlayOutEntityTeleport teleportPacket = new PacketPlayOutEntityTeleport(this);
for (Object obj : super.world.players) {
if (obj instanceof EntityPlayer) {
EntityPlayer nmsPlayer = (EntityPlayer) obj;
double distanceSquared = Utils.square(nmsPlayer.locX - super.locX) + Utils.square(nmsPlayer.locZ - super.locZ);
if (distanceSquared < 8192 && nmsPlayer.playerConnection != null) {
nmsPlayer.playerConnection.sendPacket(teleportPacket);
}
}
}
}
@Override
public boolean isDeadNMS() {
return super.dead;
}
@Override
public int getIdNMS() {
return super.getId(); // Return the real ID without checking the stack trace.
}
@Override
public CraftHologramLine getHologramLine() {
return parentPiece;
}
@Override
public org.bukkit.entity.Entity getBukkitEntityNMS() {
return getBukkitEntity();
}
}

View File

@ -0,0 +1,232 @@
package com.gmail.filoghost.holographicdisplays.nms.v1_12_R1;
import net.minecraft.server.v1_12_R1.Entity;
import net.minecraft.server.v1_12_R1.Blocks;
import net.minecraft.server.v1_12_R1.DamageSource;
import net.minecraft.server.v1_12_R1.EntityHuman;
import net.minecraft.server.v1_12_R1.EntityItem;
import net.minecraft.server.v1_12_R1.EntityPlayer;
import net.minecraft.server.v1_12_R1.ItemStack;
import net.minecraft.server.v1_12_R1.NBTTagCompound;
import net.minecraft.server.v1_12_R1.NBTTagList;
import net.minecraft.server.v1_12_R1.NBTTagString;
import net.minecraft.server.v1_12_R1.World;
import org.bukkit.craftbukkit.v1_12_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_12_R1.inventory.CraftItemStack;
import org.bukkit.entity.Player;
import com.gmail.filoghost.holographicdisplays.listener.MainListener;
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSEntityBase;
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSItem;
import com.gmail.filoghost.holographicdisplays.object.line.CraftItemLine;
import com.gmail.filoghost.holographicdisplays.util.DebugHandler;
import com.gmail.filoghost.holographicdisplays.util.ItemUtils;
import com.gmail.filoghost.holographicdisplays.util.ReflectionUtils;
public class EntityNMSItem extends EntityItem implements NMSItem {
private boolean lockTick;
private CraftItemLine parentPiece;
public EntityNMSItem(World world, CraftItemLine piece) {
super(world);
super.pickupDelay = 32767; // Lock the item pickup delay, also prevents entities from picking up the item
this.parentPiece = piece;
}
@Override
public void B_() {
// So it won't get removed.
ticksLived = 0;
if (!lockTick) {
super.B_();
}
}
// Method called when a player is near.
@Override
public void d(EntityHuman human) {
if (human.locY < super.locY - 1.5 || human.locY > super.locY + 1.0) {
// Too low or too high, it's a bit weird.
return;
}
if (parentPiece.getPickupHandler() != null && human instanceof EntityPlayer) {
MainListener.handleItemLinePickup((Player) human.getBukkitEntity(), parentPiece.getPickupHandler(), parentPiece.getParent());
// 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 NBTTagCompound save(NBTTagCompound nbttagcompound) {
// Do not save NBT.
return nbttagcompound;
}
@Override
public void f(NBTTagCompound nbttagcompound) {
// Do not load NBT.
}
@Override
public void a(NBTTagCompound nbttagcompound) {
// Do not load 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 boolean isCollidable() {
return false;
}
@Override
public void inactiveTick() {
// Check inactive ticks.
if (!lockTick) {
super.inactiveTick();
}
}
@Override
public void setLockTick(boolean lock) {
lockTick = lock;
}
@Override
public void die() {
// Prevent being killed.
}
@Override
public CraftEntity getBukkitEntity() {
if (super.bukkitEntity == null) {
super.bukkitEntity = new CraftNMSItem(super.world.getServer(), this);
}
return super.bukkitEntity;
}
@Override
public boolean isDeadNMS() {
return super.dead;
}
@Override
public void killEntityNMS() {
super.dead = true;
}
@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"); // Returns a new NBTTagCompound if not existing
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.setCount(1);
setItemStack(newItem);
}
@Override
public int getIdNMS() {
return super.getId();
}
@Override
public CraftItemLine getHologramLine() {
return parentPiece;
}
@Override
public void allowPickup(boolean pickup) {
if (pickup) {
super.pickupDelay = 0;
} else {
super.pickupDelay = 32767;
}
}
@Override
public org.bukkit.entity.Entity getBukkitEntityNMS() {
return getBukkitEntity();
}
@Override
public void setPassengerOfNMS(NMSEntityBase vehicleBase) {
if (vehicleBase == null || !(vehicleBase instanceof Entity)) {
// It should never dismount
return;
}
Entity entity = (Entity) vehicleBase;
try {
if (super.bJ() != null) {
Entity oldVehicle = super.bJ();
ReflectionUtils.setPrivateField(Entity.class, this, "au", null);
oldVehicle.passengers.remove(this);
}
ReflectionUtils.setPrivateField(Entity.class, this, "au", entity);
entity.passengers.clear();
entity.passengers.add(this);
} catch (Exception ex) {
DebugHandler.handleDebugException(ex);
}
}
@Override
public Object getRawItemStack() {
return super.getItemStack();
}
}

View File

@ -0,0 +1,215 @@
package com.gmail.filoghost.holographicdisplays.nms.v1_12_R1;
import net.minecraft.server.v1_12_R1.EntityDamageSource;
import net.minecraft.server.v1_12_R1.EntityPlayer;
import net.minecraft.server.v1_12_R1.AxisAlignedBB;
import net.minecraft.server.v1_12_R1.DamageSource;
import net.minecraft.server.v1_12_R1.Entity;
import net.minecraft.server.v1_12_R1.EntitySlime;
import net.minecraft.server.v1_12_R1.NBTTagCompound;
import net.minecraft.server.v1_12_R1.SoundEffect;
import net.minecraft.server.v1_12_R1.World;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_12_R1.entity.CraftEntity;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSEntityBase;
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSSlime;
import com.gmail.filoghost.holographicdisplays.object.line.CraftHologramLine;
import com.gmail.filoghost.holographicdisplays.object.line.CraftTouchSlimeLine;
import com.gmail.filoghost.holographicdisplays.util.DebugHandler;
import com.gmail.filoghost.holographicdisplays.util.ReflectionUtils;
public class EntityNMSSlime extends EntitySlime implements NMSSlime {
private boolean lockTick;
private CraftTouchSlimeLine parentPiece;
public EntityNMSSlime(World world, CraftTouchSlimeLine parentPiece) {
super(world);
super.persistent = true;
super.collides = false;
a(0.0F, 0.0F);
setSize(1, false);
setInvisible(true);
this.parentPiece = parentPiece;
forceSetBoundingBox(new NullBoundingBox());
}
@Override
public void a(AxisAlignedBB boundingBox) {
// Do not change it!
}
public void forceSetBoundingBox(AxisAlignedBB boundingBox) {
super.a(boundingBox);
}
@Override
public void B_() {
// So it won't get removed.
ticksLived = 0;
if (!lockTick) {
super.B_();
}
}
@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 NBTTagCompound save(NBTTagCompound nbttagcompound) {
// Do not save NBT.
return nbttagcompound;
}
@Override
public void f(NBTTagCompound nbttagcompound) {
// Do not load NBT.
}
@Override
public void a(NBTTagCompound nbttagcompound) {
// Do not load NBT.
}
@Override
public boolean damageEntity(DamageSource damageSource, float amount) {
if (damageSource instanceof EntityDamageSource) {
EntityDamageSource entityDamageSource = (EntityDamageSource) damageSource;
if (entityDamageSource.getEntity() instanceof EntityPlayer) {
Bukkit.getPluginManager().callEvent(new PlayerInteractEntityEvent(((EntityPlayer) entityDamageSource.getEntity()).getBukkitEntity(), getBukkitEntity())); // Bukkit takes care of the exceptions
}
}
return false;
}
@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 boolean isCollidable() {
return false;
}
@Override
public void inactiveTick() {
// Check inactive ticks.
if (!lockTick) {
super.inactiveTick();
}
}
@Override
public void setCustomName(String customName) {
// Locks the custom name.
}
@Override
public void setCustomNameVisible(boolean visible) {
// Locks the custom name.
}
@Override
public void a(SoundEffect soundeffect, float f, float f1) {
// Remove sounds.
}
@Override
public void setLockTick(boolean lock) {
lockTick = lock;
}
@Override
public void die() {
// Prevent being killed.
}
@Override
public CraftEntity getBukkitEntity() {
if (super.bukkitEntity == null) {
super.bukkitEntity = new CraftNMSSlime(super.world.getServer(), this);
}
return super.bukkitEntity;
}
@Override
public boolean isDeadNMS() {
return super.dead;
}
@Override
public void killEntityNMS() {
super.dead = true;
}
@Override
public void setLocationNMS(double x, double y, double z) {
super.setPosition(x, y, z);
}
@Override
public int getIdNMS() {
return super.getId();
}
@Override
public CraftHologramLine getHologramLine() {
return parentPiece;
}
@Override
public org.bukkit.entity.Entity getBukkitEntityNMS() {
return getBukkitEntity();
}
@Override
public void setPassengerOfNMS(NMSEntityBase vehicleBase) {
if (vehicleBase == null || !(vehicleBase instanceof Entity)) {
// It should never dismount
return;
}
Entity entity = (Entity) vehicleBase;
try {
if (super.bJ() != null) {
Entity oldVehicle = super.bJ();
ReflectionUtils.setPrivateField(Entity.class, this, "au", null);
oldVehicle.passengers.remove(this);
}
ReflectionUtils.setPrivateField(Entity.class, this, "au", entity);
entity.passengers.clear();
entity.passengers.add(this);
} catch (Exception ex) {
DebugHandler.handleDebugException(ex);
}
}
}

View File

@ -0,0 +1,170 @@
package com.gmail.filoghost.holographicdisplays.nms.v1_12_R1;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.server.v1_12_R1.IChatBaseComponent;
import net.minecraft.server.v1_12_R1.PacketPlayOutChat;
import org.bukkit.ChatColor;
import com.google.gson.stream.JsonWriter;
import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
import com.gmail.filoghost.holographicdisplays.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));
}
@Override
public FancyMessageImpl color(ChatColor color) {
if (!color.isColor()) {
throw new IllegalArgumentException(color.name() + " is not a color");
}
latest().color = color;
return this;
}
@Override
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;
}
@Override
public FancyMessageImpl file(String path) {
onClick("open_file", path);
return this;
}
@Override
public FancyMessageImpl link(String url) {
onClick("open_url", url);
return this;
}
@Override
public FancyMessageImpl suggest(String command) {
onClick("suggest_command", command);
return this;
}
@Override
public FancyMessageImpl command(String command) {
onClick("run_command", command);
return this;
}
@Override
public FancyMessageImpl tooltip(String text) {
onHover("show_text", text);
return this;
}
@Override
public FancyMessageImpl then(Object obj) {
messageParts.add(new MessagePart(obj.toString()));
return this;
}
@Override
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();
}
@Override
public void send(Player player) {
((CraftPlayer) player).getHandle().playerConnection.sendPacket(new PacketPlayOutChat(IChatBaseComponent.ChatSerializer.a(toJSONString())));
}
private MessagePart latest() {
return messageParts.get(messageParts.size() - 1);
}
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;
}
static class MessagePart {
public ChatColor color = null;
public ChatColor[] styles = null;
public String clickActionName = null;
public String clickActionData = null;
public String hoverActionName = null;
public String hoverActionData = null;
public final String text;
public MessagePart(final String text) {
this.text = text;
}
public JsonWriter writeJson(final JsonWriter json) throws IOException {
json.beginObject().name("text").value(text);
if (color != null) {
json.name("color").value(color.name().toLowerCase());
}
if (styles != null) {
for (final ChatColor style : styles) {
json.name(style == ChatColor.UNDERLINE ? "underlined" : style.name().toLowerCase()).value(true);
}
}
if (clickActionName != null && clickActionData != null) {
json.name("clickEvent")
.beginObject()
.name("action").value(clickActionName)
.name("value").value(clickActionData)
.endObject();
}
if (hoverActionName != null && hoverActionData != null) {
json.name("hoverEvent")
.beginObject()
.name("action").value(hoverActionName)
.name("value").value(hoverActionData)
.endObject();
}
return json.endObject();
}
}
}

View File

@ -0,0 +1,163 @@
package com.gmail.filoghost.holographicdisplays.nms.v1_12_R1;
import java.lang.reflect.Method;
import org.apache.commons.lang.NotImplementedException;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.craftbukkit.v1_12_R1.CraftChunk;
import org.bukkit.craftbukkit.v1_12_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_12_R1.entity.CraftEntity;
import org.bukkit.inventory.ItemStack;
import com.gmail.filoghost.holographicdisplays.nms.interfaces.FancyMessage;
import com.gmail.filoghost.holographicdisplays.nms.interfaces.NMSManager;
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.NMSHorse;
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSItem;
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSWitherSkull;
import com.gmail.filoghost.holographicdisplays.object.line.CraftHologramLine;
import com.gmail.filoghost.holographicdisplays.object.line.CraftItemLine;
import com.gmail.filoghost.holographicdisplays.object.line.CraftTouchSlimeLine;
import com.gmail.filoghost.holographicdisplays.util.DebugHandler;
import com.gmail.filoghost.holographicdisplays.util.ReflectionUtils;
import com.gmail.filoghost.holographicdisplays.util.Validator;
import com.gmail.filoghost.holographicdisplays.util.VersionUtils;
import net.minecraft.server.v1_12_R1.Entity;
import net.minecraft.server.v1_12_R1.EntityTypes;
import net.minecraft.server.v1_12_R1.MathHelper;
import net.minecraft.server.v1_12_R1.RegistryID;
import net.minecraft.server.v1_12_R1.RegistryMaterials;
import net.minecraft.server.v1_12_R1.World;
import net.minecraft.server.v1_12_R1.WorldServer;
public class NmsManagerImpl implements NMSManager {
private Method validateEntityMethod;
@Override
public void setup() throws Exception {
validateEntityMethod = World.class.getDeclaredMethod("b", Entity.class);
validateEntityMethod.setAccessible(true);
registerCustomEntity(EntityNMSSlime.class, 55);
}
@SuppressWarnings("unchecked")
public void registerCustomEntity(Class<? extends Entity> entityClass, int id) throws Exception {
if (VersionUtils.isMCPCOrCauldron()) {
// MCPC+ / Cauldron entity registration.
throw new UnsupportedOperationException("MCPC, Cauldron and similar softwares are not supported");
} else {
// Use reflection to get the RegistryID of entities.
RegistryID<Class<? extends Entity>> registryID = (RegistryID<Class<? extends Entity>>) ReflectionUtils.getPrivateField(RegistryMaterials.class, EntityTypes.b, "a");
Object[] idToClassMap = (Object[]) ReflectionUtils.getPrivateField(RegistryID.class, registryID, "d");
// Save the the ID -> entity class mapping before the registration.
Object oldValue = idToClassMap[id];
// Register the entity class.
registryID.a(entityClass, id);
// Restore the ID -> entity class mapping.
idToClassMap[id] = oldValue;
}
}
@Override
public NMSHorse spawnNMSHorse(org.bukkit.World world, double x, double y, double z, CraftHologramLine parentPiece) {
throw new NotImplementedException("Method can only be used on 1.7 or lower");
}
@Override
public NMSWitherSkull spawnNMSWitherSkull(org.bukkit.World bukkitWorld, double x, double y, double z, CraftHologramLine parentPiece) {
throw new NotImplementedException("Method can only be used on 1.7 or lower");
}
@Override
public NMSItem spawnNMSItem(org.bukkit.World bukkitWorld, double x, double y, double z, CraftItemLine parentPiece, ItemStack stack) {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
EntityNMSItem customItem = new EntityNMSItem(nmsWorld, parentPiece);
customItem.setLocationNMS(x, y, z);
customItem.setItemStackNMS(stack);
if (!addEntityToWorld(nmsWorld, customItem)) {
DebugHandler.handleSpawnFail(parentPiece);
}
return customItem;
}
@Override
public EntityNMSSlime spawnNMSSlime(org.bukkit.World bukkitWorld, double x, double y, double z, CraftTouchSlimeLine parentPiece) {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
EntityNMSSlime touchSlime = new EntityNMSSlime(nmsWorld, parentPiece);
touchSlime.setLocationNMS(x, y, z);
if (!addEntityToWorld(nmsWorld, touchSlime)) {
DebugHandler.handleSpawnFail(parentPiece);
}
return touchSlime;
}
@Override
public NMSArmorStand spawnNMSArmorStand(org.bukkit.World world, double x, double y, double z, CraftHologramLine parentPiece) {
WorldServer nmsWorld = ((CraftWorld) world).getHandle();
EntityNMSArmorStand invisibleArmorStand = new EntityNMSArmorStand(nmsWorld, parentPiece);
invisibleArmorStand.setLocationNMS(x, y, z);
if (!addEntityToWorld(nmsWorld, invisibleArmorStand)) {
DebugHandler.handleSpawnFail(parentPiece);
}
return invisibleArmorStand;
}
private boolean addEntityToWorld(WorldServer nmsWorld, Entity nmsEntity) {
Validator.isTrue(Bukkit.isPrimaryThread(), "Async entity add");
final int chunkX = MathHelper.floor(nmsEntity.locX / 16.0);
final int chunkZ = MathHelper.floor(nmsEntity.locZ / 16.0);
if (!nmsWorld.getChunkProviderServer().isLoaded(chunkX, chunkZ)) {
// This should never happen
nmsEntity.dead = true;
return false;
}
nmsWorld.getChunkAt(chunkX, chunkZ).a(nmsEntity);
nmsWorld.entityList.add(nmsEntity);
try {
validateEntityMethod.invoke(nmsWorld, nmsEntity);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
@Override
public boolean isNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) {
return ((CraftEntity) bukkitEntity).getHandle() instanceof NMSEntityBase;
}
@Override
public NMSEntityBase getNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) {
Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle();
if (nmsEntity instanceof NMSEntityBase) {
return ((NMSEntityBase) nmsEntity);
}
return null;
}
@Override
public FancyMessage newFancyMessage(String text) {
return new FancyMessageImpl(text);
}
@Override
public boolean isUnloadUnsure(Chunk bukkitChunk) {
return bukkitChunk.getWorld().isChunkInUse(bukkitChunk.getX(), bukkitChunk.getZ()) || !((CraftChunk) bukkitChunk).getHandle().d; // Field probably representing if the chunk is scheduled to be unloaded in ChunkProviderServer
}
}

View File

@ -0,0 +1,127 @@
package com.gmail.filoghost.holographicdisplays.nms.v1_12_R1;
import net.minecraft.server.v1_12_R1.AxisAlignedBB;
import net.minecraft.server.v1_12_R1.BlockPosition;
import net.minecraft.server.v1_12_R1.MovingObjectPosition;
import net.minecraft.server.v1_12_R1.Vec3D;
public class NullBoundingBox extends AxisAlignedBB {
public NullBoundingBox() {
super(0, 0, 0, 0, 0, 0);
}
@Override
public double a() {
return 0.0;
}
@Override
public double a(AxisAlignedBB arg0, double arg1) {
return 0.0;
}
@Override
public AxisAlignedBB a(AxisAlignedBB arg0) {
return this;
}
@Override
public AxisAlignedBB a(double arg0, double arg1, double arg2) {
return this;
}
@Override
public MovingObjectPosition b(Vec3D arg0, Vec3D arg1) {
return null;
}
@Override
public double b(AxisAlignedBB arg0, double arg1) {
return 0.0;
}
@Override
public double c(AxisAlignedBB arg0, double arg1) {
return 0.0;
}
@Override
public AxisAlignedBB grow(double arg0, double arg1, double arg2) {
return this;
}
@Override
public AxisAlignedBB shrink(double arg0) {
return this;
}
@Override
public AxisAlignedBB a(BlockPosition arg0) {
return this;
}
@Override
public boolean a(double arg0, double arg1, double arg2, double arg3, double arg4, double arg5) {
return false;
}
@Override
public boolean b(Vec3D arg0) {
return false;
}
@Override
public boolean c(Vec3D arg0) {
return false;
}
@Override
public boolean d(Vec3D arg0) {
return false;
}
@Override
public AxisAlignedBB e(double arg0) {
return this;
}
@Override
public AxisAlignedBB g(double arg0) {
return this;
}
@Override
public AxisAlignedBB a(Vec3D arg0) {
return this;
}
@Override
public AxisAlignedBB b(AxisAlignedBB arg0) {
return this;
}
@Override
public AxisAlignedBB b(double arg0, double arg1, double arg2) {
return this;
}
@Override
public boolean c(AxisAlignedBB arg0) {
return false;
}
@Override
public AxisAlignedBB d(double arg0, double arg1, double arg2) {
return this;
}
@Override
public boolean e(Vec3D arg0) {
return false;
}
}

View File

@ -22,7 +22,9 @@ public class MinecraftVersion {
// Since 1.10 there is a difference in the entity metadata packet index for items.
v1_10 = new MinecraftVersion(4),
v1_11 = new MinecraftVersion(5);
v1_11 = new MinecraftVersion(5),
v1_12 = new MinecraftVersion(6);
private int value;

View File

@ -1,6 +1,6 @@
name: HolographicDisplays
main: com.gmail.filoghost.holographicdisplays.HolographicDisplays
version: 2.2.5
version: 2.2.6
softdepend: [Multiverse-Core, MultiWorld, My Worlds, My_Worlds, ProtocolLib]