Use packets instead of entities

Missing:
* All implementations before 1.17
* Placeholder toggle
* Visibility settings
* Line touch handling
* Item pickup handling
This commit is contained in:
filoghost 2021-07-24 12:51:14 +02:00
parent c22f01c017
commit 7d86538621
230 changed files with 2063 additions and 20253 deletions

View File

@ -17,7 +17,7 @@ body:
required: true
- label: "I have tested the [latest development build](https://ci.codemc.io/job/filoghost/job/HolographicDisplays) of Holographic Displays and the bug is still present."
required: true
- label: "I have updated **Spigot** (and **ProtocolLib** if installed) to the latest release for my particular Minecraft version."
- label: "I have updated **Spigot** to the latest release for my particular Minecraft version."
required: true
- label: "I made sure the bug hasn't already been reported on the [issue tracker](https://github.com/filoghost/HolographicDisplays/issues?q=is%3Aissue)."
required: true
@ -59,12 +59,6 @@ body:
validations:
required: true
- type: input
attributes:
label: "ProtocolLib version (if installed)"
description: "Output of the command `/version ProtocolLib`."
placeholder: "ProtocolLib version 4.6.0-SNAPSHOT-b476"
- type: input
attributes:
label: "Installed plugins that allow players to join with multiple Minecraft versions"

View File

@ -9,7 +9,6 @@ import me.filoghost.holographicdisplays.api.hologram.Hologram;
import me.filoghost.holographicdisplays.api.internal.HolographicDisplaysAPIProvider;
import me.filoghost.holographicdisplays.api.placeholder.PlaceholderReplacer;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull;
@ -97,15 +96,4 @@ public interface HolographicDisplaysAPI {
*/
void unregisterPlaceholders();
/**
* Checks if an entity is part of a hologram.
*
* @param entity the entity to check
* @return if the entity is part of a hologram
* @since 1
*/
static boolean isHologramEntity(@NotNull Entity entity) {
return HolographicDisplaysAPIProvider.getImplementation().isHologramEntity(entity);
}
}

View File

@ -177,8 +177,6 @@ public interface Hologram {
/**
* Returns the {@link VisibilitySettings} of this hologram.
* <br><b style = "color: red">Note</b>: the usage of the VisibilitySettings requires ProtocolLib.
* Without the plugin, holograms will be always visible.
*
* @return the VisibilitySettings of this hologram
* @since 1

View File

@ -11,8 +11,6 @@ import org.jetbrains.annotations.NotNull;
/**
* Settings to manage the visibility of a hologram to players. Allows to set both the default visibility and the
* visibility to a specific player.
* <p>
* <b>Warning</b>: changing the visibility requires ProtocolLib, otherwise methods of this class have no effect.
*
* @since 1
*/

View File

@ -6,7 +6,6 @@
package me.filoghost.holographicdisplays.api.internal;
import me.filoghost.holographicdisplays.api.HolographicDisplaysAPI;
import org.bukkit.entity.Entity;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.ApiStatus.Internal;
@ -31,6 +30,4 @@ public abstract class HolographicDisplaysAPIProvider {
public abstract HolographicDisplaysAPI getHolographicDisplaysAPI(Plugin plugin);
public abstract boolean isHologramEntity(Entity entity);
}

View File

@ -6,8 +6,6 @@
package me.filoghost.holographicdisplays.common;
import me.filoghost.fcommons.logging.Log;
import me.filoghost.holographicdisplays.common.hologram.StandardHologramLine;
import me.filoghost.holographicdisplays.common.nms.SpawnFailedException;
public class DebugLogger {
@ -48,20 +46,4 @@ public class DebugLogger {
}
}
public static void handleSpawnFail(SpawnFailedException exception, StandardHologramLine parentHologramLine) {
severe("Couldn't spawn entity for this hologram: " + parentHologramLine.getHologram(), exception);
}
public static void cannotSetPassenger(Throwable t) {
severe("Couldn't set passenger", t);
}
public static void cannotSetArmorStandAsMarker(Throwable t) {
severe("Couldn't set armor stand as marker", t);
}
public static void cannotSetPassengerPitchYawDelta(Throwable t) {
severe("Couldn't set passenger pitch/yaw delta", t);
}
}

View File

@ -5,24 +5,12 @@
*/
package me.filoghost.holographicdisplays.common.hologram;
import org.bukkit.Chunk;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import java.util.List;
public interface StandardHologram {
World getWorld();
double getX();
double getY();
double getZ();
boolean isInChunk(Chunk chunk);
public interface StandardHologram extends StandardHologramComponent {
List<? extends StandardHologramLine> getLines();
@ -32,18 +20,4 @@ public interface StandardHologram {
boolean isVisibleTo(Player player);
void refresh();
void refresh(boolean forceRespawn);
void refresh(boolean forceRespawn, boolean isChunkLoaded);
void despawnEntities();
boolean isDeleted();
void setDeleted();
String toFormattedString();
}

View File

@ -0,0 +1,28 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.common.hologram;
import org.bukkit.World;
public interface StandardHologramComponent {
World getWorld();
double getX();
double getY();
double getZ();
int getChunkX();
int getChunkZ();
boolean isDeleted();
void setDeleted();
}

View File

@ -6,20 +6,13 @@
package me.filoghost.holographicdisplays.common.hologram;
import org.bukkit.World;
import org.bukkit.entity.Player;
import java.util.Collection;
public interface StandardHologramLine {
public interface StandardHologramLine extends StandardHologramComponent {
StandardHologram getHologram();
void respawn(World world, double x, double y, double z);
void despawn();
void setLocation(World world, double x, double y, double z);
double getHeight();
void collectTrackedEntityIDs(Player player, Collection<Integer> collector);
}

View File

@ -5,16 +5,13 @@
*/
package me.filoghost.holographicdisplays.common.hologram;
import me.filoghost.holographicdisplays.common.nms.entity.NMSArmorStand;
import me.filoghost.holographicdisplays.common.nms.entity.NMSItem;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
public interface StandardItemLine extends StandardTouchableLine {
ItemStack getItemStack();
void onPickup(Player player);
NMSItem getNMSItem();
NMSArmorStand getNMSItemVehicle();
}

View File

@ -5,14 +5,10 @@
*/
package me.filoghost.holographicdisplays.common.hologram;
import me.filoghost.holographicdisplays.common.nms.entity.NMSArmorStand;
public interface StandardTextLine extends StandardTouchableLine {
String getText();
boolean isAllowPlaceholders();
NMSArmorStand getNMSArmorStand();
}

View File

@ -5,16 +5,12 @@
*/
package me.filoghost.holographicdisplays.common.hologram;
import me.filoghost.holographicdisplays.common.nms.entity.NMSArmorStand;
import me.filoghost.holographicdisplays.common.nms.entity.NMSSlime;
import org.bukkit.entity.Player;
public interface StandardTouchableLine extends StandardHologramLine {
void onTouch(Player player);
NMSSlime getNMSSlime();
NMSArmorStand getNMSSlimeVehicle();
boolean hasTouchHandler();
}

View File

@ -0,0 +1,44 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.common.nms;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
public abstract class AbstractNMSPacketList implements NMSPacketList {
// Lazily instantiate a list only when adding more than one element
private @Nullable NMSPacket singlePacket;
private @Nullable List<NMSPacket> multiplePackets;
protected void add(NMSPacket packet) {
if (multiplePackets != null) {
multiplePackets.add(packet);
} else if (singlePacket != null) {
multiplePackets = new ArrayList<>();
multiplePackets.add(singlePacket);
multiplePackets.add(packet);
singlePacket = null;
} else {
singlePacket = packet;
}
}
@Override
public void sendTo(Player player) {
if (multiplePackets != null) {
for (NMSPacket packet : multiplePackets) {
packet.sendTo(player);
}
} else if (singlePacket != null) {
singlePacket.sendTo(player);
}
}
}

View File

@ -0,0 +1,39 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.common.nms;
import org.jetbrains.annotations.Nullable;
import java.util.UUID;
import java.util.function.Supplier;
public class EntityID {
private final Supplier<Integer> numericIDGenerator;
// Lazy initialization
private @Nullable Integer numericID;
private @Nullable UUID uuid;
public EntityID(Supplier<Integer> numericIDGenerator) {
this.numericIDGenerator = numericIDGenerator;
}
public int getNumericID() {
if (numericID == null) {
numericID = numericIDGenerator.get();
}
return numericID;
}
public UUID getUUID() {
if (uuid == null) {
uuid = UUID.randomUUID();
}
return uuid;
}
}

View File

@ -0,0 +1,37 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.common.nms;
import java.util.function.Supplier;
/**
* Fallback entity ID generator that counts down from <code>Integer.MIN_VALUE / 2</code> to <code>Integer.MIN_VALUE</code>, looping over
* when reaching the end.
* <p>
* It does not start from zero to avoid conflicts with fake entities created by other plugins, and it counts down to minimize the time
* window where the real NMS counter and this one may return the same numbers.
* <p>
* The Minecraft client can disconnect if the server sends bad packets for two entities with the same ID, which may have different types.
*/
public class FallbackEntityIDGenerator implements Supplier<Integer> {
private static final int COUNTER_START_VALUE = Integer.MIN_VALUE / 2;
private static final int COUNTER_END_VALUE = Integer.MIN_VALUE;
private int counter = COUNTER_START_VALUE;
@Override
public Integer get() {
// Loop over on allowed range values
if (counter == COUNTER_END_VALUE) {
counter = COUNTER_START_VALUE;
}
counter--;
return counter;
}
}

View File

@ -0,0 +1,15 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.common.nms;
import org.bukkit.entity.Player;
@FunctionalInterface
public interface IndividualCustomName {
String get(Player player);
}

View File

@ -0,0 +1,25 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.common.nms;
import org.bukkit.entity.Player;
import java.util.function.Function;
public class IndividualNMSPacket implements NMSPacket {
private final Function<Player, NMSPacket> individualPacketFactory;
public IndividualNMSPacket(Function<Player, NMSPacket> individualPacketFactory) {
this.individualPacketFactory = individualPacketFactory;
}
@Override
public void sendTo(Player player) {
individualPacketFactory.apply(player).sendTo(player);
}
}

View File

@ -1,23 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.common.nms;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
public class NMSCommons {
/**
* Lore is used on hologram icons, to prevent vanilla items from merging with them.
*/
public static final String ANTI_STACK_LORE = ChatColor.BLACK.toString() + Math.random();
/**
* Paper contains some code changes compared to Spigot.
*/
public static final boolean IS_PAPER_SERVER = Bukkit.getName().equals("Paper");
}

View File

@ -0,0 +1,14 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.common.nms;
public class NMSErrors {
public static final String GETTING_ENTITY_ID_GENERATOR_SHORT = "Could not get the NMS entity ID generator.";
public static final String GETTING_ENTITY_ID_GENERATOR_LONG = GETTING_ENTITY_ID_GENERATOR_SHORT
+ " There is a small chance of entity ID conflicts, causing client-side issues on single entities.";
}

View File

@ -5,40 +5,10 @@
*/
package me.filoghost.holographicdisplays.common.nms;
import me.filoghost.holographicdisplays.common.hologram.StandardHologramLine;
import me.filoghost.holographicdisplays.common.hologram.StandardItemLine;
import me.filoghost.holographicdisplays.common.nms.entity.NMSArmorStand;
import me.filoghost.holographicdisplays.common.nms.entity.NMSEntity;
import me.filoghost.holographicdisplays.common.nms.entity.NMSItem;
import me.filoghost.holographicdisplays.common.nms.entity.NMSSlime;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.inventory.ItemStack;
public interface NMSManager {
/**
* Register all the custom entities of the plugin.
*
* @throws Exception if anything during the process fails
*/
void setup() throws Exception;
EntityID newEntityID();
NMSArmorStand spawnNMSArmorStand(World bukkitWorld, double x, double y, double z, StandardHologramLine parentHologramLine)
throws SpawnFailedException;
NMSItem spawnNMSItem(World bukkitWorld, double x, double y, double z, StandardItemLine parentHologramLine, ItemStack stack)
throws SpawnFailedException;
NMSSlime spawnNMSSlime(World bukkitWorld, double x, double y, double z, StandardHologramLine parentHologramLine)
throws SpawnFailedException;
boolean isNMSEntityBase(Entity bukkitEntity);
NMSEntity getNMSEntityBase(Entity bukkitEntity);
NMSEntity getNMSEntityBaseFromID(World bukkitWorld, int entityID);
Object createCustomNameNMSObject(String customName);
NMSPacketList createPacketList();
}

View File

@ -5,8 +5,10 @@
*/
package me.filoghost.holographicdisplays.common.nms;
public interface ProtocolPacketSettings {
import org.bukkit.entity.Player;
boolean sendAccurateLocationPackets();
public interface NMSPacket {
void sendTo(Player player);
}

View File

@ -0,0 +1,37 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.common.nms;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
public interface NMSPacketList {
void addArmorStandSpawnPackets(EntityID entityID, double locationX, double locationY, double locationZ);
void addArmorStandSpawnPackets(EntityID entityID, double locationX, double locationY, double locationZ, String customName);
void addArmorStandSpawnPackets(EntityID entityID, double locationX, double locationY, double locationZ, IndividualCustomName individualCustomName);
void addArmorStandNameChangePackets(EntityID entityID, String customName);
void addArmorStandNameChangePackets(EntityID entityID, IndividualCustomName individualCustomName);
void addItemSpawnPackets(EntityID entityID, double locationX, double locationY, double locationZ, ItemStack itemStack);
void addItemStackChangePackets(EntityID entityID, ItemStack itemStack);
void addSlimeSpawnPackets(EntityID entityID, double locationX, double locationY, double locationZ);
void addEntityDestroyPackets(EntityID... entityIDs);
void addTeleportPackets(EntityID entityID, double locationX, double locationY, double locationZ);
void addMountPackets(EntityID vehicleEntityID, EntityID passengerEntityID);
void sendTo(Player player);
}

View File

@ -1,22 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.common.nms;
public class SpawnFailedException extends Exception {
public static final String REGISTER_ENTITY_FAIL = "failed to register entity";
public static final String CHUNK_NOT_LOADED = "chunk was not loaded";
public static final String ADD_ENTITY_FAILED = "failed to add entity with workaround";
public SpawnFailedException(String message) {
super(message);
}
public SpawnFailedException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@ -1,24 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.common.nms.entity;
public interface NMSArmorStand extends NMSVehicle {
void setCustomNameNMS(String customName);
/**
* Returns the last custom name set.
*/
String getCustomNameStringNMS();
/**
* Returns the custom name NMS object, whose type is version-dependent (String for MC 1.12 and below, ChatComponent
* for MC 1.13+). The returned value may differ from {@link #getCustomNameStringNMS()} even if it's a string, for
* example if the custom name has been truncated before being applied.
*/
Object getCustomNameObjectNMS();
}

View File

@ -1,30 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.common.nms.entity;
import me.filoghost.holographicdisplays.common.hologram.StandardHologramLine;
import org.bukkit.entity.Player;
/**
* A custom entity that is part of a hologram.
*/
public interface NMSEntity {
StandardHologramLine getHologramLine();
void setLocationNMS(double x, double y, double z);
boolean isDeadNMS();
void killEntityNMS();
int getIdNMS();
org.bukkit.entity.Entity getBukkitEntityNMS();
boolean isTrackedBy(Player bukkitPlayer);
}

View File

@ -1,27 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.common.nms.entity;
import org.bukkit.entity.Player;
public abstract class NMSEntityHelper<T> {
private T tracker;
protected final T getTracker() {
if (tracker == null) {
// Cache it the first time it's available
tracker = getTracker0();
}
return tracker;
}
protected abstract T getTracker0();
public abstract boolean isTrackedBy(Player bukkitPlayer);
}

View File

@ -1,19 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.common.nms.entity;
import org.bukkit.inventory.ItemStack;
public interface NMSItem extends NMSEntity {
void setItemStackNMS(ItemStack stack);
/**
* Returns the item stack NMS object.
*/
Object getRawItemStack();
}

View File

@ -1,10 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.common.nms.entity;
public interface NMSSlime extends NMSEntity {
}

View File

@ -1,12 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.common.nms.entity;
public interface NMSVehicle extends NMSEntity {
void setPassengerNMS(NMSEntity passenger);
}

View File

@ -77,7 +77,7 @@ public class HolographicDisplaysAPI {
@Deprecated
public static boolean isHologramEntity(Entity bukkitEntity) {
return me.filoghost.holographicdisplays.api.HolographicDisplaysAPI.isHologramEntity(bukkitEntity);
return false;
}
}

View File

@ -1,85 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_10_R1;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_10_R1.CraftServer;
import org.bukkit.craftbukkit.v1_10_R1.entity.CraftArmorStand;
import org.bukkit.entity.Entity;
import org.bukkit.event.entity.EntityDamageEvent;
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;
import java.util.Collection;
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 ArmorStand 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 setLastDamageCause(EntityDamageEvent event) {}
@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

@ -1,56 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_10_R1;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_10_R1.CraftServer;
import org.bukkit.craftbukkit.v1_10_R1.entity.CraftItem;
import org.bukkit.entity.Entity;
import org.bukkit.event.entity.EntityDamageEvent;
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 setLastDamageCause(EntityDamageEvent event) {}
@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

@ -1,68 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_10_R1;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_10_R1.CraftServer;
import org.bukkit.craftbukkit.v1_10_R1.entity.CraftSlime;
import org.bukkit.entity.Entity;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.potion.PotionEffect;
import org.bukkit.util.Vector;
import java.util.Collection;
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 setLastDamageCause(EntityDamageEvent event) {}
@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

@ -1,260 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_10_R1;
import me.filoghost.fcommons.Preconditions;
import me.filoghost.fcommons.Strings;
import me.filoghost.fcommons.reflection.ReflectField;
import me.filoghost.holographicdisplays.common.DebugLogger;
import me.filoghost.holographicdisplays.common.hologram.StandardHologramLine;
import me.filoghost.holographicdisplays.common.nms.ProtocolPacketSettings;
import me.filoghost.holographicdisplays.common.nms.entity.NMSArmorStand;
import me.filoghost.holographicdisplays.common.nms.entity.NMSEntity;
import net.minecraft.server.v1_10_R1.AxisAlignedBB;
import net.minecraft.server.v1_10_R1.DamageSource;
import net.minecraft.server.v1_10_R1.Entity;
import net.minecraft.server.v1_10_R1.EntityArmorStand;
import net.minecraft.server.v1_10_R1.EntityHuman;
import net.minecraft.server.v1_10_R1.EnumHand;
import net.minecraft.server.v1_10_R1.EnumInteractionResult;
import net.minecraft.server.v1_10_R1.EnumItemSlot;
import net.minecraft.server.v1_10_R1.ItemStack;
import net.minecraft.server.v1_10_R1.NBTTagCompound;
import net.minecraft.server.v1_10_R1.PacketPlayOutEntityTeleport;
import net.minecraft.server.v1_10_R1.SoundEffect;
import net.minecraft.server.v1_10_R1.Vec3D;
import net.minecraft.server.v1_10_R1.World;
import org.bukkit.craftbukkit.v1_10_R1.entity.CraftEntity;
import org.bukkit.entity.Player;
import java.util.Objects;
public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorStand {
private static final ReflectField<Entity> VEHICLE_FIELD = ReflectField.lookup(Entity.class, Entity.class, "au");
private final StandardHologramLine parentHologramLine;
private final ProtocolPacketSettings protocolPacketSettings;
private final VersionNMSEntityHelper helper;
private String customName;
public EntityNMSArmorStand(World world, StandardHologramLine parentHologramLine, ProtocolPacketSettings protocolPacketSettings) {
super(world);
this.parentHologramLine = parentHologramLine;
this.protocolPacketSettings = protocolPacketSettings;
this.helper = new VersionNMSEntityHelper(this);
super.setInvisible(true);
super.setSmall(true);
super.setArms(false);
super.setNoGravity(true);
super.setBasePlate(true);
super.setMarker(true);
super.collides = false;
super.onGround = true; // Workaround to force EntityTrackerEntry to send a teleport packet
forceSetBoundingBox(new NullBoundingBox());
}
@Override
public void m() {
// Disable normal ticking for this entity
// Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity
if (super.onGround) {
super.onGround = false;
}
}
@Override
public void inactiveTick() {
// Disable normal ticking for this entity
// Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity
if (super.onGround) {
super.onGround = false;
}
}
@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 e(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) {
// Prevents changes to custom name
}
@Override
public void setCustomNameVisible(boolean visible) {
// Prevents changes to custom name visibility
}
@Override
public EnumInteractionResult a(EntityHuman human, Vec3D vec3d, ItemStack itemstack, EnumHand enumhand) {
// Prevent armor stand from being equipped
return EnumInteractionResult.PASS;
}
@Override
public boolean c(int i, ItemStack item) {
// Prevent armor stand from being equipped
return false;
}
@Override
public void setSlot(EnumItemSlot enumitemslot, ItemStack itemstack) {
// Prevent armor stand from being equipped
}
@Override
public void a(AxisAlignedBB boundingBox) {
// Prevent changes to bounding box
}
public void forceSetBoundingBox(AxisAlignedBB boundingBox) {
super.a(boundingBox);
}
@Override
public void a(SoundEffect soundeffect, float f, float f1) {
// Remove sounds
}
@Override
public void setCustomNameNMS(String customName) {
if (Objects.equals(this.customName, customName)) {
return;
}
this.customName = customName;
super.setCustomName(createCustomNameNMSObject(customName));
super.setCustomNameVisible(customName != null && !customName.isEmpty());
}
protected static String createCustomNameNMSObject(String customName) {
return customName != null ? Strings.truncate(customName, 256) : "";
}
@Override
public String getCustomNameStringNMS() {
return this.customName;
}
@Override
public String getCustomNameObjectNMS() {
return super.getCustomName();
}
@Override
public void die() {
// Prevent entity from dying
}
@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);
if (protocolPacketSettings.sendAccurateLocationPackets()) {
helper.broadcastPacket(new PacketPlayOutEntityTeleport(this));
}
}
@Override
public void setPassengerNMS(NMSEntity passenger) {
Preconditions.checkArgument(passenger instanceof Entity);
Entity passengerEntity = (Entity) passenger;
Preconditions.checkArgument(passengerEntity.bB() == null);
Preconditions.checkState(super.passengers.isEmpty());
try {
VEHICLE_FIELD.set(passenger, this);
this.passengers.add(passengerEntity);
} catch (ReflectiveOperationException e) {
DebugLogger.cannotSetPassenger(e);
}
}
@Override
public boolean isDeadNMS() {
return super.dead;
}
@Override
public int getIdNMS() {
return super.getId();
}
@Override
public StandardHologramLine getHologramLine() {
return parentHologramLine;
}
@Override
public org.bukkit.entity.Entity getBukkitEntityNMS() {
return getBukkitEntity();
}
@Override
public boolean isTrackedBy(Player bukkitPlayer) {
return helper.isTrackedBy(bukkitPlayer);
}
}

View File

@ -1,214 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_10_R1;
import me.filoghost.holographicdisplays.common.hologram.StandardHologramLine;
import me.filoghost.holographicdisplays.common.hologram.StandardItemLine;
import me.filoghost.holographicdisplays.common.nms.NMSCommons;
import me.filoghost.holographicdisplays.common.nms.entity.NMSItem;
import net.minecraft.server.v1_10_R1.Blocks;
import net.minecraft.server.v1_10_R1.DamageSource;
import net.minecraft.server.v1_10_R1.Entity;
import net.minecraft.server.v1_10_R1.EntityHuman;
import net.minecraft.server.v1_10_R1.EntityItem;
import net.minecraft.server.v1_10_R1.EntityPlayer;
import net.minecraft.server.v1_10_R1.ItemStack;
import net.minecraft.server.v1_10_R1.NBTTagCompound;
import net.minecraft.server.v1_10_R1.NBTTagList;
import net.minecraft.server.v1_10_R1.NBTTagString;
import net.minecraft.server.v1_10_R1.PacketPlayOutMount;
import net.minecraft.server.v1_10_R1.World;
import org.bukkit.craftbukkit.v1_10_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_10_R1.inventory.CraftItemStack;
import org.bukkit.entity.Player;
public class EntityNMSItem extends EntityItem implements NMSItem {
private final StandardItemLine parentHologramLine;
private final VersionNMSEntityHelper helper;
private int resendMountPacketTicks;
public EntityNMSItem(World world, StandardItemLine parentHologramLine) {
super(world);
this.parentHologramLine = parentHologramLine;
this.helper = new VersionNMSEntityHelper(this);
super.pickupDelay = Integer.MAX_VALUE;
}
@Override
public void m() {
// Disable normal ticking for this entity
// So it won't get removed
ticksLived = 0;
if (resendMountPacketTicks++ > 20) {
resendMountPacketTicks = 0;
Entity vehicle = bB();
if (vehicle != null) {
// Send a packet near to "remind" players that the item is riding the armor stand (Spigot bug or client bug)
helper.broadcastPacket(new PacketPlayOutMount(vehicle));
}
}
}
@Override
public void inactiveTick() {
// Disable normal ticking for this entity
// So it won't get removed
ticksLived = 0;
}
// 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 (human instanceof EntityPlayer) {
parentHologramLine.onPickup(((EntityPlayer) human).getBukkitEntity());
// 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 e(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 die() {
// Prevent entity from dying
}
@Override
public boolean isAlive() {
// This override prevents items from being picked up by hoppers (should have no side effects)
return false;
}
@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");
if (!newItem.getTag().hasKey("display")) {
newItem.getTag().set("display", display);
}
NBTTagList tagList = new NBTTagList();
tagList.add(new NBTTagString(NMSCommons.ANTI_STACK_LORE));
display.set("Lore", tagList);
super.setItemStack(newItem);
}
@Override
public int getIdNMS() {
return super.getId();
}
@Override
public StandardHologramLine getHologramLine() {
return parentHologramLine;
}
@Override
public org.bukkit.entity.Entity getBukkitEntityNMS() {
return getBukkitEntity();
}
@Override
public boolean isTrackedBy(Player bukkitPlayer) {
return helper.isTrackedBy(bukkitPlayer);
}
@Override
public Object getRawItemStack() {
return super.getItemStack();
}
}

View File

@ -1,204 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_10_R1;
import me.filoghost.holographicdisplays.common.hologram.StandardHologramLine;
import me.filoghost.holographicdisplays.common.nms.entity.NMSSlime;
import net.minecraft.server.v1_10_R1.AxisAlignedBB;
import net.minecraft.server.v1_10_R1.DamageSource;
import net.minecraft.server.v1_10_R1.Entity;
import net.minecraft.server.v1_10_R1.EntityDamageSource;
import net.minecraft.server.v1_10_R1.EntityPlayer;
import net.minecraft.server.v1_10_R1.EntitySlime;
import net.minecraft.server.v1_10_R1.NBTTagCompound;
import net.minecraft.server.v1_10_R1.PacketPlayOutMount;
import net.minecraft.server.v1_10_R1.SoundEffect;
import net.minecraft.server.v1_10_R1.World;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_10_R1.entity.CraftEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerInteractEntityEvent;
public class EntityNMSSlime extends EntitySlime implements NMSSlime {
private final StandardHologramLine parentHologramLine;
private final VersionNMSEntityHelper helper;
private int resendMountPacketTicks;
public EntityNMSSlime(World world, StandardHologramLine parentHologramLine) {
super(world);
this.parentHologramLine = parentHologramLine;
this.helper = new VersionNMSEntityHelper(this);
super.persistent = true;
super.collides = false;
super.a(0.0F, 0.0F);
super.setSize(1);
super.setInvisible(true);
forceSetBoundingBox(new NullBoundingBox());
}
@Override
public void m() {
// Disable normal ticking for this entity
// So it won't get removed
ticksLived = 0;
if (resendMountPacketTicks++ > 20) {
resendMountPacketTicks = 0;
Entity vehicle = bB();
if (vehicle != null) {
// Send a packet near to "remind" players that the slime is riding the armor stand (Spigot bug or client bug)
helper.broadcastPacket(new PacketPlayOutMount(vehicle));
}
}
}
@Override
public void inactiveTick() {
// Disable normal ticking for this entity
// So it won't get removed
ticksLived = 0;
}
@Override
public void a(AxisAlignedBB boundingBox) {
// Prevent changes to bounding box
}
public void forceSetBoundingBox(AxisAlignedBB boundingBox) {
super.a(boundingBox);
}
@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 e(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) {
Player player = ((EntityPlayer) entityDamageSource.getEntity()).getBukkitEntity();
PlayerInteractEntityEvent event = new PlayerInteractEntityEvent(player, getBukkitEntity());
Bukkit.getPluginManager().callEvent(event); // 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 setCustomName(String customName) {
// Prevents changes to custom name
}
@Override
public void setCustomNameVisible(boolean visible) {
// Prevents changes to custom name visibility
}
@Override
public void a(SoundEffect soundeffect, float f, float f1) {
// Remove sounds
}
@Override
public void die() {
// Prevent entity from dying
}
@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 StandardHologramLine getHologramLine() {
return parentHologramLine;
}
@Override
public org.bukkit.entity.Entity getBukkitEntityNMS() {
return getBukkitEntity();
}
@Override
public boolean isTrackedBy(Player bukkitPlayer) {
return helper.isTrackedBy(bukkitPlayer);
}
}

View File

@ -1,114 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_10_R1;
import net.minecraft.server.v1_10_R1.AxisAlignedBB;
import net.minecraft.server.v1_10_R1.BlockPosition;
import net.minecraft.server.v1_10_R1.MovingObjectPosition;
import net.minecraft.server.v1_10_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 boolean a(Vec3D arg0) {
return false;
}
@Override
public double b(AxisAlignedBB arg0, double arg1) {
return 0.0;
}
@Override
public boolean b(AxisAlignedBB arg0) {
return false;
}
@Override
public double c(AxisAlignedBB arg0, double arg1) {
return 0.0;
}
@Override
public AxisAlignedBB c(double arg0, double arg1, double arg2) {
return this;
}
@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;
}
}

View File

@ -1,46 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_10_R1;
import me.filoghost.holographicdisplays.common.nms.entity.NMSEntityHelper;
import net.minecraft.server.v1_10_R1.Entity;
import net.minecraft.server.v1_10_R1.EntityTrackerEntry;
import net.minecraft.server.v1_10_R1.Packet;
import net.minecraft.server.v1_10_R1.WorldServer;
import org.bukkit.craftbukkit.v1_10_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
public class VersionNMSEntityHelper extends NMSEntityHelper<EntityTrackerEntry> {
private final Entity entity;
public VersionNMSEntityHelper(Entity entity) {
this.entity = entity;
}
@Override
protected EntityTrackerEntry getTracker0() {
return ((WorldServer) entity.world).tracker.trackedEntities.get(entity.getId());
}
@Override
public boolean isTrackedBy(Player bukkitPlayer) {
EntityTrackerEntry tracker = getTracker();
if (tracker != null) {
return tracker.trackedPlayers.contains(((CraftPlayer) bukkitPlayer).getHandle());
} else {
return false;
}
}
public void broadcastPacket(Packet<?> packet) {
EntityTrackerEntry tracker = getTracker();
if (tracker != null) {
tracker.broadcast(packet);
}
}
}

View File

@ -5,146 +5,20 @@
*/
package me.filoghost.holographicdisplays.nms.v1_10_R1;
import me.filoghost.fcommons.Preconditions;
import me.filoghost.fcommons.reflection.ClassToken;
import me.filoghost.fcommons.reflection.ReflectField;
import me.filoghost.fcommons.reflection.ReflectMethod;
import me.filoghost.holographicdisplays.common.hologram.StandardHologramLine;
import me.filoghost.holographicdisplays.common.hologram.StandardItemLine;
import me.filoghost.holographicdisplays.common.nms.EntityID;
import me.filoghost.holographicdisplays.common.nms.NMSManager;
import me.filoghost.holographicdisplays.common.nms.ProtocolPacketSettings;
import me.filoghost.holographicdisplays.common.nms.SpawnFailedException;
import me.filoghost.holographicdisplays.common.nms.entity.NMSArmorStand;
import me.filoghost.holographicdisplays.common.nms.entity.NMSEntity;
import me.filoghost.holographicdisplays.common.nms.entity.NMSItem;
import net.minecraft.server.v1_10_R1.Entity;
import net.minecraft.server.v1_10_R1.EntityTypes;
import net.minecraft.server.v1_10_R1.MathHelper;
import net.minecraft.server.v1_10_R1.World;
import net.minecraft.server.v1_10_R1.WorldServer;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_10_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_10_R1.entity.CraftEntity;
import org.bukkit.inventory.ItemStack;
import java.util.Map;
import me.filoghost.holographicdisplays.common.nms.NMSPacketList;
public class VersionNMSManager implements NMSManager {
private static final ReflectField<Map<Class<?>, String>> ENTITY_NAMES_BY_CLASS_FIELD
= ReflectField.lookup(new ClassToken<Map<Class<?>, String>>() {}, EntityTypes.class, "d");
private static final ReflectField<Map<Class<?>, Integer>> ENTITY_IDS_BY_CLASS_FIELD
= ReflectField.lookup(new ClassToken<Map<Class<?>, Integer>>() {}, EntityTypes.class, "f");
private static final ReflectMethod<?> REGISTER_ENTITY_METHOD = ReflectMethod.lookup(Object.class, World.class, "b", Entity.class);
private final ProtocolPacketSettings protocolPacketSettings;
public VersionNMSManager(ProtocolPacketSettings protocolPacketSettings) {
this.protocolPacketSettings = protocolPacketSettings;
@Override
public EntityID newEntityID() {
return null;
}
@Override
public void setup() throws Exception {
registerCustomEntity(EntityNMSArmorStand.class, "ArmorStand", 30);
registerCustomEntity(EntityNMSItem.class, "Item", 1);
registerCustomEntity(EntityNMSSlime.class, "Slime", 55);
}
public void registerCustomEntity(Class<?> entityClass, String name, int id) throws Exception {
ENTITY_NAMES_BY_CLASS_FIELD.getStatic().put(entityClass, name);
ENTITY_IDS_BY_CLASS_FIELD.getStatic().put(entityClass, id);
}
@Override
public NMSItem spawnNMSItem(
org.bukkit.World bukkitWorld, double x, double y, double z,
StandardItemLine parentHologramLine,
ItemStack stack) throws SpawnFailedException {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
EntityNMSItem item = new EntityNMSItem(nmsWorld, parentHologramLine);
item.setLocationNMS(x, y, z);
item.setItemStackNMS(stack);
addEntityToWorld(nmsWorld, item);
return item;
}
@Override
public EntityNMSSlime spawnNMSSlime(
org.bukkit.World bukkitWorld, double x, double y, double z,
StandardHologramLine parentHologramLine) throws SpawnFailedException {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
EntityNMSSlime slime = new EntityNMSSlime(nmsWorld, parentHologramLine);
slime.setLocationNMS(x, y, z);
addEntityToWorld(nmsWorld, slime);
return slime;
}
@Override
public NMSArmorStand spawnNMSArmorStand(
org.bukkit.World world, double x, double y, double z,
StandardHologramLine parentHologramLine) throws SpawnFailedException {
WorldServer nmsWorld = ((CraftWorld) world).getHandle();
EntityNMSArmorStand armorStand = new EntityNMSArmorStand(nmsWorld, parentHologramLine, protocolPacketSettings);
armorStand.setLocationNMS(x, y, z);
addEntityToWorld(nmsWorld, armorStand);
return armorStand;
}
private void addEntityToWorld(WorldServer nmsWorld, Entity nmsEntity) throws SpawnFailedException {
Preconditions.checkState(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;
throw new SpawnFailedException(SpawnFailedException.CHUNK_NOT_LOADED);
}
nmsWorld.getChunkAt(chunkX, chunkZ).a(nmsEntity);
nmsWorld.entityList.add(nmsEntity);
try {
REGISTER_ENTITY_METHOD.invoke(nmsWorld, nmsEntity);
} catch (ReflectiveOperationException e) {
nmsEntity.dead = true;
throw new SpawnFailedException(SpawnFailedException.REGISTER_ENTITY_FAIL, e);
}
}
@Override
public boolean isNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) {
return ((CraftEntity) bukkitEntity).getHandle() instanceof NMSEntity;
}
@Override
public NMSEntity getNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) {
Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle();
if (nmsEntity instanceof NMSEntity) {
return (NMSEntity) nmsEntity;
} else {
return null;
}
}
@Override
public NMSEntity getNMSEntityBaseFromID(org.bukkit.World bukkitWorld, int entityID) {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
Entity nmsEntity = nmsWorld.getEntity(entityID);
if (nmsEntity instanceof NMSEntity) {
return (NMSEntity) nmsEntity;
} else {
return null;
}
}
@Override
public Object createCustomNameNMSObject(String customName) {
return EntityNMSArmorStand.createCustomNameNMSObject(customName);
public NMSPacketList createPacketList() {
return null;
}
}

View File

@ -1,85 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_11_R1;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_11_R1.CraftServer;
import org.bukkit.craftbukkit.v1_11_R1.entity.CraftArmorStand;
import org.bukkit.entity.Entity;
import org.bukkit.event.entity.EntityDamageEvent;
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;
import java.util.Collection;
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 ArmorStand 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 setLastDamageCause(EntityDamageEvent event) {}
@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

@ -1,56 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_11_R1;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_11_R1.CraftServer;
import org.bukkit.craftbukkit.v1_11_R1.entity.CraftItem;
import org.bukkit.entity.Entity;
import org.bukkit.event.entity.EntityDamageEvent;
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 setLastDamageCause(EntityDamageEvent event) {}
@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

@ -1,68 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_11_R1;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_11_R1.CraftServer;
import org.bukkit.craftbukkit.v1_11_R1.entity.CraftSlime;
import org.bukkit.entity.Entity;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.potion.PotionEffect;
import org.bukkit.util.Vector;
import java.util.Collection;
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 setLastDamageCause(EntityDamageEvent event) {}
@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

@ -1,260 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_11_R1;
import me.filoghost.fcommons.Preconditions;
import me.filoghost.fcommons.Strings;
import me.filoghost.fcommons.reflection.ReflectField;
import me.filoghost.holographicdisplays.common.DebugLogger;
import me.filoghost.holographicdisplays.common.hologram.StandardHologramLine;
import me.filoghost.holographicdisplays.common.nms.ProtocolPacketSettings;
import me.filoghost.holographicdisplays.common.nms.entity.NMSArmorStand;
import me.filoghost.holographicdisplays.common.nms.entity.NMSEntity;
import net.minecraft.server.v1_11_R1.AxisAlignedBB;
import net.minecraft.server.v1_11_R1.DamageSource;
import net.minecraft.server.v1_11_R1.Entity;
import net.minecraft.server.v1_11_R1.EntityArmorStand;
import net.minecraft.server.v1_11_R1.EntityHuman;
import net.minecraft.server.v1_11_R1.EnumHand;
import net.minecraft.server.v1_11_R1.EnumInteractionResult;
import net.minecraft.server.v1_11_R1.EnumItemSlot;
import net.minecraft.server.v1_11_R1.ItemStack;
import net.minecraft.server.v1_11_R1.NBTTagCompound;
import net.minecraft.server.v1_11_R1.PacketPlayOutEntityTeleport;
import net.minecraft.server.v1_11_R1.SoundEffect;
import net.minecraft.server.v1_11_R1.Vec3D;
import net.minecraft.server.v1_11_R1.World;
import org.bukkit.craftbukkit.v1_11_R1.entity.CraftEntity;
import org.bukkit.entity.Player;
import java.util.Objects;
public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorStand {
private static final ReflectField<Entity> VEHICLE_FIELD = ReflectField.lookup(Entity.class, Entity.class, "au");
private final StandardHologramLine parentHologramLine;
private final ProtocolPacketSettings protocolPacketSettings;
private final VersionNMSEntityHelper helper;
private String customName;
public EntityNMSArmorStand(World world, StandardHologramLine parentHologramLine, ProtocolPacketSettings protocolPacketSettings) {
super(world);
this.parentHologramLine = parentHologramLine;
this.protocolPacketSettings = protocolPacketSettings;
this.helper = new VersionNMSEntityHelper(this);
super.setInvisible(true);
super.setSmall(true);
super.setArms(false);
super.setNoGravity(true);
super.setBasePlate(true);
super.setMarker(true);
super.collides = false;
super.onGround = true; // Workaround to force EntityTrackerEntry to send a teleport packet
forceSetBoundingBox(new NullBoundingBox());
}
@Override
public void A_() {
// Disable normal ticking for this entity
// Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity
if (super.onGround) {
super.onGround = false;
}
}
@Override
public void inactiveTick() {
// Disable normal ticking for this entity
// Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity
if (super.onGround) {
super.onGround = false;
}
}
@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 e(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) {
// Prevents changes to custom name
}
@Override
public void setCustomNameVisible(boolean visible) {
// Prevents changes to custom name visibility
}
@Override
public EnumInteractionResult a(EntityHuman human, Vec3D vec3d, EnumHand enumhand) {
// Prevent armor stand from being equipped
return EnumInteractionResult.PASS;
}
@Override
public boolean c(int i, ItemStack item) {
// Prevent armor stand from being equipped
return false;
}
@Override
public void setSlot(EnumItemSlot enumitemslot, ItemStack itemstack) {
// Prevent armor stand from being equipped
}
@Override
public void a(AxisAlignedBB boundingBox) {
// Prevent changes to bounding box
}
public void forceSetBoundingBox(AxisAlignedBB boundingBox) {
super.a(boundingBox);
}
@Override
public void a(SoundEffect soundeffect, float f, float f1) {
// Remove sounds
}
@Override
public void setCustomNameNMS(String customName) {
if (Objects.equals(this.customName, customName)) {
return;
}
this.customName = customName;
super.setCustomName(createCustomNameNMSObject(customName));
super.setCustomNameVisible(customName != null && !customName.isEmpty());
}
protected static String createCustomNameNMSObject(String customName) {
return customName != null ? Strings.truncate(customName, 256) : "";
}
@Override
public String getCustomNameStringNMS() {
return this.customName;
}
@Override
public String getCustomNameObjectNMS() {
return super.getCustomName();
}
@Override
public void die() {
// Prevent entity from dying
}
@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);
if (protocolPacketSettings.sendAccurateLocationPackets()) {
helper.broadcastPacket(new PacketPlayOutEntityTeleport(this));
}
}
@Override
public void setPassengerNMS(NMSEntity passenger) {
Preconditions.checkArgument(passenger instanceof Entity);
Entity passengerEntity = (Entity) passenger;
Preconditions.checkArgument(passengerEntity.bB() == null);
Preconditions.checkState(super.passengers.isEmpty());
try {
VEHICLE_FIELD.set(passenger, this);
this.passengers.add(passengerEntity);
} catch (ReflectiveOperationException e) {
DebugLogger.cannotSetPassenger(e);
}
}
@Override
public boolean isDeadNMS() {
return super.dead;
}
@Override
public int getIdNMS() {
return super.getId();
}
@Override
public StandardHologramLine getHologramLine() {
return parentHologramLine;
}
@Override
public org.bukkit.entity.Entity getBukkitEntityNMS() {
return getBukkitEntity();
}
@Override
public boolean isTrackedBy(Player bukkitPlayer) {
return helper.isTrackedBy(bukkitPlayer);
}
}

View File

@ -1,199 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_11_R1;
import me.filoghost.holographicdisplays.common.hologram.StandardHologramLine;
import me.filoghost.holographicdisplays.common.hologram.StandardItemLine;
import me.filoghost.holographicdisplays.common.nms.NMSCommons;
import me.filoghost.holographicdisplays.common.nms.entity.NMSItem;
import net.minecraft.server.v1_11_R1.Blocks;
import net.minecraft.server.v1_11_R1.DamageSource;
import net.minecraft.server.v1_11_R1.EntityHuman;
import net.minecraft.server.v1_11_R1.EntityItem;
import net.minecraft.server.v1_11_R1.EntityPlayer;
import net.minecraft.server.v1_11_R1.ItemStack;
import net.minecraft.server.v1_11_R1.NBTTagCompound;
import net.minecraft.server.v1_11_R1.NBTTagList;
import net.minecraft.server.v1_11_R1.NBTTagString;
import net.minecraft.server.v1_11_R1.World;
import org.bukkit.craftbukkit.v1_11_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_11_R1.inventory.CraftItemStack;
import org.bukkit.entity.Player;
public class EntityNMSItem extends EntityItem implements NMSItem {
private final StandardItemLine parentHologramLine;
private final VersionNMSEntityHelper helper;
public EntityNMSItem(World world, StandardItemLine parentHologramLine) {
super(world);
this.parentHologramLine = parentHologramLine;
this.helper = new VersionNMSEntityHelper(this);
super.pickupDelay = 32767; // Lock the item pickup delay, also prevents entities from picking up the item
}
@Override
public void A_() {
// Disable normal ticking for this entity
// So it won't get removed
ticksLived = 0;
}
@Override
public void inactiveTick() {
// Disable normal ticking for this entity
// So it won't get removed
ticksLived = 0;
}
// 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 (human instanceof EntityPlayer) {
parentHologramLine.onPickup(((EntityPlayer) human).getBukkitEntity());
// 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 e(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 die() {
// Prevent entity from dying
}
@Override
public boolean isAlive() {
// This override prevents items from being picked up by hoppers (should have no side effects)
return false;
}
@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 == ItemStack.a) { // ItemStack.a is returned if the stack is not valid
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(NMSCommons.ANTI_STACK_LORE));
display.set("Lore", tagList);
super.setItemStack(newItem);
}
@Override
public int getIdNMS() {
return super.getId();
}
@Override
public StandardHologramLine getHologramLine() {
return parentHologramLine;
}
@Override
public org.bukkit.entity.Entity getBukkitEntityNMS() {
return getBukkitEntity();
}
@Override
public boolean isTrackedBy(Player bukkitPlayer) {
return helper.isTrackedBy(bukkitPlayer);
}
@Override
public Object getRawItemStack() {
return super.getItemStack();
}
}

View File

@ -1,190 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_11_R1;
import me.filoghost.holographicdisplays.common.hologram.StandardHologramLine;
import me.filoghost.holographicdisplays.common.nms.entity.NMSSlime;
import net.minecraft.server.v1_11_R1.AxisAlignedBB;
import net.minecraft.server.v1_11_R1.DamageSource;
import net.minecraft.server.v1_11_R1.EntityDamageSource;
import net.minecraft.server.v1_11_R1.EntityPlayer;
import net.minecraft.server.v1_11_R1.EntitySlime;
import net.minecraft.server.v1_11_R1.NBTTagCompound;
import net.minecraft.server.v1_11_R1.SoundEffect;
import net.minecraft.server.v1_11_R1.World;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_11_R1.entity.CraftEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerInteractEntityEvent;
public class EntityNMSSlime extends EntitySlime implements NMSSlime {
private final StandardHologramLine parentHologramLine;
private final VersionNMSEntityHelper helper;
public EntityNMSSlime(World world, StandardHologramLine parentHologramLine) {
super(world);
this.parentHologramLine = parentHologramLine;
this.helper = new VersionNMSEntityHelper(this);
super.persistent = true;
super.collides = false;
super.a(0.0F, 0.0F);
super.setSize(1, false);
super.setInvisible(true);
forceSetBoundingBox(new NullBoundingBox());
}
@Override
public void A_() {
// Disable normal ticking for this entity
// So it won't get removed
ticksLived = 0;
}
@Override
public void inactiveTick() {
// Disable normal ticking for this entity
// So it won't get removed
ticksLived = 0;
}
@Override
public void a(AxisAlignedBB boundingBox) {
// Prevent changes to bounding box
}
public void forceSetBoundingBox(AxisAlignedBB boundingBox) {
super.a(boundingBox);
}
@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 e(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) {
Player player = ((EntityPlayer) entityDamageSource.getEntity()).getBukkitEntity();
PlayerInteractEntityEvent event = new PlayerInteractEntityEvent(player, getBukkitEntity());
Bukkit.getPluginManager().callEvent(event); // 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 setCustomName(String customName) {
// Prevents changes to custom name
}
@Override
public void setCustomNameVisible(boolean visible) {
// Prevents changes to custom name visibility
}
@Override
public void a(SoundEffect soundeffect, float f, float f1) {
// Remove sounds
}
@Override
public void die() {
// Prevent entity from dying
}
@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 StandardHologramLine getHologramLine() {
return parentHologramLine;
}
@Override
public org.bukkit.entity.Entity getBukkitEntityNMS() {
return getBukkitEntity();
}
@Override
public boolean isTrackedBy(Player bukkitPlayer) {
return helper.isTrackedBy(bukkitPlayer);
}
}

View File

@ -1,129 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_11_R1;
import net.minecraft.server.v1_11_R1.AxisAlignedBB;
import net.minecraft.server.v1_11_R1.BlockPosition;
import net.minecraft.server.v1_11_R1.MovingObjectPosition;
import net.minecraft.server.v1_11_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

@ -1,46 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_11_R1;
import me.filoghost.holographicdisplays.common.nms.entity.NMSEntityHelper;
import net.minecraft.server.v1_11_R1.Entity;
import net.minecraft.server.v1_11_R1.EntityTrackerEntry;
import net.minecraft.server.v1_11_R1.Packet;
import net.minecraft.server.v1_11_R1.WorldServer;
import org.bukkit.craftbukkit.v1_11_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
public class VersionNMSEntityHelper extends NMSEntityHelper<EntityTrackerEntry> {
private final Entity entity;
public VersionNMSEntityHelper(Entity entity) {
this.entity = entity;
}
@Override
protected EntityTrackerEntry getTracker0() {
return ((WorldServer) entity.world).tracker.trackedEntities.get(entity.getId());
}
@Override
public boolean isTrackedBy(Player bukkitPlayer) {
EntityTrackerEntry tracker = getTracker();
if (tracker != null) {
return tracker.trackedPlayers.contains(((CraftPlayer) bukkitPlayer).getHandle());
} else {
return false;
}
}
public void broadcastPacket(Packet<?> packet) {
EntityTrackerEntry tracker = getTracker();
if (tracker != null) {
tracker.broadcast(packet);
}
}
}

View File

@ -5,154 +5,20 @@
*/
package me.filoghost.holographicdisplays.nms.v1_11_R1;
import me.filoghost.fcommons.Preconditions;
import me.filoghost.fcommons.reflection.ClassToken;
import me.filoghost.fcommons.reflection.ReflectField;
import me.filoghost.fcommons.reflection.ReflectMethod;
import me.filoghost.holographicdisplays.common.hologram.StandardHologramLine;
import me.filoghost.holographicdisplays.common.hologram.StandardItemLine;
import me.filoghost.holographicdisplays.common.nms.EntityID;
import me.filoghost.holographicdisplays.common.nms.NMSManager;
import me.filoghost.holographicdisplays.common.nms.ProtocolPacketSettings;
import me.filoghost.holographicdisplays.common.nms.SpawnFailedException;
import me.filoghost.holographicdisplays.common.nms.entity.NMSArmorStand;
import me.filoghost.holographicdisplays.common.nms.entity.NMSEntity;
import me.filoghost.holographicdisplays.common.nms.entity.NMSItem;
import net.minecraft.server.v1_11_R1.Entity;
import net.minecraft.server.v1_11_R1.EntityTypes;
import net.minecraft.server.v1_11_R1.MathHelper;
import net.minecraft.server.v1_11_R1.RegistryID;
import net.minecraft.server.v1_11_R1.RegistryMaterials;
import net.minecraft.server.v1_11_R1.World;
import net.minecraft.server.v1_11_R1.WorldServer;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_11_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_11_R1.entity.CraftEntity;
import org.bukkit.inventory.ItemStack;
import me.filoghost.holographicdisplays.common.nms.NMSPacketList;
public class VersionNMSManager implements NMSManager {
private static final ReflectField<RegistryID<Class<? extends Entity>>> REGISTRY_ID_FIELD
= ReflectField.lookup(new ClassToken<RegistryID<Class<? extends Entity>>>() {}, RegistryMaterials.class, "a");
private static final ReflectField<Object[]> ID_TO_CLASS_MAP_FIELD
= ReflectField.lookup(Object[].class, RegistryID.class, "d");
private static final ReflectMethod<?> REGISTER_ENTITY_METHOD = ReflectMethod.lookup(Object.class, World.class, "b", Entity.class);
private final ProtocolPacketSettings protocolPacketSettings;
public VersionNMSManager(ProtocolPacketSettings protocolPacketSettings) {
this.protocolPacketSettings = protocolPacketSettings;
@Override
public EntityID newEntityID() {
return null;
}
@Override
public void setup() throws Exception {
registerCustomEntity(EntityNMSSlime.class, 55);
}
public void registerCustomEntity(Class<? extends Entity> entityClass, int id) throws Exception {
// Use reflection to get the RegistryID of entities
RegistryID<Class<? extends Entity>> registryID = REGISTRY_ID_FIELD.get(EntityTypes.b);
Object[] idToClassMap = ID_TO_CLASS_MAP_FIELD.get(registryID);
// 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 NMSItem spawnNMSItem(
org.bukkit.World bukkitWorld, double x, double y, double z,
StandardItemLine parentHologramLine,
ItemStack stack) throws SpawnFailedException {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
EntityNMSItem item = new EntityNMSItem(nmsWorld, parentHologramLine);
item.setLocationNMS(x, y, z);
item.setItemStackNMS(stack);
addEntityToWorld(nmsWorld, item);
return item;
}
@Override
public EntityNMSSlime spawnNMSSlime(
org.bukkit.World bukkitWorld, double x, double y, double z,
StandardHologramLine parentHologramLine) throws SpawnFailedException {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
EntityNMSSlime slime = new EntityNMSSlime(nmsWorld, parentHologramLine);
slime.setLocationNMS(x, y, z);
addEntityToWorld(nmsWorld, slime);
return slime;
}
@Override
public NMSArmorStand spawnNMSArmorStand(
org.bukkit.World world, double x, double y, double z,
StandardHologramLine parentHologramLine) throws SpawnFailedException {
WorldServer nmsWorld = ((CraftWorld) world).getHandle();
EntityNMSArmorStand armorStand = new EntityNMSArmorStand(nmsWorld, parentHologramLine, protocolPacketSettings);
armorStand.setLocationNMS(x, y, z);
addEntityToWorld(nmsWorld, armorStand);
return armorStand;
}
private void addEntityToWorld(WorldServer nmsWorld, Entity nmsEntity) throws SpawnFailedException {
Preconditions.checkState(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;
throw new SpawnFailedException(SpawnFailedException.CHUNK_NOT_LOADED);
}
nmsWorld.getChunkAt(chunkX, chunkZ).a(nmsEntity);
nmsWorld.entityList.add(nmsEntity);
try {
REGISTER_ENTITY_METHOD.invoke(nmsWorld, nmsEntity);
} catch (ReflectiveOperationException e) {
nmsEntity.dead = true;
throw new SpawnFailedException(SpawnFailedException.REGISTER_ENTITY_FAIL, e);
}
}
@Override
public boolean isNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) {
return ((CraftEntity) bukkitEntity).getHandle() instanceof NMSEntity;
}
@Override
public NMSEntity getNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) {
Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle();
if (nmsEntity instanceof NMSEntity) {
return (NMSEntity) nmsEntity;
} else {
return null;
}
}
@Override
public NMSEntity getNMSEntityBaseFromID(org.bukkit.World bukkitWorld, int entityID) {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
Entity nmsEntity = nmsWorld.getEntity(entityID);
if (nmsEntity instanceof NMSEntity) {
return (NMSEntity) nmsEntity;
} else {
return null;
}
}
@Override
public Object createCustomNameNMSObject(String customName) {
return EntityNMSArmorStand.createCustomNameNMSObject(customName);
public NMSPacketList createPacketList() {
return null;
}
}

View File

@ -1,86 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.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.CraftArmorStand;
import org.bukkit.entity.Entity;
import org.bukkit.event.entity.EntityDamageEvent;
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;
import java.util.Collection;
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 ArmorStand 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 setLastDamageCause(EntityDamageEvent event) {}
@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

@ -1,56 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.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.entity.EntityDamageEvent;
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 setLastDamageCause(EntityDamageEvent event) {}
@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

@ -1,68 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.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.CraftSlime;
import org.bukkit.entity.Entity;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.potion.PotionEffect;
import org.bukkit.util.Vector;
import java.util.Collection;
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 setLastDamageCause(EntityDamageEvent event) {}
@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

@ -1,260 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_12_R1;
import me.filoghost.fcommons.Preconditions;
import me.filoghost.fcommons.Strings;
import me.filoghost.fcommons.reflection.ReflectField;
import me.filoghost.holographicdisplays.common.DebugLogger;
import me.filoghost.holographicdisplays.common.hologram.StandardHologramLine;
import me.filoghost.holographicdisplays.common.nms.ProtocolPacketSettings;
import me.filoghost.holographicdisplays.common.nms.entity.NMSArmorStand;
import me.filoghost.holographicdisplays.common.nms.entity.NMSEntity;
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.EntityArmorStand;
import net.minecraft.server.v1_12_R1.EntityHuman;
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;
import org.bukkit.craftbukkit.v1_12_R1.entity.CraftEntity;
import org.bukkit.entity.Player;
import java.util.Objects;
public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorStand {
private static final ReflectField<Entity> VEHICLE_FIELD = ReflectField.lookup(Entity.class, Entity.class, "au");
private final StandardHologramLine parentHologramLine;
private final ProtocolPacketSettings protocolPacketSettings;
private final VersionNMSEntityHelper helper;
private String customName;
public EntityNMSArmorStand(World world, StandardHologramLine parentHologramLine, ProtocolPacketSettings protocolPacketSettings) {
super(world);
this.parentHologramLine = parentHologramLine;
this.protocolPacketSettings = protocolPacketSettings;
this.helper = new VersionNMSEntityHelper(this);
super.setInvisible(true);
super.setSmall(true);
super.setArms(false);
super.setNoGravity(true);
super.setBasePlate(true);
super.setMarker(true);
super.collides = false;
super.onGround = true; // Workaround to force EntityTrackerEntry to send a teleport packet
forceSetBoundingBox(new NullBoundingBox());
}
@Override
public void B_() {
// Disable normal ticking for this entity
// Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity
if (super.onGround) {
super.onGround = false;
}
}
@Override
public void inactiveTick() {
// Disable normal ticking for this entity
// Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity
if (super.onGround) {
super.onGround = false;
}
}
@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) {
// Prevents changes to custom name
}
@Override
public void setCustomNameVisible(boolean visible) {
// Prevents changes to custom name visibility
}
@Override
public EnumInteractionResult a(EntityHuman human, Vec3D vec3d, EnumHand enumhand) {
// Prevent armor stand from being equipped
return EnumInteractionResult.PASS;
}
@Override
public boolean c(int i, ItemStack item) {
// Prevent armor stand from being equipped
return false;
}
@Override
public void setSlot(EnumItemSlot enumitemslot, ItemStack itemstack) {
// Prevent armor stand from being equipped
}
@Override
public void a(AxisAlignedBB boundingBox) {
// Prevent changes to bounding box
}
public void forceSetBoundingBox(AxisAlignedBB boundingBox) {
super.a(boundingBox);
}
@Override
public void a(SoundEffect soundeffect, float f, float f1) {
// Remove sounds
}
@Override
public void setCustomNameNMS(String customName) {
if (Objects.equals(this.customName, customName)) {
return;
}
this.customName = customName;
super.setCustomName(createCustomNameNMSObject(customName));
super.setCustomNameVisible(customName != null && !customName.isEmpty());
}
protected static String createCustomNameNMSObject(String customName) {
return customName != null ? Strings.truncate(customName, 256) : "";
}
@Override
public String getCustomNameStringNMS() {
return this.customName;
}
@Override
public String getCustomNameObjectNMS() {
return super.getCustomName();
}
@Override
public void die() {
// Prevent entity from dying
}
@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);
if (protocolPacketSettings.sendAccurateLocationPackets()) {
helper.broadcastPacket(new PacketPlayOutEntityTeleport(this));
}
}
@Override
public void setPassengerNMS(NMSEntity passenger) {
Preconditions.checkArgument(passenger instanceof Entity);
Entity passengerEntity = (Entity) passenger;
Preconditions.checkArgument(passengerEntity.bJ() == null);
Preconditions.checkState(super.passengers.isEmpty());
try {
VEHICLE_FIELD.set(passenger, this);
this.passengers.add(passengerEntity);
} catch (ReflectiveOperationException e) {
DebugLogger.cannotSetPassenger(e);
}
}
@Override
public boolean isDeadNMS() {
return super.dead;
}
@Override
public int getIdNMS() {
return super.getId();
}
@Override
public StandardHologramLine getHologramLine() {
return parentHologramLine;
}
@Override
public org.bukkit.entity.Entity getBukkitEntityNMS() {
return getBukkitEntity();
}
@Override
public boolean isTrackedBy(Player bukkitPlayer) {
return helper.isTrackedBy(bukkitPlayer);
}
}

View File

@ -1,199 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_12_R1;
import me.filoghost.holographicdisplays.common.hologram.StandardHologramLine;
import me.filoghost.holographicdisplays.common.hologram.StandardItemLine;
import me.filoghost.holographicdisplays.common.nms.NMSCommons;
import me.filoghost.holographicdisplays.common.nms.entity.NMSItem;
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;
public class EntityNMSItem extends EntityItem implements NMSItem {
private final StandardItemLine parentHologramLine;
private final VersionNMSEntityHelper helper;
public EntityNMSItem(World world, StandardItemLine parentHologramLine) {
super(world);
this.parentHologramLine = parentHologramLine;
this.helper = new VersionNMSEntityHelper(this);
super.pickupDelay = 32767; // Lock the item pickup delay, also prevents entities from picking up the item
}
@Override
public void B_() {
// Disable normal ticking for this entity
// So it won't get removed
ticksLived = 0;
}
@Override
public void inactiveTick() {
// Disable normal ticking for this entity
// So it won't get removed
ticksLived = 0;
}
// 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 (human instanceof EntityPlayer) {
parentHologramLine.onPickup(((EntityPlayer) human).getBukkitEntity());
// 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 die() {
// Prevent entity from dying
}
@Override
public boolean isAlive() {
// This override prevents items from being picked up by hoppers (should have no side effects)
return false;
}
@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 == ItemStack.a) { // ItemStack.a is returned if the stack is not valid
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(NMSCommons.ANTI_STACK_LORE));
display.set("Lore", tagList);
super.setItemStack(newItem);
}
@Override
public int getIdNMS() {
return super.getId();
}
@Override
public StandardHologramLine getHologramLine() {
return parentHologramLine;
}
@Override
public org.bukkit.entity.Entity getBukkitEntityNMS() {
return getBukkitEntity();
}
@Override
public boolean isTrackedBy(Player bukkitPlayer) {
return helper.isTrackedBy(bukkitPlayer);
}
@Override
public Object getRawItemStack() {
return super.getItemStack();
}
}

View File

@ -1,190 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_12_R1;
import me.filoghost.holographicdisplays.common.hologram.StandardHologramLine;
import me.filoghost.holographicdisplays.common.nms.entity.NMSSlime;
import net.minecraft.server.v1_12_R1.AxisAlignedBB;
import net.minecraft.server.v1_12_R1.DamageSource;
import net.minecraft.server.v1_12_R1.EntityDamageSource;
import net.minecraft.server.v1_12_R1.EntityPlayer;
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.entity.Player;
import org.bukkit.event.player.PlayerInteractEntityEvent;
public class EntityNMSSlime extends EntitySlime implements NMSSlime {
private final StandardHologramLine parentHologramLine;
private final VersionNMSEntityHelper helper;
public EntityNMSSlime(World world, StandardHologramLine parentHologramLine) {
super(world);
this.parentHologramLine = parentHologramLine;
this.helper = new VersionNMSEntityHelper(this);
super.persistent = true;
super.collides = false;
super.a(0.0F, 0.0F);
super.setSize(1, false);
super.setInvisible(true);
forceSetBoundingBox(new NullBoundingBox());
}
@Override
public void B_() {
// Disable normal ticking for this entity
// So it won't get removed
ticksLived = 0;
}
@Override
public void inactiveTick() {
// Disable normal ticking for this entity
// So it won't get removed
ticksLived = 0;
}
@Override
public void a(AxisAlignedBB boundingBox) {
// Prevent changes to bounding box
}
public void forceSetBoundingBox(AxisAlignedBB boundingBox) {
super.a(boundingBox);
}
@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) {
Player player = ((EntityPlayer) entityDamageSource.getEntity()).getBukkitEntity();
PlayerInteractEntityEvent event = new PlayerInteractEntityEvent(player, getBukkitEntity());
Bukkit.getPluginManager().callEvent(event); // 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 setCustomName(String customName) {
// Prevents changes to custom name
}
@Override
public void setCustomNameVisible(boolean visible) {
// Prevents changes to custom name visibility
}
@Override
public void a(SoundEffect soundeffect, float f, float f1) {
// Remove sounds
}
@Override
public void die() {
// Prevent entity from dying
}
@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 StandardHologramLine getHologramLine() {
return parentHologramLine;
}
@Override
public org.bukkit.entity.Entity getBukkitEntityNMS() {
return getBukkitEntity();
}
@Override
public boolean isTrackedBy(Player bukkitPlayer) {
return helper.isTrackedBy(bukkitPlayer);
}
}

View File

@ -1,129 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.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

@ -1,46 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_12_R1;
import me.filoghost.holographicdisplays.common.nms.entity.NMSEntityHelper;
import net.minecraft.server.v1_12_R1.Entity;
import net.minecraft.server.v1_12_R1.EntityTrackerEntry;
import net.minecraft.server.v1_12_R1.Packet;
import net.minecraft.server.v1_12_R1.WorldServer;
import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
public class VersionNMSEntityHelper extends NMSEntityHelper<EntityTrackerEntry> {
private final Entity entity;
public VersionNMSEntityHelper(Entity entity) {
this.entity = entity;
}
@Override
protected EntityTrackerEntry getTracker0() {
return ((WorldServer) entity.world).tracker.trackedEntities.get(entity.getId());
}
@Override
public boolean isTrackedBy(Player bukkitPlayer) {
EntityTrackerEntry tracker = getTracker();
if (tracker != null) {
return tracker.trackedPlayers.contains(((CraftPlayer) bukkitPlayer).getHandle());
} else {
return false;
}
}
public void broadcastPacket(Packet<?> packet) {
EntityTrackerEntry tracker = getTracker();
if (tracker != null) {
tracker.broadcast(packet);
}
}
}

View File

@ -5,154 +5,20 @@
*/
package me.filoghost.holographicdisplays.nms.v1_12_R1;
import me.filoghost.fcommons.Preconditions;
import me.filoghost.fcommons.reflection.ClassToken;
import me.filoghost.fcommons.reflection.ReflectField;
import me.filoghost.fcommons.reflection.ReflectMethod;
import me.filoghost.holographicdisplays.common.hologram.StandardHologramLine;
import me.filoghost.holographicdisplays.common.hologram.StandardItemLine;
import me.filoghost.holographicdisplays.common.nms.EntityID;
import me.filoghost.holographicdisplays.common.nms.NMSManager;
import me.filoghost.holographicdisplays.common.nms.ProtocolPacketSettings;
import me.filoghost.holographicdisplays.common.nms.SpawnFailedException;
import me.filoghost.holographicdisplays.common.nms.entity.NMSArmorStand;
import me.filoghost.holographicdisplays.common.nms.entity.NMSEntity;
import me.filoghost.holographicdisplays.common.nms.entity.NMSItem;
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;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_12_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_12_R1.entity.CraftEntity;
import org.bukkit.inventory.ItemStack;
import me.filoghost.holographicdisplays.common.nms.NMSPacketList;
public class VersionNMSManager implements NMSManager {
private static final ReflectField<RegistryID<Class<? extends Entity>>> REGISTRY_ID_FIELD
= ReflectField.lookup(new ClassToken<RegistryID<Class<? extends Entity>>>() {}, RegistryMaterials.class, "a");
private static final ReflectField<Object[]> ID_TO_CLASS_MAP_FIELD
= ReflectField.lookup(Object[].class, RegistryID.class, "d");
private static final ReflectMethod<?> REGISTER_ENTITY_METHOD = ReflectMethod.lookup(Object.class, World.class, "b", Entity.class);
private final ProtocolPacketSettings protocolPacketSettings;
public VersionNMSManager(ProtocolPacketSettings protocolPacketSettings) {
this.protocolPacketSettings = protocolPacketSettings;
@Override
public EntityID newEntityID() {
return null;
}
@Override
public void setup() throws Exception {
registerCustomEntity(EntityNMSSlime.class, 55);
}
public void registerCustomEntity(Class<? extends Entity> entityClass, int id) throws Exception {
// Use reflection to get the RegistryID of entities
RegistryID<Class<? extends Entity>> registryID = REGISTRY_ID_FIELD.get(EntityTypes.b);
Object[] idToClassMap = ID_TO_CLASS_MAP_FIELD.get(registryID);
// 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 NMSItem spawnNMSItem(
org.bukkit.World bukkitWorld, double x, double y, double z,
StandardItemLine parentHologramLine,
ItemStack stack) throws SpawnFailedException {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
EntityNMSItem item = new EntityNMSItem(nmsWorld, parentHologramLine);
item.setLocationNMS(x, y, z);
item.setItemStackNMS(stack);
addEntityToWorld(nmsWorld, item);
return item;
}
@Override
public EntityNMSSlime spawnNMSSlime(
org.bukkit.World bukkitWorld, double x, double y, double z,
StandardHologramLine parentHologramLine) throws SpawnFailedException {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
EntityNMSSlime slime = new EntityNMSSlime(nmsWorld, parentHologramLine);
slime.setLocationNMS(x, y, z);
addEntityToWorld(nmsWorld, slime);
return slime;
}
@Override
public NMSArmorStand spawnNMSArmorStand(
org.bukkit.World world, double x, double y, double z,
StandardHologramLine parentHologramLine) throws SpawnFailedException {
WorldServer nmsWorld = ((CraftWorld) world).getHandle();
EntityNMSArmorStand armorStand = new EntityNMSArmorStand(nmsWorld, parentHologramLine, protocolPacketSettings);
armorStand.setLocationNMS(x, y, z);
addEntityToWorld(nmsWorld, armorStand);
return armorStand;
}
private void addEntityToWorld(WorldServer nmsWorld, Entity nmsEntity) throws SpawnFailedException {
Preconditions.checkState(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;
throw new SpawnFailedException(SpawnFailedException.CHUNK_NOT_LOADED);
}
nmsWorld.getChunkAt(chunkX, chunkZ).a(nmsEntity);
nmsWorld.entityList.add(nmsEntity);
try {
REGISTER_ENTITY_METHOD.invoke(nmsWorld, nmsEntity);
} catch (ReflectiveOperationException e) {
nmsEntity.dead = true;
throw new SpawnFailedException(SpawnFailedException.REGISTER_ENTITY_FAIL, e);
}
}
@Override
public boolean isNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) {
return ((CraftEntity) bukkitEntity).getHandle() instanceof NMSEntity;
}
@Override
public NMSEntity getNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) {
Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle();
if (nmsEntity instanceof NMSEntity) {
return (NMSEntity) nmsEntity;
} else {
return null;
}
}
@Override
public NMSEntity getNMSEntityBaseFromID(org.bukkit.World bukkitWorld, int entityID) {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
Entity nmsEntity = nmsWorld.getEntity(entityID);
if (nmsEntity instanceof NMSEntity) {
return (NMSEntity) nmsEntity;
} else {
return null;
}
}
@Override
public Object createCustomNameNMSObject(String customName) {
return EntityNMSArmorStand.createCustomNameNMSObject(customName);
public NMSPacketList createPacketList() {
return null;
}
}

View File

@ -1,88 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_13_R1;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_13_R1.CraftServer;
import org.bukkit.craftbukkit.v1_13_R1.entity.CraftArmorStand;
import org.bukkit.entity.Entity;
import org.bukkit.event.entity.EntityDamageEvent;
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;
import java.util.Collection;
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 ArmorStand 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; }
@Override public void setSwimming(boolean swimming) {}
// 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 setLastDamageCause(EntityDamageEvent event) {}
@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

@ -1,56 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_13_R1;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_13_R1.CraftServer;
import org.bukkit.craftbukkit.v1_13_R1.entity.CraftItem;
import org.bukkit.entity.Entity;
import org.bukkit.event.entity.EntityDamageEvent;
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 setLastDamageCause(EntityDamageEvent event) {}
@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

@ -1,72 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_13_R1;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_13_R1.CraftServer;
import org.bukkit.craftbukkit.v1_13_R1.entity.CraftSlime;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.potion.PotionEffect;
import org.bukkit.util.Vector;
import java.util.Collection;
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; }
@Override public void setSwimming(boolean swimming) {}
// 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 setLastDamageCause(EntityDamageEvent event) {}
@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) {}
@Override public void setTarget(LivingEntity target) {}
}

View File

@ -1,262 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_13_R1;
import me.filoghost.fcommons.Preconditions;
import me.filoghost.fcommons.Strings;
import me.filoghost.fcommons.reflection.ReflectField;
import me.filoghost.holographicdisplays.common.DebugLogger;
import me.filoghost.holographicdisplays.common.hologram.StandardHologramLine;
import me.filoghost.holographicdisplays.common.nms.ProtocolPacketSettings;
import me.filoghost.holographicdisplays.common.nms.entity.NMSArmorStand;
import me.filoghost.holographicdisplays.common.nms.entity.NMSEntity;
import net.minecraft.server.v1_13_R1.AxisAlignedBB;
import net.minecraft.server.v1_13_R1.DamageSource;
import net.minecraft.server.v1_13_R1.Entity;
import net.minecraft.server.v1_13_R1.EntityArmorStand;
import net.minecraft.server.v1_13_R1.EntityHuman;
import net.minecraft.server.v1_13_R1.EnumHand;
import net.minecraft.server.v1_13_R1.EnumInteractionResult;
import net.minecraft.server.v1_13_R1.EnumItemSlot;
import net.minecraft.server.v1_13_R1.IChatBaseComponent;
import net.minecraft.server.v1_13_R1.ItemStack;
import net.minecraft.server.v1_13_R1.NBTTagCompound;
import net.minecraft.server.v1_13_R1.PacketPlayOutEntityTeleport;
import net.minecraft.server.v1_13_R1.SoundEffect;
import net.minecraft.server.v1_13_R1.Vec3D;
import net.minecraft.server.v1_13_R1.World;
import org.bukkit.craftbukkit.v1_13_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_13_R1.util.CraftChatMessage;
import org.bukkit.entity.Player;
import java.util.Objects;
public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorStand {
private static final ReflectField<Entity> VEHICLE_FIELD = ReflectField.lookup(Entity.class, Entity.class, "ax");
private final StandardHologramLine parentHologramLine;
private final ProtocolPacketSettings protocolPacketSettings;
private final VersionNMSEntityHelper helper;
private String customName;
public EntityNMSArmorStand(World world, StandardHologramLine parentHologramLine, ProtocolPacketSettings protocolPacketSettings) {
super(world);
this.parentHologramLine = parentHologramLine;
this.protocolPacketSettings = protocolPacketSettings;
this.helper = new VersionNMSEntityHelper(this);
super.setInvisible(true);
super.setSmall(true);
super.setArms(false);
super.setNoGravity(true);
super.setBasePlate(true);
super.setMarker(true);
super.collides = false;
super.onGround = true; // Workaround to force EntityTrackerEntry to send a teleport packet
forceSetBoundingBox(new NullBoundingBox());
}
@Override
public void tick() {
// Disable normal ticking for this entity
// Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity
if (super.onGround) {
super.onGround = false;
}
}
@Override
public void inactiveTick() {
// Disable normal ticking for this entity
// Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity
if (super.onGround) {
super.onGround = false;
}
}
@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(IChatBaseComponent ichatbasecomponent) {
// Prevents changes to custom name
}
@Override
public void setCustomNameVisible(boolean visible) {
// Prevents changes to custom name visibility
}
@Override
public EnumInteractionResult a(EntityHuman human, Vec3D vec3d, EnumHand enumhand) {
// Prevent armor stand from being equipped
return EnumInteractionResult.PASS;
}
@Override
public boolean c(int i, ItemStack item) {
// Prevent armor stand from being equipped
return false;
}
@Override
public void setSlot(EnumItemSlot enumitemslot, ItemStack itemstack) {
// Prevent armor stand from being equipped
}
@Override
public void a(AxisAlignedBB boundingBox) {
// Prevent changes to bounding box
}
public void forceSetBoundingBox(AxisAlignedBB boundingBox) {
super.a(boundingBox);
}
@Override
public void a(SoundEffect soundeffect, float f, float f1) {
// Remove sounds
}
@Override
public void setCustomNameNMS(String customName) {
if (Objects.equals(this.customName, customName)) {
return;
}
this.customName = customName;
super.setCustomName(createCustomNameNMSObject(customName));
super.setCustomNameVisible(customName != null && !customName.isEmpty());
}
protected static IChatBaseComponent createCustomNameNMSObject(String customName) {
return CraftChatMessage.fromStringOrNull(Strings.truncate(customName, 300));
}
@Override
public String getCustomNameStringNMS() {
return this.customName;
}
@Override
public IChatBaseComponent getCustomNameObjectNMS() {
return super.getCustomName();
}
@Override
public void die() {
// Prevent entity from dying
}
@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);
if (protocolPacketSettings.sendAccurateLocationPackets()) {
helper.broadcastPacket(new PacketPlayOutEntityTeleport(this));
}
}
@Override
public void setPassengerNMS(NMSEntity passenger) {
Preconditions.checkArgument(passenger instanceof Entity);
Entity passengerEntity = (Entity) passenger;
Preconditions.checkArgument(passengerEntity.getVehicle() == null);
Preconditions.checkState(super.passengers.isEmpty());
try {
VEHICLE_FIELD.set(passenger, this);
this.passengers.add(passengerEntity);
} catch (ReflectiveOperationException e) {
DebugLogger.cannotSetPassenger(e);
}
}
@Override
public boolean isDeadNMS() {
return super.dead;
}
@Override
public int getIdNMS() {
return super.getId();
}
@Override
public StandardHologramLine getHologramLine() {
return parentHologramLine;
}
@Override
public org.bukkit.entity.Entity getBukkitEntityNMS() {
return getBukkitEntity();
}
@Override
public boolean isTrackedBy(Player bukkitPlayer) {
return helper.isTrackedBy(bukkitPlayer);
}
}

View File

@ -1,199 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_13_R1;
import me.filoghost.holographicdisplays.common.hologram.StandardHologramLine;
import me.filoghost.holographicdisplays.common.hologram.StandardItemLine;
import me.filoghost.holographicdisplays.common.nms.NMSCommons;
import me.filoghost.holographicdisplays.common.nms.entity.NMSItem;
import net.minecraft.server.v1_13_R1.Blocks;
import net.minecraft.server.v1_13_R1.DamageSource;
import net.minecraft.server.v1_13_R1.EntityHuman;
import net.minecraft.server.v1_13_R1.EntityItem;
import net.minecraft.server.v1_13_R1.EntityPlayer;
import net.minecraft.server.v1_13_R1.ItemStack;
import net.minecraft.server.v1_13_R1.NBTTagCompound;
import net.minecraft.server.v1_13_R1.NBTTagList;
import net.minecraft.server.v1_13_R1.NBTTagString;
import net.minecraft.server.v1_13_R1.World;
import org.bukkit.craftbukkit.v1_13_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_13_R1.inventory.CraftItemStack;
import org.bukkit.entity.Player;
public class EntityNMSItem extends EntityItem implements NMSItem {
private final StandardItemLine parentHologramLine;
private final VersionNMSEntityHelper helper;
public EntityNMSItem(World world, StandardItemLine parentHologramLine) {
super(world);
this.parentHologramLine = parentHologramLine;
this.helper = new VersionNMSEntityHelper(this);
super.pickupDelay = 32767; // Lock the item pickup delay, also prevents entities from picking up the item
}
@Override
public void tick() {
// Disable normal ticking for this entity
// So it won't get removed
ticksLived = 0;
}
@Override
public void inactiveTick() {
// Disable normal ticking for this entity
// So it won't get removed
ticksLived = 0;
}
// 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 (human instanceof EntityPlayer) {
parentHologramLine.onPickup(((EntityPlayer) human).getBukkitEntity());
// 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 die() {
// Prevent entity from dying
}
@Override
public boolean isAlive() {
// This override prevents items from being picked up by hoppers (should have no side effects)
return false;
}
@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 == ItemStack.a) { // ItemStack.a is returned if the stack is not valid
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(NMSCommons.ANTI_STACK_LORE));
display.set("Lore", tagList);
super.setItemStack(newItem);
}
@Override
public int getIdNMS() {
return super.getId();
}
@Override
public StandardHologramLine getHologramLine() {
return parentHologramLine;
}
@Override
public org.bukkit.entity.Entity getBukkitEntityNMS() {
return getBukkitEntity();
}
@Override
public boolean isTrackedBy(Player bukkitPlayer) {
return helper.isTrackedBy(bukkitPlayer);
}
@Override
public Object getRawItemStack() {
return super.getItemStack();
}
}

View File

@ -1,191 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_13_R1;
import me.filoghost.holographicdisplays.common.hologram.StandardHologramLine;
import me.filoghost.holographicdisplays.common.nms.entity.NMSSlime;
import net.minecraft.server.v1_13_R1.AxisAlignedBB;
import net.minecraft.server.v1_13_R1.DamageSource;
import net.minecraft.server.v1_13_R1.EntityDamageSource;
import net.minecraft.server.v1_13_R1.EntityPlayer;
import net.minecraft.server.v1_13_R1.EntitySlime;
import net.minecraft.server.v1_13_R1.IChatBaseComponent;
import net.minecraft.server.v1_13_R1.NBTTagCompound;
import net.minecraft.server.v1_13_R1.SoundEffect;
import net.minecraft.server.v1_13_R1.World;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_13_R1.entity.CraftEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerInteractEntityEvent;
public class EntityNMSSlime extends EntitySlime implements NMSSlime {
private final StandardHologramLine parentHologramLine;
private final VersionNMSEntityHelper helper;
public EntityNMSSlime(World world, StandardHologramLine parentHologramLine) {
super(world);
this.parentHologramLine = parentHologramLine;
this.helper = new VersionNMSEntityHelper(this);
super.persistent = true;
super.collides = false;
super.a(0.0F, 0.0F);
super.setSize(1, false);
super.setInvisible(true);
forceSetBoundingBox(new NullBoundingBox());
}
@Override
public void tick() {
// Disable normal ticking for this entity
// So it won't get removed
ticksLived = 0;
}
@Override
public void inactiveTick() {
// Disable normal ticking for this entity
// So it won't get removed
ticksLived = 0;
}
@Override
public void a(AxisAlignedBB boundingBox) {
// Prevent changes to bounding box
}
public void forceSetBoundingBox(AxisAlignedBB boundingBox) {
super.a(boundingBox);
}
@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) {
Player player = ((EntityPlayer) entityDamageSource.getEntity()).getBukkitEntity();
PlayerInteractEntityEvent event = new PlayerInteractEntityEvent(player, getBukkitEntity());
Bukkit.getPluginManager().callEvent(event); // 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 setCustomName(IChatBaseComponent ichatbasecomponent) {
// Prevents changes to custom name
}
@Override
public void setCustomNameVisible(boolean visible) {
// Prevents changes to custom name visibility
}
@Override
public void a(SoundEffect soundeffect, float f, float f1) {
// Remove sounds
}
@Override
public void die() {
// Prevent entity from dying
}
@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 StandardHologramLine getHologramLine() {
return parentHologramLine;
}
@Override
public org.bukkit.entity.Entity getBukkitEntityNMS() {
return getBukkitEntity();
}
@Override
public boolean isTrackedBy(Player bukkitPlayer) {
return helper.isTrackedBy(bukkitPlayer);
}
}

View File

@ -1,120 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_13_R1;
import net.minecraft.server.v1_13_R1.AxisAlignedBB;
import net.minecraft.server.v1_13_R1.BlockPosition;
import net.minecraft.server.v1_13_R1.EnumDirection.EnumAxis;
import net.minecraft.server.v1_13_R1.MovingObjectPosition;
import net.minecraft.server.v1_13_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 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 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 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 double a(EnumAxis arg0) {
return 0.0;
}
@Override
public MovingObjectPosition a(Vec3D arg0, Vec3D arg1, BlockPosition arg2) {
return null;
}
@Override
public double b(EnumAxis arg0) {
return 0.0;
}
@Override
public boolean e(double arg0, double arg1, double arg2) {
return false;
}
@Override
public AxisAlignedBB f(double arg0, double arg1, double arg2) {
return this;
}
}

View File

@ -1,46 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_13_R1;
import me.filoghost.holographicdisplays.common.nms.entity.NMSEntityHelper;
import net.minecraft.server.v1_13_R1.Entity;
import net.minecraft.server.v1_13_R1.EntityTrackerEntry;
import net.minecraft.server.v1_13_R1.Packet;
import net.minecraft.server.v1_13_R1.WorldServer;
import org.bukkit.craftbukkit.v1_13_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
public class VersionNMSEntityHelper extends NMSEntityHelper<EntityTrackerEntry> {
private final Entity entity;
public VersionNMSEntityHelper(Entity entity) {
this.entity = entity;
}
@Override
protected EntityTrackerEntry getTracker0() {
return ((WorldServer) entity.world).tracker.trackedEntities.get(entity.getId());
}
@Override
public boolean isTrackedBy(Player bukkitPlayer) {
EntityTrackerEntry tracker = getTracker();
if (tracker != null) {
return tracker.trackedPlayers.contains(((CraftPlayer) bukkitPlayer).getHandle());
} else {
return false;
}
}
public void broadcastPacket(Packet<?> packet) {
EntityTrackerEntry tracker = getTracker();
if (tracker != null) {
tracker.broadcast(packet);
}
}
}

View File

@ -5,170 +5,20 @@
*/
package me.filoghost.holographicdisplays.nms.v1_13_R1;
import me.filoghost.fcommons.Preconditions;
import me.filoghost.fcommons.reflection.ClassToken;
import me.filoghost.fcommons.reflection.ReflectField;
import me.filoghost.fcommons.reflection.ReflectMethod;
import me.filoghost.holographicdisplays.common.hologram.StandardHologramLine;
import me.filoghost.holographicdisplays.common.hologram.StandardItemLine;
import me.filoghost.holographicdisplays.common.nms.NMSCommons;
import me.filoghost.holographicdisplays.common.nms.EntityID;
import me.filoghost.holographicdisplays.common.nms.NMSManager;
import me.filoghost.holographicdisplays.common.nms.ProtocolPacketSettings;
import me.filoghost.holographicdisplays.common.nms.SpawnFailedException;
import me.filoghost.holographicdisplays.common.nms.entity.NMSArmorStand;
import me.filoghost.holographicdisplays.common.nms.entity.NMSEntity;
import me.filoghost.holographicdisplays.common.nms.entity.NMSItem;
import net.minecraft.server.v1_13_R1.Entity;
import net.minecraft.server.v1_13_R1.EntityTypes;
import net.minecraft.server.v1_13_R1.MathHelper;
import net.minecraft.server.v1_13_R1.RegistryID;
import net.minecraft.server.v1_13_R1.RegistryMaterials;
import net.minecraft.server.v1_13_R1.World;
import net.minecraft.server.v1_13_R1.WorldServer;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_13_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_13_R1.entity.CraftEntity;
import org.bukkit.inventory.ItemStack;
import java.util.List;
import me.filoghost.holographicdisplays.common.nms.NMSPacketList;
public class VersionNMSManager implements NMSManager {
private static final ReflectField<RegistryID<EntityTypes<?>>> REGISTRY_ID_FIELD
= ReflectField.lookup(new ClassToken<RegistryID<EntityTypes<?>>>() {}, RegistryMaterials.class, "a");
private static final ReflectField<Object[]> ID_TO_CLASS_MAP_FIELD
= ReflectField.lookup(Object[].class, RegistryID.class, "d");
private static final ReflectField<List<Entity>> ENTITY_LIST_FIELD
= ReflectField.lookup(new ClassToken<List<Entity>>() {}, World.class, "entityList");
private static final ReflectMethod<?> REGISTER_ENTITY_METHOD = ReflectMethod.lookup(Object.class, World.class, "b", Entity.class);
private final ProtocolPacketSettings protocolPacketSettings;
public VersionNMSManager(ProtocolPacketSettings protocolPacketSettings) {
this.protocolPacketSettings = protocolPacketSettings;
@Override
public EntityID newEntityID() {
return null;
}
@Override
public void setup() throws Exception {
registerCustomEntity(EntityNMSSlime.class, 55);
}
public void registerCustomEntity(Class<? extends Entity> entityClass, int id) throws Exception {
// Use reflection to get the RegistryID of entities
RegistryID<EntityTypes<?>> registryID = REGISTRY_ID_FIELD.get(EntityTypes.REGISTRY);
Object[] idToClassMap = ID_TO_CLASS_MAP_FIELD.get(registryID);
// Save the the ID -> EntityTypes mapping before the registration
Object oldValue = idToClassMap[id];
// Register the EntityTypes object
registryID.a(new EntityTypes<>(entityClass, world -> null, true, true, null), id);
// Restore the ID -> EntityTypes mapping
idToClassMap[id] = oldValue;
}
@Override
public NMSItem spawnNMSItem(
org.bukkit.World bukkitWorld, double x, double y, double z,
StandardItemLine parentHologramLine,
ItemStack stack) throws SpawnFailedException {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
EntityNMSItem item = new EntityNMSItem(nmsWorld, parentHologramLine);
item.setLocationNMS(x, y, z);
item.setItemStackNMS(stack);
addEntityToWorld(nmsWorld, item);
return item;
}
@Override
public EntityNMSSlime spawnNMSSlime(
org.bukkit.World bukkitWorld, double x, double y, double z,
StandardHologramLine parentHologramLine) throws SpawnFailedException {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
EntityNMSSlime slime = new EntityNMSSlime(nmsWorld, parentHologramLine);
slime.setLocationNMS(x, y, z);
addEntityToWorld(nmsWorld, slime);
return slime;
}
@Override
public NMSArmorStand spawnNMSArmorStand(
org.bukkit.World world, double x, double y, double z,
StandardHologramLine parentHologramLine) throws SpawnFailedException {
WorldServer nmsWorld = ((CraftWorld) world).getHandle();
EntityNMSArmorStand armorStand = new EntityNMSArmorStand(nmsWorld, parentHologramLine, protocolPacketSettings);
armorStand.setLocationNMS(x, y, z);
addEntityToWorld(nmsWorld, armorStand);
return armorStand;
}
private void addEntityToWorld(WorldServer nmsWorld, Entity nmsEntity) throws SpawnFailedException {
Preconditions.checkState(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;
throw new SpawnFailedException(SpawnFailedException.CHUNK_NOT_LOADED);
}
nmsWorld.getChunkAt(chunkX, chunkZ).a(nmsEntity);
if (NMSCommons.IS_PAPER_SERVER) {
try {
// Workaround because nmsWorld.entityList is a different class in Paper,
// if used without reflection it throws NoSuchFieldError.
ENTITY_LIST_FIELD.get(nmsWorld).add(nmsEntity);
} catch (ReflectiveOperationException e) {
e.printStackTrace();
throw new SpawnFailedException(SpawnFailedException.CHUNK_NOT_LOADED);
}
} else {
nmsWorld.entityList.add(nmsEntity);
}
try {
REGISTER_ENTITY_METHOD.invoke(nmsWorld, nmsEntity);
} catch (ReflectiveOperationException e) {
nmsEntity.dead = true;
throw new SpawnFailedException(SpawnFailedException.REGISTER_ENTITY_FAIL, e);
}
}
@Override
public boolean isNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) {
return ((CraftEntity) bukkitEntity).getHandle() instanceof NMSEntity;
}
@Override
public NMSEntity getNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) {
Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle();
if (nmsEntity instanceof NMSEntity) {
return (NMSEntity) nmsEntity;
} else {
return null;
}
}
@Override
public NMSEntity getNMSEntityBaseFromID(org.bukkit.World bukkitWorld, int entityID) {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
Entity nmsEntity = nmsWorld.getEntity(entityID);
if (nmsEntity instanceof NMSEntity) {
return (NMSEntity) nmsEntity;
} else {
return null;
}
}
@Override
public Object createCustomNameNMSObject(String customName) {
return EntityNMSArmorStand.createCustomNameNMSObject(customName);
public NMSPacketList createPacketList() {
return null;
}
}

View File

@ -1,89 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_13_R2;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_13_R2.CraftServer;
import org.bukkit.craftbukkit.v1_13_R2.entity.CraftArmorStand;
import org.bukkit.entity.Entity;
import org.bukkit.event.entity.EntityDamageEvent;
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;
import java.util.Collection;
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 ArmorStand 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; }
@Override public void setSwimming(boolean swimming) {}
// 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 setLastDamageCause(EntityDamageEvent event) {}
@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) {}
@Override public void setPersistent(boolean flag) {}
}

View File

@ -1,57 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_13_R2;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_13_R2.CraftServer;
import org.bukkit.craftbukkit.v1_13_R2.entity.CraftItem;
import org.bukkit.entity.Entity;
import org.bukkit.event.entity.EntityDamageEvent;
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 setLastDamageCause(EntityDamageEvent event) {}
@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) {}
@Override public void setPersistent(boolean flag) {}
// Methods from Item
@Override public void setItemStack(ItemStack stack) {}
@Override public void setPickupDelay(int delay) {}
}

View File

@ -1,77 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_13_R2;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_13_R2.CraftServer;
import org.bukkit.craftbukkit.v1_13_R2.entity.CraftSlime;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.loot.LootTable;
import org.bukkit.potion.PotionEffect;
import org.bukkit.util.Vector;
import java.util.Collection;
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; }
@Override public void setSwimming(boolean swimming) {}
// 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 setLastDamageCause(EntityDamageEvent event) {}
@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) {}
@Override public void setPersistent(boolean flag) {}
// Methods from Mob
@Override public void setLootTable(LootTable table) {}
@Override public void setSeed(long seed) {}
// Methods from Slime
@Override public void setSize(int size) {}
@Override public void setTarget(LivingEntity target) {}
}

View File

@ -1,262 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_13_R2;
import me.filoghost.fcommons.Preconditions;
import me.filoghost.fcommons.Strings;
import me.filoghost.fcommons.reflection.ReflectField;
import me.filoghost.holographicdisplays.common.DebugLogger;
import me.filoghost.holographicdisplays.common.hologram.StandardHologramLine;
import me.filoghost.holographicdisplays.common.nms.ProtocolPacketSettings;
import me.filoghost.holographicdisplays.common.nms.entity.NMSArmorStand;
import me.filoghost.holographicdisplays.common.nms.entity.NMSEntity;
import net.minecraft.server.v1_13_R2.AxisAlignedBB;
import net.minecraft.server.v1_13_R2.DamageSource;
import net.minecraft.server.v1_13_R2.Entity;
import net.minecraft.server.v1_13_R2.EntityArmorStand;
import net.minecraft.server.v1_13_R2.EntityHuman;
import net.minecraft.server.v1_13_R2.EnumHand;
import net.minecraft.server.v1_13_R2.EnumInteractionResult;
import net.minecraft.server.v1_13_R2.EnumItemSlot;
import net.minecraft.server.v1_13_R2.IChatBaseComponent;
import net.minecraft.server.v1_13_R2.ItemStack;
import net.minecraft.server.v1_13_R2.NBTTagCompound;
import net.minecraft.server.v1_13_R2.PacketPlayOutEntityTeleport;
import net.minecraft.server.v1_13_R2.SoundEffect;
import net.minecraft.server.v1_13_R2.Vec3D;
import net.minecraft.server.v1_13_R2.World;
import org.bukkit.craftbukkit.v1_13_R2.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_13_R2.util.CraftChatMessage;
import org.bukkit.entity.Player;
import java.util.Objects;
public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorStand {
private static final ReflectField<Entity> VEHICLE_FIELD = ReflectField.lookup(Entity.class, Entity.class, "vehicle");
private final StandardHologramLine parentHologramLine;
private final ProtocolPacketSettings protocolPacketSettings;
private final VersionNMSEntityHelper helper;
private String customName;
public EntityNMSArmorStand(World world, StandardHologramLine parentHologramLine, ProtocolPacketSettings protocolPacketSettings) {
super(world);
this.parentHologramLine = parentHologramLine;
this.protocolPacketSettings = protocolPacketSettings;
this.helper = new VersionNMSEntityHelper(this);
super.setInvisible(true);
super.setSmall(true);
super.setArms(false);
super.setNoGravity(true);
super.setBasePlate(true);
super.setMarker(true);
super.collides = false;
super.onGround = true; // Workaround to force EntityTrackerEntry to send a teleport packet
forceSetBoundingBox(new NullBoundingBox());
}
@Override
public void tick() {
// Disable normal ticking for this entity
// Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity
if (super.onGround) {
super.onGround = false;
}
}
@Override
public void inactiveTick() {
// Disable normal ticking for this entity
// Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity
if (super.onGround) {
super.onGround = false;
}
}
@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(IChatBaseComponent ichatbasecomponent) {
// Prevents changes to custom name
}
@Override
public void setCustomNameVisible(boolean visible) {
// Prevents changes to custom name visibility
}
@Override
public EnumInteractionResult a(EntityHuman human, Vec3D vec3d, EnumHand enumhand) {
// Prevent armor stand from being equipped
return EnumInteractionResult.PASS;
}
@Override
public boolean c(int i, ItemStack item) {
// Prevent armor stand from being equipped
return false;
}
@Override
public void setSlot(EnumItemSlot enumitemslot, ItemStack itemstack) {
// Prevent armor stand from being equipped
}
@Override
public void a(AxisAlignedBB boundingBox) {
// Prevent changes to bounding box
}
public void forceSetBoundingBox(AxisAlignedBB boundingBox) {
super.a(boundingBox);
}
@Override
public void a(SoundEffect soundeffect, float f, float f1) {
// Remove sounds
}
@Override
public void setCustomNameNMS(String customName) {
if (Objects.equals(this.customName, customName)) {
return;
}
this.customName = customName;
super.setCustomName(createCustomNameNMSObject(customName));
super.setCustomNameVisible(customName != null && !customName.isEmpty());
}
protected static IChatBaseComponent createCustomNameNMSObject(String customName) {
return CraftChatMessage.fromStringOrNull(Strings.truncate(customName, 300));
}
@Override
public String getCustomNameStringNMS() {
return this.customName;
}
@Override
public IChatBaseComponent getCustomNameObjectNMS() {
return super.getCustomName();
}
@Override
public void die() {
// Prevent entity from dying
}
@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);
if (protocolPacketSettings.sendAccurateLocationPackets()) {
helper.broadcastPacket(new PacketPlayOutEntityTeleport(this));
}
}
@Override
public void setPassengerNMS(NMSEntity passenger) {
Preconditions.checkArgument(passenger instanceof Entity);
Entity passengerEntity = (Entity) passenger;
Preconditions.checkArgument(passengerEntity.getVehicle() == null);
Preconditions.checkState(super.passengers.isEmpty());
try {
VEHICLE_FIELD.set(passenger, this);
this.passengers.add(passengerEntity);
} catch (ReflectiveOperationException e) {
DebugLogger.cannotSetPassenger(e);
}
}
@Override
public boolean isDeadNMS() {
return super.dead;
}
@Override
public int getIdNMS() {
return super.getId();
}
@Override
public StandardHologramLine getHologramLine() {
return parentHologramLine;
}
@Override
public org.bukkit.entity.Entity getBukkitEntityNMS() {
return getBukkitEntity();
}
@Override
public boolean isTrackedBy(Player bukkitPlayer) {
return helper.isTrackedBy(bukkitPlayer);
}
}

View File

@ -1,199 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_13_R2;
import me.filoghost.holographicdisplays.common.hologram.StandardHologramLine;
import me.filoghost.holographicdisplays.common.hologram.StandardItemLine;
import me.filoghost.holographicdisplays.common.nms.NMSCommons;
import me.filoghost.holographicdisplays.common.nms.entity.NMSItem;
import net.minecraft.server.v1_13_R2.Blocks;
import net.minecraft.server.v1_13_R2.DamageSource;
import net.minecraft.server.v1_13_R2.EntityHuman;
import net.minecraft.server.v1_13_R2.EntityItem;
import net.minecraft.server.v1_13_R2.EntityPlayer;
import net.minecraft.server.v1_13_R2.ItemStack;
import net.minecraft.server.v1_13_R2.NBTTagCompound;
import net.minecraft.server.v1_13_R2.NBTTagList;
import net.minecraft.server.v1_13_R2.NBTTagString;
import net.minecraft.server.v1_13_R2.World;
import org.bukkit.craftbukkit.v1_13_R2.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_13_R2.inventory.CraftItemStack;
import org.bukkit.entity.Player;
public class EntityNMSItem extends EntityItem implements NMSItem {
private final StandardItemLine parentHologramLine;
private final VersionNMSEntityHelper helper;
public EntityNMSItem(World world, StandardItemLine parentHologramLine) {
super(world);
this.parentHologramLine = parentHologramLine;
this.helper = new VersionNMSEntityHelper(this);
super.pickupDelay = 32767; // Lock the item pickup delay, also prevents entities from picking up the item
}
@Override
public void tick() {
// Disable normal ticking for this entity
// So it won't get removed
ticksLived = 0;
}
@Override
public void inactiveTick() {
// Disable normal ticking for this entity
// So it won't get removed
ticksLived = 0;
}
// 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 (human instanceof EntityPlayer) {
parentHologramLine.onPickup(((EntityPlayer) human).getBukkitEntity());
// 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 die() {
// Prevent entity from dying
}
@Override
public boolean isAlive() {
// This override prevents items from being picked up by hoppers (should have no side effects)
return false;
}
@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 == ItemStack.a) { // ItemStack.a is returned if the stack is not valid
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(NMSCommons.ANTI_STACK_LORE));
display.set("Lore", tagList);
super.setItemStack(newItem);
}
@Override
public int getIdNMS() {
return super.getId();
}
@Override
public StandardHologramLine getHologramLine() {
return parentHologramLine;
}
@Override
public org.bukkit.entity.Entity getBukkitEntityNMS() {
return getBukkitEntity();
}
@Override
public boolean isTrackedBy(Player bukkitPlayer) {
return helper.isTrackedBy(bukkitPlayer);
}
@Override
public Object getRawItemStack() {
return super.getItemStack();
}
}

View File

@ -1,191 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_13_R2;
import me.filoghost.holographicdisplays.common.hologram.StandardHologramLine;
import me.filoghost.holographicdisplays.common.nms.entity.NMSSlime;
import net.minecraft.server.v1_13_R2.AxisAlignedBB;
import net.minecraft.server.v1_13_R2.DamageSource;
import net.minecraft.server.v1_13_R2.EntityDamageSource;
import net.minecraft.server.v1_13_R2.EntityPlayer;
import net.minecraft.server.v1_13_R2.EntitySlime;
import net.minecraft.server.v1_13_R2.IChatBaseComponent;
import net.minecraft.server.v1_13_R2.NBTTagCompound;
import net.minecraft.server.v1_13_R2.SoundEffect;
import net.minecraft.server.v1_13_R2.World;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_13_R2.entity.CraftEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerInteractEntityEvent;
public class EntityNMSSlime extends EntitySlime implements NMSSlime {
private final StandardHologramLine parentHologramLine;
private final VersionNMSEntityHelper helper;
public EntityNMSSlime(World world, StandardHologramLine parentHologramLine) {
super(world);
this.parentHologramLine = parentHologramLine;
this.helper = new VersionNMSEntityHelper(this);
super.persistent = true;
super.collides = false;
super.a(0.0F, 0.0F);
super.setSize(1, false);
super.setInvisible(true);
forceSetBoundingBox(new NullBoundingBox());
}
@Override
public void tick() {
// Disable normal ticking for this entity
// So it won't get removed
ticksLived = 0;
}
@Override
public void inactiveTick() {
// Disable normal ticking for this entity
// So it won't get removed
ticksLived = 0;
}
@Override
public void a(AxisAlignedBB boundingBox) {
// Prevent changes to bounding box
}
public void forceSetBoundingBox(AxisAlignedBB boundingBox) {
super.a(boundingBox);
}
@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) {
Player player = ((EntityPlayer) entityDamageSource.getEntity()).getBukkitEntity();
PlayerInteractEntityEvent event = new PlayerInteractEntityEvent(player, getBukkitEntity());
Bukkit.getPluginManager().callEvent(event); // 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 setCustomName(IChatBaseComponent ichatbasecomponent) {
// Prevents changes to custom name
}
@Override
public void setCustomNameVisible(boolean visible) {
// Prevents changes to custom name visibility
}
@Override
public void a(SoundEffect soundeffect, float f, float f1) {
// Remove sounds
}
@Override
public void die() {
// Prevent entity from dying
}
@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 StandardHologramLine getHologramLine() {
return parentHologramLine;
}
@Override
public org.bukkit.entity.Entity getBukkitEntityNMS() {
return getBukkitEntity();
}
@Override
public boolean isTrackedBy(Player bukkitPlayer) {
return helper.isTrackedBy(bukkitPlayer);
}
}

View File

@ -1,120 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_13_R2;
import net.minecraft.server.v1_13_R2.AxisAlignedBB;
import net.minecraft.server.v1_13_R2.BlockPosition;
import net.minecraft.server.v1_13_R2.EnumDirection.EnumAxis;
import net.minecraft.server.v1_13_R2.MovingObjectPosition;
import net.minecraft.server.v1_13_R2.Vec3D;
public class NullBoundingBox extends AxisAlignedBB {
public NullBoundingBox() {
super(0, 0, 0, 0, 0, 0);
}
@Override
public double a() {
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 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 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 double a(EnumAxis arg0) {
return 0.0;
}
@Override
public MovingObjectPosition a(Vec3D arg0, Vec3D arg1, BlockPosition arg2) {
return null;
}
@Override
public double b(EnumAxis arg0) {
return 0.0;
}
@Override
public boolean e(double arg0, double arg1, double arg2) {
return false;
}
@Override
public AxisAlignedBB f(double arg0, double arg1, double arg2) {
return this;
}
}

View File

@ -1,46 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_13_R2;
import me.filoghost.holographicdisplays.common.nms.entity.NMSEntityHelper;
import net.minecraft.server.v1_13_R2.Entity;
import net.minecraft.server.v1_13_R2.EntityTrackerEntry;
import net.minecraft.server.v1_13_R2.Packet;
import net.minecraft.server.v1_13_R2.WorldServer;
import org.bukkit.craftbukkit.v1_13_R2.entity.CraftPlayer;
import org.bukkit.entity.Player;
public class VersionNMSEntityHelper extends NMSEntityHelper<EntityTrackerEntry> {
private final Entity entity;
public VersionNMSEntityHelper(Entity entity) {
this.entity = entity;
}
@Override
protected EntityTrackerEntry getTracker0() {
return ((WorldServer) entity.world).tracker.trackedEntities.get(entity.getId());
}
@Override
public boolean isTrackedBy(Player bukkitPlayer) {
EntityTrackerEntry tracker = getTracker();
if (tracker != null) {
return tracker.trackedPlayers.contains(((CraftPlayer) bukkitPlayer).getHandle());
} else {
return false;
}
}
public void broadcastPacket(Packet<?> packet) {
EntityTrackerEntry tracker = getTracker();
if (tracker != null) {
tracker.broadcast(packet);
}
}
}

View File

@ -5,171 +5,20 @@
*/
package me.filoghost.holographicdisplays.nms.v1_13_R2;
import me.filoghost.fcommons.Preconditions;
import me.filoghost.fcommons.reflection.ClassToken;
import me.filoghost.fcommons.reflection.ReflectField;
import me.filoghost.fcommons.reflection.ReflectMethod;
import me.filoghost.holographicdisplays.common.hologram.StandardHologramLine;
import me.filoghost.holographicdisplays.common.hologram.StandardItemLine;
import me.filoghost.holographicdisplays.common.nms.NMSCommons;
import me.filoghost.holographicdisplays.common.nms.EntityID;
import me.filoghost.holographicdisplays.common.nms.NMSManager;
import me.filoghost.holographicdisplays.common.nms.ProtocolPacketSettings;
import me.filoghost.holographicdisplays.common.nms.SpawnFailedException;
import me.filoghost.holographicdisplays.common.nms.entity.NMSArmorStand;
import me.filoghost.holographicdisplays.common.nms.entity.NMSEntity;
import me.filoghost.holographicdisplays.common.nms.entity.NMSItem;
import net.minecraft.server.v1_13_R2.Entity;
import net.minecraft.server.v1_13_R2.EntityTypes;
import net.minecraft.server.v1_13_R2.IRegistry;
import net.minecraft.server.v1_13_R2.MathHelper;
import net.minecraft.server.v1_13_R2.RegistryID;
import net.minecraft.server.v1_13_R2.RegistryMaterials;
import net.minecraft.server.v1_13_R2.World;
import net.minecraft.server.v1_13_R2.WorldServer;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_13_R2.CraftWorld;
import org.bukkit.craftbukkit.v1_13_R2.entity.CraftEntity;
import org.bukkit.inventory.ItemStack;
import java.util.List;
import me.filoghost.holographicdisplays.common.nms.NMSPacketList;
public class VersionNMSManager implements NMSManager {
private static final ReflectField<RegistryID<EntityTypes<?>>> REGISTRY_ID_FIELD
= ReflectField.lookup(new ClassToken<RegistryID<EntityTypes<?>>>() {}, RegistryMaterials.class, "b");
private static final ReflectField<Object[]> ID_TO_CLASS_MAP_FIELD
= ReflectField.lookup(Object[].class, RegistryID.class, "d");
private static final ReflectField<List<Entity>> ENTITY_LIST_FIELD
= ReflectField.lookup(new ClassToken<List<Entity>>() {}, World.class, "entityList");
private static final ReflectMethod<?> REGISTER_ENTITY_METHOD = ReflectMethod.lookup(Object.class, World.class, "b", Entity.class);
private final ProtocolPacketSettings protocolPacketSettings;
public VersionNMSManager(ProtocolPacketSettings protocolPacketSettings) {
this.protocolPacketSettings = protocolPacketSettings;
@Override
public EntityID newEntityID() {
return null;
}
@Override
public void setup() throws Exception {
registerCustomEntity(EntityNMSSlime.class, 55);
}
public void registerCustomEntity(Class<? extends Entity> entityClass, int id) throws Exception {
// Use reflection to get the RegistryID of entities
RegistryID<EntityTypes<?>> registryID = REGISTRY_ID_FIELD.get(IRegistry.ENTITY_TYPE);
Object[] idToClassMap = ID_TO_CLASS_MAP_FIELD.get(registryID);
// Save the the ID -> EntityTypes mapping before the registration
Object oldValue = idToClassMap[id];
// Register the EntityTypes object
registryID.a(new EntityTypes<>(entityClass, world -> null, true, true, null), id);
// Restore the ID -> EntityTypes mapping
idToClassMap[id] = oldValue;
}
@Override
public NMSItem spawnNMSItem(
org.bukkit.World bukkitWorld, double x, double y, double z,
StandardItemLine parentHologramLine,
ItemStack stack) throws SpawnFailedException {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
EntityNMSItem item = new EntityNMSItem(nmsWorld, parentHologramLine);
item.setLocationNMS(x, y, z);
item.setItemStackNMS(stack);
addEntityToWorld(nmsWorld, item);
return item;
}
@Override
public EntityNMSSlime spawnNMSSlime(
org.bukkit.World bukkitWorld, double x, double y, double z,
StandardHologramLine parentHologramLine) throws SpawnFailedException {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
EntityNMSSlime slime = new EntityNMSSlime(nmsWorld, parentHologramLine);
slime.setLocationNMS(x, y, z);
addEntityToWorld(nmsWorld, slime);
return slime;
}
@Override
public NMSArmorStand spawnNMSArmorStand(
org.bukkit.World world, double x, double y, double z,
StandardHologramLine parentHologramLine) throws SpawnFailedException {
WorldServer nmsWorld = ((CraftWorld) world).getHandle();
EntityNMSArmorStand armorStand = new EntityNMSArmorStand(nmsWorld, parentHologramLine, protocolPacketSettings);
armorStand.setLocationNMS(x, y, z);
addEntityToWorld(nmsWorld, armorStand);
return armorStand;
}
private void addEntityToWorld(WorldServer nmsWorld, Entity nmsEntity) throws SpawnFailedException {
Preconditions.checkState(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.isChunkLoaded(chunkX, chunkZ, true)) { // The boolean "true" is currently unused
// This should never happen
nmsEntity.dead = true;
throw new SpawnFailedException(SpawnFailedException.CHUNK_NOT_LOADED);
}
nmsWorld.getChunkAt(chunkX, chunkZ).a(nmsEntity);
if (NMSCommons.IS_PAPER_SERVER) {
try {
// Workaround because nmsWorld.entityList is a different class in Paper,
// if used without reflection it throws NoSuchFieldError.
ENTITY_LIST_FIELD.get(nmsWorld).add(nmsEntity);
} catch (ReflectiveOperationException e) {
e.printStackTrace();
throw new SpawnFailedException(SpawnFailedException.CHUNK_NOT_LOADED);
}
} else {
nmsWorld.entityList.add(nmsEntity);
}
try {
REGISTER_ENTITY_METHOD.invoke(nmsWorld, nmsEntity);
} catch (ReflectiveOperationException e) {
nmsEntity.dead = true;
throw new SpawnFailedException(SpawnFailedException.REGISTER_ENTITY_FAIL, e);
}
}
@Override
public boolean isNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) {
return ((CraftEntity) bukkitEntity).getHandle() instanceof NMSEntity;
}
@Override
public NMSEntity getNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) {
Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle();
if (nmsEntity instanceof NMSEntity) {
return (NMSEntity) nmsEntity;
} else {
return null;
}
}
@Override
public NMSEntity getNMSEntityBaseFromID(org.bukkit.World bukkitWorld, int entityID) {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
Entity nmsEntity = nmsWorld.getEntity(entityID);
if (nmsEntity instanceof NMSEntity) {
return (NMSEntity) nmsEntity;
} else {
return null;
}
}
@Override
public Object createCustomNameNMSObject(String customName) {
return EntityNMSArmorStand.createCustomNameNMSObject(customName);
public NMSPacketList createPacketList() {
return null;
}
}

View File

@ -1,89 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_14_R1;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_14_R1.CraftServer;
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftArmorStand;
import org.bukkit.entity.Entity;
import org.bukkit.event.entity.EntityDamageEvent;
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;
import java.util.Collection;
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 ArmorStand 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; }
@Override public void setSwimming(boolean swimming) {}
// Methods from Entity class
@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 setLastDamageCause(EntityDamageEvent event) {}
@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) {}
@Override public void setPersistent(boolean flag) {}
@Override public void setRotation(float yaw, float pitch) {}
}

View File

@ -1,58 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_14_R1;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_14_R1.CraftServer;
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftItem;
import org.bukkit.entity.Entity;
import org.bukkit.event.entity.EntityDamageEvent;
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 Item class
@Override public void setItemStack(ItemStack stack) {}
@Override public void setPickupDelay(int delay) {}
// Methods from Entity class
@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 setLastDamageCause(EntityDamageEvent event) {}
@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) {}
@Override public void setPersistent(boolean flag) {}
@Override public void setRotation(float yaw, float pitch) {}
}

View File

@ -1,78 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_14_R1;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_14_R1.CraftServer;
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftSlime;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.loot.LootTable;
import org.bukkit.potion.PotionEffect;
import org.bukkit.util.Vector;
import java.util.Collection;
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 Slime class
@Override public void setSize(int size) {}
@Override public void setTarget(LivingEntity target) {}
// Methods from Mob class
@Override public void setLootTable(LootTable table) {}
@Override public void setSeed(long seed) {}
// 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; }
@Override public void setSwimming(boolean swimming) {}
// Methods from Entity class
@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 setLastDamageCause(EntityDamageEvent event) {}
@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) {}
@Override public void setPersistent(boolean flag) {}
@Override public void setRotation(float yaw, float pitch) {}
}

View File

@ -1,264 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_14_R1;
import me.filoghost.fcommons.Preconditions;
import me.filoghost.fcommons.Strings;
import me.filoghost.fcommons.reflection.ReflectField;
import me.filoghost.holographicdisplays.common.DebugLogger;
import me.filoghost.holographicdisplays.common.hologram.StandardHologramLine;
import me.filoghost.holographicdisplays.common.nms.ProtocolPacketSettings;
import me.filoghost.holographicdisplays.common.nms.entity.NMSArmorStand;
import me.filoghost.holographicdisplays.common.nms.entity.NMSEntity;
import net.minecraft.server.v1_14_R1.AxisAlignedBB;
import net.minecraft.server.v1_14_R1.DamageSource;
import net.minecraft.server.v1_14_R1.Entity;
import net.minecraft.server.v1_14_R1.EntityArmorStand;
import net.minecraft.server.v1_14_R1.EntityHuman;
import net.minecraft.server.v1_14_R1.EntityTypes;
import net.minecraft.server.v1_14_R1.EnumHand;
import net.minecraft.server.v1_14_R1.EnumInteractionResult;
import net.minecraft.server.v1_14_R1.EnumItemSlot;
import net.minecraft.server.v1_14_R1.IChatBaseComponent;
import net.minecraft.server.v1_14_R1.ItemStack;
import net.minecraft.server.v1_14_R1.NBTTagCompound;
import net.minecraft.server.v1_14_R1.PacketPlayOutEntityTeleport;
import net.minecraft.server.v1_14_R1.SoundEffect;
import net.minecraft.server.v1_14_R1.Vec3D;
import net.minecraft.server.v1_14_R1.World;
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_14_R1.util.CraftChatMessage;
import org.bukkit.entity.Player;
import java.util.Objects;
public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorStand {
private static final ReflectField<Entity> VEHICLE_FIELD = ReflectField.lookup(Entity.class, Entity.class, "vehicle");
private final StandardHologramLine parentHologramLine;
private final ProtocolPacketSettings protocolPacketSettings;
private final VersionNMSEntityHelper helper;
private CraftEntity customBukkitEntity;
private String customName;
public EntityNMSArmorStand(World world, StandardHologramLine parentHologramLine, ProtocolPacketSettings protocolPacketSettings) {
super(EntityTypes.ARMOR_STAND, world);
this.parentHologramLine = parentHologramLine;
this.protocolPacketSettings = protocolPacketSettings;
this.helper = new VersionNMSEntityHelper(this);
super.setInvisible(true);
super.setSmall(true);
super.setArms(false);
super.setNoGravity(true);
super.setBasePlate(true);
super.setMarker(true);
super.collides = false;
super.onGround = true; // Workaround to force EntityTrackerEntry to send a teleport packet
forceSetBoundingBox(new NullBoundingBox());
}
@Override
public void tick() {
// Disable normal ticking for this entity
// Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity
if (super.onGround) {
super.onGround = false;
}
}
@Override
public void inactiveTick() {
// Disable normal ticking for this entity
// Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity
if (super.onGround) {
super.onGround = false;
}
}
@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(IChatBaseComponent ichatbasecomponent) {
// Prevents changes to custom name
}
@Override
public void setCustomNameVisible(boolean visible) {
// Prevents changes to custom name visibility
}
@Override
public EnumInteractionResult a(EntityHuman human, Vec3D vec3d, EnumHand enumhand) {
// Prevent armor stand from being equipped
return EnumInteractionResult.PASS;
}
@Override
public boolean a_(int i, ItemStack item) {
// Prevent armor stand from being equipped
return false;
}
@Override
public void setSlot(EnumItemSlot enumitemslot, ItemStack itemstack) {
// Prevent armor stand from being equipped
}
@Override
public void a(AxisAlignedBB boundingBox) {
// Prevent changes to bounding box
}
public void forceSetBoundingBox(AxisAlignedBB boundingBox) {
super.a(boundingBox);
}
@Override
public void a(SoundEffect soundeffect, float f, float f1) {
// Remove sounds
}
@Override
public void setCustomNameNMS(String customName) {
if (Objects.equals(this.customName, customName)) {
return;
}
this.customName = customName;
super.setCustomName(createCustomNameNMSObject(customName));
super.setCustomNameVisible(customName != null && !customName.isEmpty());
}
protected static IChatBaseComponent createCustomNameNMSObject(String customName) {
return CraftChatMessage.fromStringOrNull(Strings.truncate(customName, 300));
}
@Override
public String getCustomNameStringNMS() {
return this.customName;
}
@Override
public IChatBaseComponent getCustomNameObjectNMS() {
return super.getCustomName();
}
@Override
public void die() {
// Prevent entity from dying
}
@Override
public CraftEntity getBukkitEntity() {
if (customBukkitEntity == null) {
customBukkitEntity = new CraftNMSArmorStand(super.world.getServer(), this);
}
return customBukkitEntity;
}
@Override
public void killEntityNMS() {
super.dead = true;
}
@Override
public void setLocationNMS(double x, double y, double z) {
super.setPosition(x, y, z);
if (protocolPacketSettings.sendAccurateLocationPackets()) {
helper.broadcastPacket(new PacketPlayOutEntityTeleport(this));
}
}
@Override
public void setPassengerNMS(NMSEntity passenger) {
Preconditions.checkArgument(passenger instanceof Entity);
Entity passengerEntity = (Entity) passenger;
Preconditions.checkArgument(passengerEntity.getVehicle() == null);
Preconditions.checkState(super.passengers.isEmpty());
try {
VEHICLE_FIELD.set(passenger, this);
this.passengers.add(passengerEntity);
} catch (ReflectiveOperationException e) {
DebugLogger.cannotSetPassenger(e);
}
}
@Override
public boolean isDeadNMS() {
return super.dead;
}
@Override
public int getIdNMS() {
return super.getId();
}
@Override
public StandardHologramLine getHologramLine() {
return parentHologramLine;
}
@Override
public org.bukkit.entity.Entity getBukkitEntityNMS() {
return getBukkitEntity();
}
@Override
public boolean isTrackedBy(Player bukkitPlayer) {
return helper.isTrackedBy(bukkitPlayer);
}
}

View File

@ -1,201 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_14_R1;
import me.filoghost.holographicdisplays.common.hologram.StandardHologramLine;
import me.filoghost.holographicdisplays.common.hologram.StandardItemLine;
import me.filoghost.holographicdisplays.common.nms.NMSCommons;
import me.filoghost.holographicdisplays.common.nms.entity.NMSItem;
import net.minecraft.server.v1_14_R1.Blocks;
import net.minecraft.server.v1_14_R1.DamageSource;
import net.minecraft.server.v1_14_R1.EntityHuman;
import net.minecraft.server.v1_14_R1.EntityItem;
import net.minecraft.server.v1_14_R1.EntityPlayer;
import net.minecraft.server.v1_14_R1.EntityTypes;
import net.minecraft.server.v1_14_R1.ItemStack;
import net.minecraft.server.v1_14_R1.NBTTagCompound;
import net.minecraft.server.v1_14_R1.NBTTagList;
import net.minecraft.server.v1_14_R1.NBTTagString;
import net.minecraft.server.v1_14_R1.World;
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftItemStack;
import org.bukkit.entity.Player;
public class EntityNMSItem extends EntityItem implements NMSItem {
private final StandardItemLine parentHologramLine;
private final VersionNMSEntityHelper helper;
private CraftEntity customBukkitEntity;
public EntityNMSItem(World world, StandardItemLine parentHologramLine) {
super(EntityTypes.ITEM, world);
this.parentHologramLine = parentHologramLine;
this.helper = new VersionNMSEntityHelper(this);
super.pickupDelay = 32767; // Lock the item pickup delay, also prevents entities from picking up the item
}
@Override
public void tick() {
// Disable normal ticking for this entity
// So it won't get removed
ticksLived = 0;
}
@Override
public void inactiveTick() {
// Disable normal ticking for this entity
// So it won't get removed
ticksLived = 0;
}
// Method called when a player is near
@Override
public void pickup(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 (human instanceof EntityPlayer) {
parentHologramLine.onPickup(((EntityPlayer) human).getBukkitEntity());
// 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 die() {
// Prevent entity from dying
}
@Override
public boolean isAlive() {
// This override prevents items from being picked up by hoppers (should have no side effects)
return false;
}
@Override
public CraftEntity getBukkitEntity() {
if (customBukkitEntity == null) {
customBukkitEntity = new CraftNMSItem(super.world.getServer(), this);
}
return customBukkitEntity;
}
@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 == ItemStack.a) { // ItemStack.a is returned if the stack is not valid
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(NMSCommons.ANTI_STACK_LORE));
display.set("Lore", tagList);
super.setItemStack(newItem);
}
@Override
public int getIdNMS() {
return super.getId();
}
@Override
public StandardHologramLine getHologramLine() {
return parentHologramLine;
}
@Override
public org.bukkit.entity.Entity getBukkitEntityNMS() {
return getBukkitEntity();
}
@Override
public boolean isTrackedBy(Player bukkitPlayer) {
return helper.isTrackedBy(bukkitPlayer);
}
@Override
public Object getRawItemStack() {
return super.getItemStack();
}
}

View File

@ -1,193 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_14_R1;
import me.filoghost.holographicdisplays.common.hologram.StandardHologramLine;
import me.filoghost.holographicdisplays.common.nms.entity.NMSSlime;
import net.minecraft.server.v1_14_R1.AxisAlignedBB;
import net.minecraft.server.v1_14_R1.DamageSource;
import net.minecraft.server.v1_14_R1.EntityDamageSource;
import net.minecraft.server.v1_14_R1.EntityPlayer;
import net.minecraft.server.v1_14_R1.EntitySlime;
import net.minecraft.server.v1_14_R1.EntityTypes;
import net.minecraft.server.v1_14_R1.IChatBaseComponent;
import net.minecraft.server.v1_14_R1.NBTTagCompound;
import net.minecraft.server.v1_14_R1.SoundEffect;
import net.minecraft.server.v1_14_R1.World;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerInteractEntityEvent;
public class EntityNMSSlime extends EntitySlime implements NMSSlime {
private final StandardHologramLine parentHologramLine;
private final VersionNMSEntityHelper helper;
private CraftEntity customBukkitEntity;
public EntityNMSSlime(World world, StandardHologramLine parentHologramLine) {
super(EntityTypes.SLIME, world);
this.parentHologramLine = parentHologramLine;
this.helper = new VersionNMSEntityHelper(this);
super.persistent = true;
super.collides = false;
super.a(0.0F, 0.0F);
super.setSize(1, false);
super.setInvisible(true);
forceSetBoundingBox(new NullBoundingBox());
}
@Override
public void tick() {
// Disable normal ticking for this entity
// So it won't get removed
ticksLived = 0;
}
@Override
public void inactiveTick() {
// Disable normal ticking for this entity
// So it won't get removed
ticksLived = 0;
}
@Override
public void a(AxisAlignedBB boundingBox) {
// Prevent changes to bounding box
}
public void forceSetBoundingBox(AxisAlignedBB boundingBox) {
super.a(boundingBox);
}
@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) {
Player player = ((EntityPlayer) entityDamageSource.getEntity()).getBukkitEntity();
PlayerInteractEntityEvent event = new PlayerInteractEntityEvent(player, getBukkitEntity());
Bukkit.getPluginManager().callEvent(event); // 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 setCustomName(IChatBaseComponent ichatbasecomponent) {
// Prevents changes to custom name
}
@Override
public void setCustomNameVisible(boolean visible) {
// Prevents changes to custom name visibility
}
@Override
public void a(SoundEffect soundeffect, float f, float f1) {
// Remove sounds
}
@Override
public void die() {
// Prevent entity from dying
}
@Override
public CraftEntity getBukkitEntity() {
if (customBukkitEntity == null) {
customBukkitEntity = new CraftNMSSlime(super.world.getServer(), this);
}
return customBukkitEntity;
}
@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 StandardHologramLine getHologramLine() {
return parentHologramLine;
}
@Override
public org.bukkit.entity.Entity getBukkitEntityNMS() {
return getBukkitEntity();
}
@Override
public boolean isTrackedBy(Player bukkitPlayer) {
return helper.isTrackedBy(bukkitPlayer);
}
}

View File

@ -1,124 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_14_R1;
import net.minecraft.server.v1_14_R1.AxisAlignedBB;
import net.minecraft.server.v1_14_R1.BlockPosition;
import net.minecraft.server.v1_14_R1.EnumDirection.EnumAxis;
import net.minecraft.server.v1_14_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 AxisAlignedBB a(AxisAlignedBB arg0) {
return this;
}
@Override
public AxisAlignedBB a(double arg0, double arg1, double arg2) {
return this;
}
@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 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 double a(EnumAxis arg0) {
return 0.0;
}
@Override
public double b(EnumAxis arg0) {
return 0.0;
}
@Override
public boolean e(double arg0, double arg1, double arg2) {
return false;
}
@Override
public double b() {
return 0.0;
}
@Override
public double c() {
return 0.0;
}
@Override
public double d() {
return 0.0;
}
@Override
public boolean c(Vec3D var0) {
return false;
}
@Override
public Vec3D f() {
return Vec3D.a;
}
}

View File

@ -1,46 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_14_R1;
import me.filoghost.holographicdisplays.common.nms.entity.NMSEntityHelper;
import net.minecraft.server.v1_14_R1.Entity;
import net.minecraft.server.v1_14_R1.Packet;
import net.minecraft.server.v1_14_R1.PlayerChunkMap.EntityTracker;
import net.minecraft.server.v1_14_R1.WorldServer;
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
public class VersionNMSEntityHelper extends NMSEntityHelper<EntityTracker> {
private final Entity entity;
public VersionNMSEntityHelper(Entity entity) {
this.entity = entity;
}
@Override
protected EntityTracker getTracker0() {
return ((WorldServer) entity.world).getChunkProvider().playerChunkMap.trackedEntities.get(entity.getId());
}
@Override
public boolean isTrackedBy(Player bukkitPlayer) {
EntityTracker tracker = getTracker();
if (tracker != null) {
return tracker.trackedPlayers.contains(((CraftPlayer) bukkitPlayer).getHandle());
} else {
return false;
}
}
public void broadcastPacket(Packet<?> packet) {
EntityTracker tracker = getTracker();
if (tracker != null) {
tracker.broadcast(packet);
}
}
}

View File

@ -5,154 +5,20 @@
*/
package me.filoghost.holographicdisplays.nms.v1_14_R1;
import me.filoghost.fcommons.Preconditions;
import me.filoghost.fcommons.reflection.ClassToken;
import me.filoghost.fcommons.reflection.ReflectField;
import me.filoghost.fcommons.reflection.ReflectMethod;
import me.filoghost.holographicdisplays.common.hologram.StandardHologramLine;
import me.filoghost.holographicdisplays.common.hologram.StandardItemLine;
import me.filoghost.holographicdisplays.common.nms.EntityID;
import me.filoghost.holographicdisplays.common.nms.NMSManager;
import me.filoghost.holographicdisplays.common.nms.ProtocolPacketSettings;
import me.filoghost.holographicdisplays.common.nms.SpawnFailedException;
import me.filoghost.holographicdisplays.common.nms.entity.NMSArmorStand;
import me.filoghost.holographicdisplays.common.nms.entity.NMSEntity;
import me.filoghost.holographicdisplays.common.nms.entity.NMSItem;
import net.minecraft.server.v1_14_R1.Entity;
import net.minecraft.server.v1_14_R1.EntityTypes;
import net.minecraft.server.v1_14_R1.EnumCreatureType;
import net.minecraft.server.v1_14_R1.IRegistry;
import net.minecraft.server.v1_14_R1.MathHelper;
import net.minecraft.server.v1_14_R1.RegistryID;
import net.minecraft.server.v1_14_R1.RegistryMaterials;
import net.minecraft.server.v1_14_R1.WorldServer;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_14_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftEntity;
import org.bukkit.inventory.ItemStack;
import me.filoghost.holographicdisplays.common.nms.NMSPacketList;
public class VersionNMSManager implements NMSManager {
private static final ReflectField<RegistryID<EntityTypes<?>>> REGISTRY_ID_FIELD
= ReflectField.lookup(new ClassToken<RegistryID<EntityTypes<?>>>() {}, RegistryMaterials.class, "b");
private static final ReflectField<Object[]> ID_TO_CLASS_MAP_FIELD
= ReflectField.lookup(Object[].class, RegistryID.class, "d");
private static final ReflectMethod<Void> REGISTER_ENTITY_METHOD
= ReflectMethod.lookup(void.class, WorldServer.class, "registerEntity", Entity.class);
private final ProtocolPacketSettings protocolPacketSettings;
public VersionNMSManager(ProtocolPacketSettings protocolPacketSettings) {
this.protocolPacketSettings = protocolPacketSettings;
@Override
public EntityID newEntityID() {
return null;
}
@Override
public void setup() throws Exception {
registerCustomEntity(EntityNMSSlime.class, 55, 2.04f, 2.04f);
}
public void registerCustomEntity(Class<? extends Entity> entityClass, int id, float sizeWidth, float sizeHeight) throws Exception {
// Use reflection to get the RegistryID of entities
RegistryID<EntityTypes<?>> registryID = REGISTRY_ID_FIELD.get(IRegistry.ENTITY_TYPE);
Object[] idToClassMap = ID_TO_CLASS_MAP_FIELD.get(registryID);
// Save the the ID -> EntityTypes mapping before the registration
Object oldValue = idToClassMap[id];
// Register the EntityTypes object
registryID.a(EntityTypes.a.a(EnumCreatureType.MONSTER).a(sizeWidth, sizeHeight).b().a((String) null), id);
// Restore the ID -> EntityTypes mapping
idToClassMap[id] = oldValue;
}
@Override
public NMSItem spawnNMSItem(
World bukkitWorld, double x, double y, double z,
StandardItemLine parentHologramLine,
ItemStack stack) throws SpawnFailedException {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
EntityNMSItem item = new EntityNMSItem(nmsWorld, parentHologramLine);
item.setLocationNMS(x, y, z);
item.setItemStackNMS(stack);
addEntityToWorld(nmsWorld, item);
return item;
}
@Override
public EntityNMSSlime spawnNMSSlime(
World bukkitWorld, double x, double y, double z,
StandardHologramLine parentHologramLine) throws SpawnFailedException {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
EntityNMSSlime slime = new EntityNMSSlime(nmsWorld, parentHologramLine);
slime.setLocationNMS(x, y, z);
addEntityToWorld(nmsWorld, slime);
return slime;
}
@Override
public NMSArmorStand spawnNMSArmorStand(
World world, double x, double y, double z,
StandardHologramLine parentHologramLine) throws SpawnFailedException {
WorldServer nmsWorld = ((CraftWorld) world).getHandle();
EntityNMSArmorStand armorStand = new EntityNMSArmorStand(nmsWorld, parentHologramLine, protocolPacketSettings);
armorStand.setLocationNMS(x, y, z);
addEntityToWorld(nmsWorld, armorStand);
return armorStand;
}
private void addEntityToWorld(WorldServer nmsWorld, Entity nmsEntity) throws SpawnFailedException {
Preconditions.checkState(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.isChunkLoaded(chunkX, chunkZ)) {
// This should never happen
nmsEntity.dead = true;
throw new SpawnFailedException(SpawnFailedException.CHUNK_NOT_LOADED);
}
nmsWorld.getChunkAt(chunkX, chunkZ).a(nmsEntity);
try {
REGISTER_ENTITY_METHOD.invoke(nmsWorld, nmsEntity);
} catch (ReflectiveOperationException e) {
nmsEntity.dead = true;
throw new SpawnFailedException(SpawnFailedException.REGISTER_ENTITY_FAIL, e);
}
}
@Override
public boolean isNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) {
return ((CraftEntity) bukkitEntity).getHandle() instanceof NMSEntity;
}
@Override
public NMSEntity getNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) {
Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle();
if (nmsEntity instanceof NMSEntity) {
return (NMSEntity) nmsEntity;
} else {
return null;
}
}
@Override
public NMSEntity getNMSEntityBaseFromID(org.bukkit.World bukkitWorld, int entityID) {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
Entity nmsEntity = nmsWorld.getEntity(entityID);
if (nmsEntity instanceof NMSEntity) {
return (NMSEntity) nmsEntity;
} else {
return null;
}
}
@Override
public Object createCustomNameNMSObject(String customName) {
return EntityNMSArmorStand.createCustomNameNMSObject(customName);
public NMSPacketList createPacketList() {
return null;
}
}

View File

@ -1,89 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_15_R1;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_15_R1.CraftServer;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftArmorStand;
import org.bukkit.entity.Entity;
import org.bukkit.event.entity.EntityDamageEvent;
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;
import java.util.Collection;
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 ArmorStand 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; }
@Override public void setSwimming(boolean swimming) {}
// Methods from Entity class
@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 setLastDamageCause(EntityDamageEvent event) {}
@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) {}
@Override public void setPersistent(boolean flag) {}
@Override public void setRotation(float yaw, float pitch) {}
}

View File

@ -1,58 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_15_R1;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_15_R1.CraftServer;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftItem;
import org.bukkit.entity.Entity;
import org.bukkit.event.entity.EntityDamageEvent;
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 Item class
@Override public void setItemStack(ItemStack stack) {}
@Override public void setPickupDelay(int delay) {}
// Methods from Entity class
@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 setLastDamageCause(EntityDamageEvent event) {}
@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) {}
@Override public void setPersistent(boolean flag) {}
@Override public void setRotation(float yaw, float pitch) {}
}

View File

@ -1,78 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_15_R1;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_15_R1.CraftServer;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftSlime;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.loot.LootTable;
import org.bukkit.potion.PotionEffect;
import org.bukkit.util.Vector;
import java.util.Collection;
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 Slime class
@Override public void setSize(int size) {}
@Override public void setTarget(LivingEntity target) {}
// Methods from Mob class
@Override public void setLootTable(LootTable table) {}
@Override public void setSeed(long seed) {}
// 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; }
@Override public void setSwimming(boolean swimming) {}
// Methods from Entity class
@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 setLastDamageCause(EntityDamageEvent event) {}
@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) {}
@Override public void setPersistent(boolean flag) {}
@Override public void setRotation(float yaw, float pitch) {}
}

View File

@ -1,264 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_15_R1;
import me.filoghost.fcommons.Preconditions;
import me.filoghost.fcommons.Strings;
import me.filoghost.fcommons.reflection.ReflectField;
import me.filoghost.holographicdisplays.common.DebugLogger;
import me.filoghost.holographicdisplays.common.hologram.StandardHologramLine;
import me.filoghost.holographicdisplays.common.nms.ProtocolPacketSettings;
import me.filoghost.holographicdisplays.common.nms.entity.NMSArmorStand;
import me.filoghost.holographicdisplays.common.nms.entity.NMSEntity;
import net.minecraft.server.v1_15_R1.AxisAlignedBB;
import net.minecraft.server.v1_15_R1.DamageSource;
import net.minecraft.server.v1_15_R1.Entity;
import net.minecraft.server.v1_15_R1.EntityArmorStand;
import net.minecraft.server.v1_15_R1.EntityHuman;
import net.minecraft.server.v1_15_R1.EntityTypes;
import net.minecraft.server.v1_15_R1.EnumHand;
import net.minecraft.server.v1_15_R1.EnumInteractionResult;
import net.minecraft.server.v1_15_R1.EnumItemSlot;
import net.minecraft.server.v1_15_R1.IChatBaseComponent;
import net.minecraft.server.v1_15_R1.ItemStack;
import net.minecraft.server.v1_15_R1.NBTTagCompound;
import net.minecraft.server.v1_15_R1.PacketPlayOutEntityTeleport;
import net.minecraft.server.v1_15_R1.SoundEffect;
import net.minecraft.server.v1_15_R1.Vec3D;
import net.minecraft.server.v1_15_R1.World;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_15_R1.util.CraftChatMessage;
import org.bukkit.entity.Player;
import java.util.Objects;
public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorStand {
private static final ReflectField<Entity> VEHICLE_FIELD = ReflectField.lookup(Entity.class, Entity.class, "vehicle");
private final StandardHologramLine parentHologramLine;
private final ProtocolPacketSettings protocolPacketSettings;
private final VersionNMSEntityHelper helper;
private CraftEntity customBukkitEntity;
private String customName;
public EntityNMSArmorStand(World world, StandardHologramLine parentHologramLine, ProtocolPacketSettings protocolPacketSettings) {
super(EntityTypes.ARMOR_STAND, world);
this.parentHologramLine = parentHologramLine;
this.protocolPacketSettings = protocolPacketSettings;
this.helper = new VersionNMSEntityHelper(this);
super.setInvisible(true);
super.setSmall(true);
super.setArms(false);
super.setNoGravity(true);
super.setBasePlate(true);
super.setMarker(true);
super.collides = false;
super.onGround = true; // Workaround to force EntityTrackerEntry to send a teleport packet
forceSetBoundingBox(new NullBoundingBox());
}
@Override
public void tick() {
// Disable normal ticking for this entity
// Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity
if (super.onGround) {
super.onGround = false;
}
}
@Override
public void inactiveTick() {
// Disable normal ticking for this entity
// Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity
if (super.onGround) {
super.onGround = false;
}
}
@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(IChatBaseComponent ichatbasecomponent) {
// Prevents changes to custom name
}
@Override
public void setCustomNameVisible(boolean visible) {
// Prevents changes to custom name visibility
}
@Override
public EnumInteractionResult a(EntityHuman human, Vec3D vec3d, EnumHand enumhand) {
// Prevent armor stand from being equipped
return EnumInteractionResult.PASS;
}
@Override
public boolean a_(int i, ItemStack item) {
// Prevent armor stand from being equipped
return false;
}
@Override
public void setSlot(EnumItemSlot enumitemslot, ItemStack itemstack) {
// Prevent armor stand from being equipped
}
@Override
public void a(AxisAlignedBB boundingBox) {
// Prevent changes to bounding box
}
public void forceSetBoundingBox(AxisAlignedBB boundingBox) {
super.a(boundingBox);
}
@Override
public void a(SoundEffect soundeffect, float f, float f1) {
// Remove sounds
}
@Override
public void setCustomNameNMS(String customName) {
if (Objects.equals(this.customName, customName)) {
return;
}
this.customName = customName;
super.setCustomName(createCustomNameNMSObject(customName));
super.setCustomNameVisible(customName != null && !customName.isEmpty());
}
protected static IChatBaseComponent createCustomNameNMSObject(String customName) {
return CraftChatMessage.fromStringOrNull(Strings.truncate(customName, 300));
}
@Override
public String getCustomNameStringNMS() {
return this.customName;
}
@Override
public IChatBaseComponent getCustomNameObjectNMS() {
return super.getCustomName();
}
@Override
public void die() {
// Prevent entity from dying
}
@Override
public CraftEntity getBukkitEntity() {
if (customBukkitEntity == null) {
customBukkitEntity = new CraftNMSArmorStand(super.world.getServer(), this);
}
return customBukkitEntity;
}
@Override
public void killEntityNMS() {
super.dead = true;
}
@Override
public void setLocationNMS(double x, double y, double z) {
super.setPosition(x, y, z);
if (protocolPacketSettings.sendAccurateLocationPackets()) {
helper.broadcastPacket(new PacketPlayOutEntityTeleport(this));
}
}
@Override
public void setPassengerNMS(NMSEntity passenger) {
Preconditions.checkArgument(passenger instanceof Entity);
Entity passengerEntity = (Entity) passenger;
Preconditions.checkArgument(passengerEntity.getVehicle() == null);
Preconditions.checkState(super.passengers.isEmpty());
try {
VEHICLE_FIELD.set(passenger, this);
this.passengers.add(passengerEntity);
} catch (ReflectiveOperationException e) {
DebugLogger.cannotSetPassenger(e);
}
}
@Override
public boolean isDeadNMS() {
return super.dead;
}
@Override
public int getIdNMS() {
return super.getId();
}
@Override
public StandardHologramLine getHologramLine() {
return parentHologramLine;
}
@Override
public org.bukkit.entity.Entity getBukkitEntityNMS() {
return getBukkitEntity();
}
@Override
public boolean isTrackedBy(Player bukkitPlayer) {
return helper.isTrackedBy(bukkitPlayer);
}
}

View File

@ -1,201 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_15_R1;
import me.filoghost.holographicdisplays.common.hologram.StandardHologramLine;
import me.filoghost.holographicdisplays.common.hologram.StandardItemLine;
import me.filoghost.holographicdisplays.common.nms.NMSCommons;
import me.filoghost.holographicdisplays.common.nms.entity.NMSItem;
import net.minecraft.server.v1_15_R1.Blocks;
import net.minecraft.server.v1_15_R1.DamageSource;
import net.minecraft.server.v1_15_R1.EntityHuman;
import net.minecraft.server.v1_15_R1.EntityItem;
import net.minecraft.server.v1_15_R1.EntityPlayer;
import net.minecraft.server.v1_15_R1.EntityTypes;
import net.minecraft.server.v1_15_R1.ItemStack;
import net.minecraft.server.v1_15_R1.NBTTagCompound;
import net.minecraft.server.v1_15_R1.NBTTagList;
import net.minecraft.server.v1_15_R1.NBTTagString;
import net.minecraft.server.v1_15_R1.World;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack;
import org.bukkit.entity.Player;
public class EntityNMSItem extends EntityItem implements NMSItem {
private final StandardItemLine parentHologramLine;
private final VersionNMSEntityHelper helper;
private CraftEntity customBukkitEntity;
public EntityNMSItem(World world, StandardItemLine parentHologramLine) {
super(EntityTypes.ITEM, world);
this.parentHologramLine = parentHologramLine;
this.helper = new VersionNMSEntityHelper(this);
super.pickupDelay = 32767; // Lock the item pickup delay, also prevents entities from picking up the item
}
@Override
public void tick() {
// Disable normal ticking for this entity
// So it won't get removed
ticksLived = 0;
}
@Override
public void inactiveTick() {
// Disable normal ticking for this entity
// So it won't get removed
ticksLived = 0;
}
// Method called when a player is near
@Override
public void pickup(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 (human instanceof EntityPlayer) {
parentHologramLine.onPickup(((EntityPlayer) human).getBukkitEntity());
// 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 die() {
// Prevent entity from dying
}
@Override
public boolean isAlive() {
// This override prevents items from being picked up by hoppers (should have no side effects)
return false;
}
@Override
public CraftEntity getBukkitEntity() {
if (customBukkitEntity == null) {
customBukkitEntity = new CraftNMSItem(super.world.getServer(), this);
}
return customBukkitEntity;
}
@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 == ItemStack.a) { // ItemStack.a is returned if the stack is not valid
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(NBTTagString.a(NMSCommons.ANTI_STACK_LORE));
display.set("Lore", tagList);
super.setItemStack(newItem);
}
@Override
public int getIdNMS() {
return super.getId();
}
@Override
public StandardHologramLine getHologramLine() {
return parentHologramLine;
}
@Override
public org.bukkit.entity.Entity getBukkitEntityNMS() {
return getBukkitEntity();
}
@Override
public boolean isTrackedBy(Player bukkitPlayer) {
return helper.isTrackedBy(bukkitPlayer);
}
@Override
public Object getRawItemStack() {
return super.getItemStack();
}
}

View File

@ -1,193 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_15_R1;
import me.filoghost.holographicdisplays.common.hologram.StandardHologramLine;
import me.filoghost.holographicdisplays.common.nms.entity.NMSSlime;
import net.minecraft.server.v1_15_R1.AxisAlignedBB;
import net.minecraft.server.v1_15_R1.DamageSource;
import net.minecraft.server.v1_15_R1.EntityDamageSource;
import net.minecraft.server.v1_15_R1.EntityPlayer;
import net.minecraft.server.v1_15_R1.EntitySlime;
import net.minecraft.server.v1_15_R1.EntityTypes;
import net.minecraft.server.v1_15_R1.IChatBaseComponent;
import net.minecraft.server.v1_15_R1.NBTTagCompound;
import net.minecraft.server.v1_15_R1.SoundEffect;
import net.minecraft.server.v1_15_R1.World;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerInteractEntityEvent;
public class EntityNMSSlime extends EntitySlime implements NMSSlime {
private final StandardHologramLine parentHologramLine;
private final VersionNMSEntityHelper helper;
private CraftEntity customBukkitEntity;
public EntityNMSSlime(World world, StandardHologramLine parentHologramLine) {
super(EntityTypes.SLIME, world);
this.parentHologramLine = parentHologramLine;
this.helper = new VersionNMSEntityHelper(this);
super.persistent = true;
super.collides = false;
super.a(0.0F, 0.0F);
super.setSize(1, false);
super.setInvisible(true);
forceSetBoundingBox(new NullBoundingBox());
}
@Override
public void tick() {
// Disable normal ticking for this entity
// So it won't get removed
ticksLived = 0;
}
@Override
public void inactiveTick() {
// Disable normal ticking for this entity
// So it won't get removed
ticksLived = 0;
}
@Override
public void a(AxisAlignedBB boundingBox) {
// Prevent changes to bounding box
}
public void forceSetBoundingBox(AxisAlignedBB boundingBox) {
super.a(boundingBox);
}
@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) {
Player player = ((EntityPlayer) entityDamageSource.getEntity()).getBukkitEntity();
PlayerInteractEntityEvent event = new PlayerInteractEntityEvent(player, getBukkitEntity());
Bukkit.getPluginManager().callEvent(event); // 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 setCustomName(IChatBaseComponent ichatbasecomponent) {
// Prevents changes to custom name
}
@Override
public void setCustomNameVisible(boolean visible) {
// Prevents changes to custom name visibility
}
@Override
public void a(SoundEffect soundeffect, float f, float f1) {
// Remove sounds
}
@Override
public void die() {
// Prevent entity from dying
}
@Override
public CraftEntity getBukkitEntity() {
if (customBukkitEntity == null) {
customBukkitEntity = new CraftNMSSlime(super.world.getServer(), this);
}
return customBukkitEntity;
}
@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 StandardHologramLine getHologramLine() {
return parentHologramLine;
}
@Override
public org.bukkit.entity.Entity getBukkitEntityNMS() {
return getBukkitEntity();
}
@Override
public boolean isTrackedBy(Player bukkitPlayer) {
return helper.isTrackedBy(bukkitPlayer);
}
}

View File

@ -1,124 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_15_R1;
import net.minecraft.server.v1_15_R1.AxisAlignedBB;
import net.minecraft.server.v1_15_R1.BlockPosition;
import net.minecraft.server.v1_15_R1.EnumDirection.EnumAxis;
import net.minecraft.server.v1_15_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 AxisAlignedBB a(AxisAlignedBB arg0) {
return this;
}
@Override
public AxisAlignedBB a(double arg0, double arg1, double arg2) {
return this;
}
@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 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 double a(EnumAxis arg0) {
return 0.0;
}
@Override
public double b(EnumAxis arg0) {
return 0.0;
}
@Override
public boolean e(double arg0, double arg1, double arg2) {
return false;
}
@Override
public double b() {
return 0.0;
}
@Override
public double c() {
return 0.0;
}
@Override
public double d() {
return 0.0;
}
@Override
public boolean c(Vec3D var0) {
return false;
}
@Override
public Vec3D f() {
return Vec3D.a;
}
}

View File

@ -1,46 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_15_R1;
import me.filoghost.holographicdisplays.common.nms.entity.NMSEntityHelper;
import net.minecraft.server.v1_15_R1.Entity;
import net.minecraft.server.v1_15_R1.Packet;
import net.minecraft.server.v1_15_R1.PlayerChunkMap.EntityTracker;
import net.minecraft.server.v1_15_R1.WorldServer;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
public class VersionNMSEntityHelper extends NMSEntityHelper<EntityTracker> {
private final Entity entity;
public VersionNMSEntityHelper(Entity entity) {
this.entity = entity;
}
@Override
protected EntityTracker getTracker0() {
return ((WorldServer) entity.world).getChunkProvider().playerChunkMap.trackedEntities.get(entity.getId());
}
@Override
public boolean isTrackedBy(Player bukkitPlayer) {
EntityTracker tracker = getTracker();
if (tracker != null) {
return tracker.trackedPlayers.contains(((CraftPlayer) bukkitPlayer).getHandle());
} else {
return false;
}
}
public void broadcastPacket(Packet<?> packet) {
EntityTracker tracker = getTracker();
if (tracker != null) {
tracker.broadcast(packet);
}
}
}

View File

@ -5,154 +5,20 @@
*/
package me.filoghost.holographicdisplays.nms.v1_15_R1;
import me.filoghost.fcommons.Preconditions;
import me.filoghost.fcommons.reflection.ClassToken;
import me.filoghost.fcommons.reflection.ReflectField;
import me.filoghost.fcommons.reflection.ReflectMethod;
import me.filoghost.holographicdisplays.common.hologram.StandardHologramLine;
import me.filoghost.holographicdisplays.common.hologram.StandardItemLine;
import me.filoghost.holographicdisplays.common.nms.EntityID;
import me.filoghost.holographicdisplays.common.nms.NMSManager;
import me.filoghost.holographicdisplays.common.nms.ProtocolPacketSettings;
import me.filoghost.holographicdisplays.common.nms.SpawnFailedException;
import me.filoghost.holographicdisplays.common.nms.entity.NMSArmorStand;
import me.filoghost.holographicdisplays.common.nms.entity.NMSEntity;
import me.filoghost.holographicdisplays.common.nms.entity.NMSItem;
import net.minecraft.server.v1_15_R1.Entity;
import net.minecraft.server.v1_15_R1.EntityTypes;
import net.minecraft.server.v1_15_R1.EnumCreatureType;
import net.minecraft.server.v1_15_R1.IRegistry;
import net.minecraft.server.v1_15_R1.MathHelper;
import net.minecraft.server.v1_15_R1.RegistryID;
import net.minecraft.server.v1_15_R1.RegistryMaterials;
import net.minecraft.server.v1_15_R1.WorldServer;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_15_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftEntity;
import org.bukkit.inventory.ItemStack;
import me.filoghost.holographicdisplays.common.nms.NMSPacketList;
public class VersionNMSManager implements NMSManager {
private static final ReflectField<RegistryID<EntityTypes<?>>> REGISTRY_ID_FIELD
= ReflectField.lookup(new ClassToken<RegistryID<EntityTypes<?>>>() {}, RegistryMaterials.class, "b");
private static final ReflectField<Object[]> ID_TO_CLASS_MAP_FIELD
= ReflectField.lookup(Object[].class, RegistryID.class, "d");
private static final ReflectMethod<Void> REGISTER_ENTITY_METHOD
= ReflectMethod.lookup(void.class, WorldServer.class, "registerEntity", Entity.class);
private final ProtocolPacketSettings protocolPacketSettings;
public VersionNMSManager(ProtocolPacketSettings protocolPacketSettings) {
this.protocolPacketSettings = protocolPacketSettings;
@Override
public EntityID newEntityID() {
return null;
}
@Override
public void setup() throws Exception {
registerCustomEntity(EntityNMSSlime.class, 55, 2.04f, 2.04f);
}
public void registerCustomEntity(Class<? extends Entity> entityClass, int id, float sizeWidth, float sizeHeight) throws Exception {
// Use reflection to get the RegistryID of entities
RegistryID<EntityTypes<?>> registryID = REGISTRY_ID_FIELD.get(IRegistry.ENTITY_TYPE);
Object[] idToClassMap = ID_TO_CLASS_MAP_FIELD.get(registryID);
// Save the the ID -> EntityTypes mapping before the registration
Object oldValue = idToClassMap[id];
// Register the EntityTypes object
registryID.a(EntityTypes.a.a(EnumCreatureType.MONSTER).a(sizeWidth, sizeHeight).b().a((String) null), id);
// Restore the ID -> EntityTypes mapping
idToClassMap[id] = oldValue;
}
@Override
public NMSItem spawnNMSItem(
World bukkitWorld, double x, double y, double z,
StandardItemLine parentHologramLine,
ItemStack stack) throws SpawnFailedException {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
EntityNMSItem item = new EntityNMSItem(nmsWorld, parentHologramLine);
item.setLocationNMS(x, y, z);
item.setItemStackNMS(stack);
addEntityToWorld(nmsWorld, item);
return item;
}
@Override
public EntityNMSSlime spawnNMSSlime(
World bukkitWorld, double x, double y, double z,
StandardHologramLine parentHologramLine) throws SpawnFailedException {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
EntityNMSSlime slime = new EntityNMSSlime(nmsWorld, parentHologramLine);
slime.setLocationNMS(x, y, z);
addEntityToWorld(nmsWorld, slime);
return slime;
}
@Override
public NMSArmorStand spawnNMSArmorStand(
World world, double x, double y, double z,
StandardHologramLine parentHologramLine) throws SpawnFailedException {
WorldServer nmsWorld = ((CraftWorld) world).getHandle();
EntityNMSArmorStand armorStand = new EntityNMSArmorStand(nmsWorld, parentHologramLine, protocolPacketSettings);
armorStand.setLocationNMS(x, y, z);
addEntityToWorld(nmsWorld, armorStand);
return armorStand;
}
private void addEntityToWorld(WorldServer nmsWorld, Entity nmsEntity) throws SpawnFailedException {
Preconditions.checkState(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.isChunkLoaded(chunkX, chunkZ)) {
// This should never happen
nmsEntity.dead = true;
throw new SpawnFailedException(SpawnFailedException.CHUNK_NOT_LOADED);
}
nmsWorld.getChunkAt(chunkX, chunkZ).a(nmsEntity);
try {
REGISTER_ENTITY_METHOD.invoke(nmsWorld, nmsEntity);
} catch (ReflectiveOperationException e) {
nmsEntity.dead = true;
throw new SpawnFailedException(SpawnFailedException.REGISTER_ENTITY_FAIL, e);
}
}
@Override
public boolean isNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) {
return ((CraftEntity) bukkitEntity).getHandle() instanceof NMSEntity;
}
@Override
public NMSEntity getNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) {
Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle();
if (nmsEntity instanceof NMSEntity) {
return (NMSEntity) nmsEntity;
} else {
return null;
}
}
@Override
public NMSEntity getNMSEntityBaseFromID(org.bukkit.World bukkitWorld, int entityID) {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
Entity nmsEntity = nmsWorld.getEntity(entityID);
if (nmsEntity instanceof NMSEntity) {
return (NMSEntity) nmsEntity;
} else {
return null;
}
}
@Override
public Object createCustomNameNMSObject(String customName) {
return EntityNMSArmorStand.createCustomNameNMSObject(customName);
public NMSPacketList createPacketList() {
return null;
}
}

View File

@ -1,89 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_16_R1;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_16_R1.CraftServer;
import org.bukkit.craftbukkit.v1_16_R1.entity.CraftArmorStand;
import org.bukkit.entity.Entity;
import org.bukkit.event.entity.EntityDamageEvent;
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;
import java.util.Collection;
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 ArmorStand 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; }
@Override public void setSwimming(boolean swimming) {}
// Methods from Entity class
@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 setLastDamageCause(EntityDamageEvent event) {}
@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) {}
@Override public void setPersistent(boolean flag) {}
@Override public void setRotation(float yaw, float pitch) {}
}

View File

@ -1,58 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_16_R1;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_16_R1.CraftServer;
import org.bukkit.craftbukkit.v1_16_R1.entity.CraftItem;
import org.bukkit.entity.Entity;
import org.bukkit.event.entity.EntityDamageEvent;
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 Item class
@Override public void setItemStack(ItemStack stack) {}
@Override public void setPickupDelay(int delay) {}
// Methods from Entity class
@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 setLastDamageCause(EntityDamageEvent event) {}
@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) {}
@Override public void setPersistent(boolean flag) {}
@Override public void setRotation(float yaw, float pitch) {}
}

View File

@ -1,78 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_16_R1;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_16_R1.CraftServer;
import org.bukkit.craftbukkit.v1_16_R1.entity.CraftSlime;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.loot.LootTable;
import org.bukkit.potion.PotionEffect;
import org.bukkit.util.Vector;
import java.util.Collection;
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 Slime class
@Override public void setSize(int size) {}
@Override public void setTarget(LivingEntity target) {}
// Methods from Mob class
@Override public void setLootTable(LootTable table) {}
@Override public void setSeed(long seed) {}
// 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; }
@Override public void setSwimming(boolean swimming) {}
// Methods from Entity class
@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 setLastDamageCause(EntityDamageEvent event) {}
@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) {}
@Override public void setPersistent(boolean flag) {}
@Override public void setRotation(float yaw, float pitch) {}
}

View File

@ -1,264 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_16_R1;
import me.filoghost.fcommons.Preconditions;
import me.filoghost.fcommons.Strings;
import me.filoghost.fcommons.reflection.ReflectField;
import me.filoghost.holographicdisplays.common.DebugLogger;
import me.filoghost.holographicdisplays.common.hologram.StandardHologramLine;
import me.filoghost.holographicdisplays.common.nms.ProtocolPacketSettings;
import me.filoghost.holographicdisplays.common.nms.entity.NMSArmorStand;
import me.filoghost.holographicdisplays.common.nms.entity.NMSEntity;
import net.minecraft.server.v1_16_R1.AxisAlignedBB;
import net.minecraft.server.v1_16_R1.DamageSource;
import net.minecraft.server.v1_16_R1.Entity;
import net.minecraft.server.v1_16_R1.EntityArmorStand;
import net.minecraft.server.v1_16_R1.EntityHuman;
import net.minecraft.server.v1_16_R1.EntityTypes;
import net.minecraft.server.v1_16_R1.EnumHand;
import net.minecraft.server.v1_16_R1.EnumInteractionResult;
import net.minecraft.server.v1_16_R1.EnumItemSlot;
import net.minecraft.server.v1_16_R1.IChatBaseComponent;
import net.minecraft.server.v1_16_R1.ItemStack;
import net.minecraft.server.v1_16_R1.NBTTagCompound;
import net.minecraft.server.v1_16_R1.PacketPlayOutEntityTeleport;
import net.minecraft.server.v1_16_R1.SoundEffect;
import net.minecraft.server.v1_16_R1.Vec3D;
import net.minecraft.server.v1_16_R1.World;
import org.bukkit.craftbukkit.v1_16_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_16_R1.util.CraftChatMessage;
import org.bukkit.entity.Player;
import java.util.Objects;
public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorStand {
private static final ReflectField<Entity> VEHICLE_FIELD = ReflectField.lookup(Entity.class, Entity.class, "vehicle");
private final StandardHologramLine parentHologramLine;
private final ProtocolPacketSettings protocolPacketSettings;
private final VersionNMSEntityHelper helper;
private CraftEntity customBukkitEntity;
private String customName;
public EntityNMSArmorStand(World world, StandardHologramLine parentHologramLine, ProtocolPacketSettings protocolPacketSettings) {
super(EntityTypes.ARMOR_STAND, world);
this.parentHologramLine = parentHologramLine;
this.protocolPacketSettings = protocolPacketSettings;
this.helper = new VersionNMSEntityHelper(this);
super.setInvisible(true);
super.setSmall(true);
super.setArms(false);
super.setNoGravity(true);
super.setBasePlate(true);
super.setMarker(true);
super.collides = false;
super.onGround = true; // Workaround to force EntityTrackerEntry to send a teleport packet
forceSetBoundingBox(new NullBoundingBox());
}
@Override
public void tick() {
// Disable normal ticking for this entity
// Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity
if (super.onGround) {
super.onGround = false;
}
}
@Override
public void inactiveTick() {
// Disable normal ticking for this entity
// Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity
if (super.onGround) {
super.onGround = false;
}
}
@Override
public void saveData(NBTTagCompound nbttagcompound) {
// Do not save NBT
}
@Override
public boolean a_(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 load(NBTTagCompound nbttagcompound) {
// Do not load NBT
}
@Override
public void loadData(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(IChatBaseComponent ichatbasecomponent) {
// Prevents changes to custom name
}
@Override
public void setCustomNameVisible(boolean visible) {
// Prevents changes to custom name visibility
}
@Override
public EnumInteractionResult a(EntityHuman human, Vec3D vec3d, EnumHand enumhand) {
// Prevent armor stand from being equipped
return EnumInteractionResult.PASS;
}
@Override
public boolean a_(int i, ItemStack item) {
// Prevent armor stand from being equipped
return false;
}
@Override
public void setSlot(EnumItemSlot enumitemslot, ItemStack itemstack) {
// Prevent armor stand from being equipped
}
@Override
public void a(AxisAlignedBB boundingBox) {
// Prevent changes to bounding box
}
public void forceSetBoundingBox(AxisAlignedBB boundingBox) {
super.a(boundingBox);
}
@Override
public void playSound(SoundEffect soundeffect, float f, float f1) {
// Remove sounds
}
@Override
public void setCustomNameNMS(String customName) {
if (Objects.equals(this.customName, customName)) {
return;
}
this.customName = customName;
super.setCustomName(createCustomNameNMSObject(customName));
super.setCustomNameVisible(customName != null && !customName.isEmpty());
}
protected static IChatBaseComponent createCustomNameNMSObject(String customName) {
return CraftChatMessage.fromStringOrNull(Strings.truncate(customName, 300));
}
@Override
public String getCustomNameStringNMS() {
return this.customName;
}
@Override
public IChatBaseComponent getCustomNameObjectNMS() {
return super.getCustomName();
}
@Override
public void die() {
// Prevent entity from dying
}
@Override
public CraftEntity getBukkitEntity() {
if (customBukkitEntity == null) {
customBukkitEntity = new CraftNMSArmorStand(super.world.getServer(), this);
}
return customBukkitEntity;
}
@Override
public void killEntityNMS() {
super.dead = true;
}
@Override
public void setLocationNMS(double x, double y, double z) {
super.setPosition(x, y, z);
if (protocolPacketSettings.sendAccurateLocationPackets()) {
helper.broadcastPacket(new PacketPlayOutEntityTeleport(this));
}
}
@Override
public void setPassengerNMS(NMSEntity passenger) {
Preconditions.checkArgument(passenger instanceof Entity);
Entity passengerEntity = (Entity) passenger;
Preconditions.checkArgument(passengerEntity.getVehicle() == null);
Preconditions.checkState(super.passengers.isEmpty());
try {
VEHICLE_FIELD.set(passenger, this);
this.passengers.add(passengerEntity);
} catch (ReflectiveOperationException e) {
DebugLogger.cannotSetPassenger(e);
}
}
@Override
public boolean isDeadNMS() {
return super.dead;
}
@Override
public int getIdNMS() {
return super.getId();
}
@Override
public StandardHologramLine getHologramLine() {
return parentHologramLine;
}
@Override
public org.bukkit.entity.Entity getBukkitEntityNMS() {
return getBukkitEntity();
}
@Override
public boolean isTrackedBy(Player bukkitPlayer) {
return helper.isTrackedBy(bukkitPlayer);
}
}

View File

@ -1,201 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_16_R1;
import me.filoghost.holographicdisplays.common.hologram.StandardHologramLine;
import me.filoghost.holographicdisplays.common.hologram.StandardItemLine;
import me.filoghost.holographicdisplays.common.nms.NMSCommons;
import me.filoghost.holographicdisplays.common.nms.entity.NMSItem;
import net.minecraft.server.v1_16_R1.Blocks;
import net.minecraft.server.v1_16_R1.DamageSource;
import net.minecraft.server.v1_16_R1.EntityHuman;
import net.minecraft.server.v1_16_R1.EntityItem;
import net.minecraft.server.v1_16_R1.EntityPlayer;
import net.minecraft.server.v1_16_R1.EntityTypes;
import net.minecraft.server.v1_16_R1.ItemStack;
import net.minecraft.server.v1_16_R1.NBTTagCompound;
import net.minecraft.server.v1_16_R1.NBTTagList;
import net.minecraft.server.v1_16_R1.NBTTagString;
import net.minecraft.server.v1_16_R1.World;
import org.bukkit.craftbukkit.v1_16_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftItemStack;
import org.bukkit.entity.Player;
public class EntityNMSItem extends EntityItem implements NMSItem {
private final StandardItemLine parentHologramLine;
private final VersionNMSEntityHelper helper;
private CraftEntity customBukkitEntity;
public EntityNMSItem(World world, StandardItemLine parentHologramLine) {
super(EntityTypes.ITEM, world);
this.parentHologramLine = parentHologramLine;
this.helper = new VersionNMSEntityHelper(this);
super.pickupDelay = 32767; // Lock the item pickup delay, also prevents entities from picking up the item
}
@Override
public void tick() {
// Disable normal ticking for this entity
// So it won't get removed
ticksLived = 0;
}
@Override
public void inactiveTick() {
// Disable normal ticking for this entity
// So it won't get removed
ticksLived = 0;
}
// Method called when a player is near
@Override
public void pickup(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 (human instanceof EntityPlayer) {
parentHologramLine.onPickup(((EntityPlayer) human).getBukkitEntity());
// It is never added to the inventory
}
}
@Override
public void saveData(NBTTagCompound nbttagcompound) {
// Do not save NBT
}
@Override
public boolean a_(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 load(NBTTagCompound nbttagcompound) {
// Do not load NBT
}
@Override
public void loadData(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 die() {
// Prevent entity from dying
}
@Override
public boolean isAlive() {
// This override prevents items from being picked up by hoppers (should have no side effects)
return false;
}
@Override
public CraftEntity getBukkitEntity() {
if (customBukkitEntity == null) {
customBukkitEntity = new CraftNMSItem(super.world.getServer(), this);
}
return customBukkitEntity;
}
@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 == ItemStack.b) { // ItemStack.b is returned if the stack is not valid
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(NBTTagString.a(NMSCommons.ANTI_STACK_LORE));
display.set("Lore", tagList);
super.setItemStack(newItem);
}
@Override
public int getIdNMS() {
return super.getId();
}
@Override
public StandardHologramLine getHologramLine() {
return parentHologramLine;
}
@Override
public org.bukkit.entity.Entity getBukkitEntityNMS() {
return getBukkitEntity();
}
@Override
public boolean isTrackedBy(Player bukkitPlayer) {
return helper.isTrackedBy(bukkitPlayer);
}
@Override
public Object getRawItemStack() {
return super.getItemStack();
}
}

View File

@ -1,193 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_16_R1;
import me.filoghost.holographicdisplays.common.hologram.StandardHologramLine;
import me.filoghost.holographicdisplays.common.nms.entity.NMSSlime;
import net.minecraft.server.v1_16_R1.AxisAlignedBB;
import net.minecraft.server.v1_16_R1.DamageSource;
import net.minecraft.server.v1_16_R1.EntityDamageSource;
import net.minecraft.server.v1_16_R1.EntityPlayer;
import net.minecraft.server.v1_16_R1.EntitySlime;
import net.minecraft.server.v1_16_R1.EntityTypes;
import net.minecraft.server.v1_16_R1.IChatBaseComponent;
import net.minecraft.server.v1_16_R1.NBTTagCompound;
import net.minecraft.server.v1_16_R1.SoundEffect;
import net.minecraft.server.v1_16_R1.World;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_16_R1.entity.CraftEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerInteractEntityEvent;
public class EntityNMSSlime extends EntitySlime implements NMSSlime {
private final StandardHologramLine parentHologramLine;
private final VersionNMSEntityHelper helper;
private CraftEntity customBukkitEntity;
public EntityNMSSlime(World world, StandardHologramLine parentHologramLine) {
super(EntityTypes.SLIME, world);
this.parentHologramLine = parentHologramLine;
this.helper = new VersionNMSEntityHelper(this);
super.persistent = true;
super.collides = false;
super.a(0.0F, 0.0F);
super.setSize(1, false);
super.setInvisible(true);
forceSetBoundingBox(new NullBoundingBox());
}
@Override
public void tick() {
// Disable normal ticking for this entity
// So it won't get removed
ticksLived = 0;
}
@Override
public void inactiveTick() {
// Disable normal ticking for this entity
// So it won't get removed
ticksLived = 0;
}
@Override
public void a(AxisAlignedBB boundingBox) {
// Prevent changes to bounding box
}
public void forceSetBoundingBox(AxisAlignedBB boundingBox) {
super.a(boundingBox);
}
@Override
public void saveData(NBTTagCompound nbttagcompound) {
// Do not save NBT
}
@Override
public boolean a_(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 load(NBTTagCompound nbttagcompound) {
// Do not load NBT
}
@Override
public void loadData(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) {
Player player = ((EntityPlayer) entityDamageSource.getEntity()).getBukkitEntity();
PlayerInteractEntityEvent event = new PlayerInteractEntityEvent(player, getBukkitEntity());
Bukkit.getPluginManager().callEvent(event); // 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 setCustomName(IChatBaseComponent ichatbasecomponent) {
// Prevents changes to custom name
}
@Override
public void setCustomNameVisible(boolean visible) {
// Prevents changes to custom name visibility
}
@Override
public void playSound(SoundEffect soundeffect, float f, float f1) {
// Remove sounds
}
@Override
public void die() {
// Prevent entity from dying
}
@Override
public CraftEntity getBukkitEntity() {
if (customBukkitEntity == null) {
customBukkitEntity = new CraftNMSSlime(super.world.getServer(), this);
}
return customBukkitEntity;
}
@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 StandardHologramLine getHologramLine() {
return parentHologramLine;
}
@Override
public org.bukkit.entity.Entity getBukkitEntityNMS() {
return getBukkitEntity();
}
@Override
public boolean isTrackedBy(Player bukkitPlayer) {
return helper.isTrackedBy(bukkitPlayer);
}
}

View File

@ -1,124 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.nms.v1_16_R1;
import net.minecraft.server.v1_16_R1.AxisAlignedBB;
import net.minecraft.server.v1_16_R1.BlockPosition;
import net.minecraft.server.v1_16_R1.EnumDirection.EnumAxis;
import net.minecraft.server.v1_16_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 AxisAlignedBB a(AxisAlignedBB arg0) {
return this;
}
@Override
public AxisAlignedBB a(double arg0, double arg1, double arg2) {
return this;
}
@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 AxisAlignedBB g(double arg0) {
return this;
}
@Override
public AxisAlignedBB b(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 double a(EnumAxis arg0) {
return 0.0;
}
@Override
public double b(EnumAxis arg0) {
return 0.0;
}
@Override
public boolean e(double arg0, double arg1, double arg2) {
return false;
}
@Override
public double b() {
return 0.0;
}
@Override
public double c() {
return 0.0;
}
@Override
public double d() {
return 0.0;
}
@Override
public boolean d(Vec3D var0) {
return false;
}
@Override
public Vec3D f() {
return Vec3D.a;
}
}

Some files were not shown because too many files have changed in this diff Show More