Started thinking about the implemtation of #11

This commit is contained in:
Jitse Boonstra 2019-10-21 09:49:23 +02:00
parent 6d5895870b
commit 4d2140d24c
24 changed files with 377 additions and 254 deletions

View File

@ -89,12 +89,12 @@ public final class NPCLib {
/**
* Create a new non-player character (NPC).
*
* @param lines The text you want to sendShowPackets above the NPC (null = no text).
* @param text The text you want to sendShowPackets above the NPC (null = no text).
* @return The NPC object you may use to sendShowPackets it to players.
*/
public NPC createNPC(List<String> lines) {
public NPC createNPC(List<String> text) {
try {
return (NPC) npcClass.getConstructors()[0].newInstance(this, lines);
return (NPC) npcClass.getConstructors()[0].newInstance(this, text);
} catch (Exception exception) {
logger.warning("Failed to create NPC. Please report the following stacktrace message: " + exception.getMessage());
}

View File

@ -12,6 +12,8 @@ import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.List;
public interface NPC {
/**
@ -108,4 +110,6 @@ public interface NPC {
* @return Object instance.
*/
NPC setItem(NPCSlot slot, ItemStack item);
NPC setText(List<String> text);
}

View File

@ -1,179 +1,4 @@
/*
* Copyright (c) 2018 Jitse Boonstra
*/
package net.jitse.npclib.hologram;
import com.comphenix.tinyprotocol.Reflection;
import net.jitse.npclib.internal.MinecraftVersion;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class Hologram {
private final double delta = 0.3;
private List<Object> armorStands = new ArrayList<>();
private Set<Object> spawnPackets = new HashSet<>();
private Set<Object> destroyPackets = new HashSet<>();
// Classes:
private static final Class<?> CHAT_COMPONENT_TEXT_CLAZZ = Reflection.getMinecraftClass("ChatComponentText");
private static final Class<?> CHAT_BASE_COMPONENT_CLAZZ = Reflection.getMinecraftClass("IChatBaseComponent");
private static final Class<?> ENTITY_ARMOR_STAND_CLAZZ = Reflection.getMinecraftClass("EntityArmorStand");
private static final Class<?> ENTITY_LIVING_CLAZZ = Reflection.getMinecraftClass("EntityLiving");
private static final Class<?> ENTITY_CLAZZ = Reflection.getMinecraftClass("Entity");
private static final Class<?> CRAFT_BUKKIT_CLASS = Reflection.getCraftBukkitClass("CraftWorld");
private static final Class<?> CRAFT_PLAYER_CLAZZ = Reflection.getCraftBukkitClass("entity.CraftPlayer");
private static final Class<?> PACKET_PLAY_OUT_SPAWN_ENTITY_LIVING_CLAZZ = Reflection.getMinecraftClass(
"PacketPlayOutSpawnEntityLiving");
private static final Class<?> PACKET_PLAY_OUT_ENTITY_DESTROY_CLAZZ = Reflection.getMinecraftClass(
"PacketPlayOutEntityDestroy");
private static final Class<?> ENTITY_PLAYER_CLAZZ = Reflection.getMinecraftClass("EntityPlayer");
private static final Class<?> PLAYER_CONNECTION_CLAZZ = Reflection.getMinecraftClass("PlayerConnection");
private static final Class<?> PACKET_CLAZZ = Reflection.getMinecraftClass("Packet");
// Constructors:
private static final Reflection.ConstructorInvoker CHAT_COMPONENT_TEXT_CONSTRUCTOR = Reflection
.getConstructor(CHAT_COMPONENT_TEXT_CLAZZ, String.class);
private static final Reflection.ConstructorInvoker PACKET_PLAY_OUT_SPAWN_ENTITY_LIVING_CONSTRUCTOR = Reflection
.getConstructor(PACKET_PLAY_OUT_SPAWN_ENTITY_LIVING_CLAZZ, ENTITY_LIVING_CLAZZ);
private static final Reflection.ConstructorInvoker PACKET_PLAY_OUT_ENTITY_DESTROY_CONSTRUCTOR = Reflection
.getConstructor(PACKET_PLAY_OUT_ENTITY_DESTROY_CLAZZ, int[].class);
// Fields:
private static final Reflection.FieldAccessor playerConnectionField = Reflection.getField(ENTITY_PLAYER_CLAZZ,
"playerConnection", PLAYER_CONNECTION_CLAZZ);
// Methods:
private static final Reflection.MethodInvoker SET_LOCATION_METHOD = Reflection.getMethod(ENTITY_ARMOR_STAND_CLAZZ,
"setLocation", double.class, double.class, double.class, float.class, float.class);
private static final Reflection.MethodInvoker SET_SMALL_METHOD = Reflection.getMethod(ENTITY_ARMOR_STAND_CLAZZ,
"setSmall", boolean.class);
private static final Reflection.MethodInvoker SET_INVISIBLE_METHOD = Reflection.getMethod(ENTITY_ARMOR_STAND_CLAZZ,
"setInvisible", boolean.class);
private static final Reflection.MethodInvoker SET_BASE_PLATE_METHOD = Reflection.getMethod(ENTITY_ARMOR_STAND_CLAZZ,
"setBasePlate", boolean.class);
private static final Reflection.MethodInvoker SET_ARMS_METHOD = Reflection.getMethod(ENTITY_ARMOR_STAND_CLAZZ,
"setArms", boolean.class);
private static final Reflection.MethodInvoker PLAYER_GET_HANDLE_METHOD = Reflection.getMethod(CRAFT_PLAYER_CLAZZ,
"getHandle");
private static final Reflection.MethodInvoker SEND_PACKET_METHOD = Reflection.getMethod(PLAYER_CONNECTION_CLAZZ,
"sendPacket", PACKET_CLAZZ);
private static final Reflection.MethodInvoker GET_ID_METHOD = Reflection.getMethod(ENTITY_ARMOR_STAND_CLAZZ,
"getId");
private final Location start;
private final List<String> lines;
private final Object worldServer;
public Hologram(Location location, List<String> lines) {
this.start = location;
this.lines = lines;
this.worldServer = Reflection.getMethod(CRAFT_BUKKIT_CLASS, "getHandle")
.invoke(CRAFT_BUKKIT_CLASS.cast(location.getWorld()));
}
public void generatePackets(MinecraftVersion version) {
// TODO: Check when this method was changed (1.9 R2 is giving an exception...
Reflection.MethodInvoker gravityMethod = (version.isAboveOrEqual(MinecraftVersion.V1_9_R2) ?
Reflection.getMethod(ENTITY_CLAZZ, "setNoGravity", boolean.class) :
Reflection.getMethod(ENTITY_ARMOR_STAND_CLAZZ, "setGravity", boolean.class));
Reflection.MethodInvoker customNameMethod = (version.isAboveOrEqual(MinecraftVersion.V1_12_R1)
? Reflection.getMethod(ENTITY_CLAZZ, "setCustomName", version.isAboveOrEqual(MinecraftVersion.V1_13_R1) ? CHAT_BASE_COMPONENT_CLAZZ : String.class)
: Reflection.getMethod(ENTITY_ARMOR_STAND_CLAZZ, "setCustomName", String.class));
Reflection.MethodInvoker customNameVisibilityMethod = (version.isAboveOrEqual(MinecraftVersion.V1_12_R1) ?
Reflection.getMethod(ENTITY_CLAZZ, "setCustomNameVisible", boolean.class) :
Reflection.getMethod(ENTITY_ARMOR_STAND_CLAZZ, "setCustomNameVisible", boolean.class));
Location location = start.clone().add(0, delta * lines.size(), 0);
Class<?> worldClass = worldServer.getClass().getSuperclass();
if (start.getWorld().getEnvironment() != World.Environment.NORMAL) {
worldClass = worldClass.getSuperclass();
}
Reflection.ConstructorInvoker entityArmorStandConstructor = (version.isAboveOrEqual(MinecraftVersion.V1_14_R1) ?
Reflection.getConstructor(ENTITY_ARMOR_STAND_CLAZZ, worldClass, double.class, double.class, double.class) :
Reflection.getConstructor(ENTITY_ARMOR_STAND_CLAZZ, worldClass));
for (String line : lines) {
Object entityArmorStand = (version.isAboveOrEqual(MinecraftVersion.V1_14_R1) ?
entityArmorStandConstructor.invoke(worldServer, location.getX(), location.getY(), location.getZ()) :
entityArmorStandConstructor.invoke(worldServer));
if (!version.isAboveOrEqual(MinecraftVersion.V1_14_R1)) {
SET_LOCATION_METHOD.invoke(entityArmorStand, location.getX(), location.getY(), location.getZ(), 0, 0);
}
customNameMethod.invoke(entityArmorStand, version.isAboveOrEqual(MinecraftVersion.V1_13_R1) ?
CHAT_COMPONENT_TEXT_CONSTRUCTOR.invoke(line) : line);
customNameVisibilityMethod.invoke(entityArmorStand, true);
gravityMethod.invoke(entityArmorStand, version.isAboveOrEqual(MinecraftVersion.V1_9_R2));
SET_SMALL_METHOD.invoke(entityArmorStand, true);
SET_INVISIBLE_METHOD.invoke(entityArmorStand, true);
SET_BASE_PLATE_METHOD.invoke(entityArmorStand, false);
SET_ARMS_METHOD.invoke(entityArmorStand, false);
location.subtract(0, delta, 0);
if (line.isEmpty()) {
continue;
}
armorStands.add(entityArmorStand);
Object spawnPacket = PACKET_PLAY_OUT_SPAWN_ENTITY_LIVING_CONSTRUCTOR.invoke(entityArmorStand);
spawnPackets.add(spawnPacket);
Object destroyPacket = PACKET_PLAY_OUT_ENTITY_DESTROY_CONSTRUCTOR
.invoke(new int[]{(int) GET_ID_METHOD.invoke(entityArmorStand)});
destroyPackets.add(destroyPacket);
}
}
// public void updateText(List<String> newLines) {
// if (lines.size() != newLines.size()) {
// throw new IllegalArgumentException("New NPC text cannot differ in size from old text.");
// return;
// }
//
// int i = 0;
// for (String oldLine : lines) {
// if (oldLine.isEmpty() && !newLines.get(i).isEmpty()) {
// // Need to spawn
// }
// i++;
// }
// customNameMethod.invoke(entityArmorStand, above_1_12_r1 ? CHAT_COMPONENT_TEXT_CONSTRUCTOR.invoke(line) : line);
// }
public void spawn(Player player) {
Object playerConnection = playerConnectionField.get(PLAYER_GET_HANDLE_METHOD
.invoke(CRAFT_PLAYER_CLAZZ.cast(player)));
for (Object packet : spawnPackets) {
SEND_PACKET_METHOD.invoke(playerConnection, packet);
}
}
public void destroy(Player player) {
Object playerConnection = playerConnectionField.get(PLAYER_GET_HANDLE_METHOD
.invoke(CRAFT_PLAYER_CLAZZ.cast(player)));
for (Object packet : destroyPackets) {
SEND_PACKET_METHOD.invoke(playerConnection, packet);
}
}
public interface Hologram {
}

View File

@ -0,0 +1,34 @@
package net.jitse.npclib.hologram;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
public abstract class HologramBase implements Hologram, HologramPacketHandler {
protected final static double DELTA = 0.3;
protected final Set<UUID> shown = new HashSet<>();
protected final Location start;
protected List<String> text;
public HologramBase(Location start, List<String> text) {
this.start = start;
this.text = text;
}
abstract public void show(Player player);
abstract public void hide(Player player);
abstract public void silentHide(UUID uuid);
abstract public void updateText(List<String> text);
}

View File

@ -0,0 +1,6 @@
package net.jitse.npclib.hologram;
public interface HologramPacketHandler {
void sendTextUpdatePackets(int index, String newLine);
}

View File

@ -0,0 +1,179 @@
/*
* Copyright (c) 2018 Jitse Boonstra
*/
package net.jitse.npclib.hologram;
import com.comphenix.tinyprotocol.Reflection;
import net.jitse.npclib.internal.MinecraftVersion;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class _Hologram {
private final double delta = 0.3;
private List<Object> armorStands = new ArrayList<>();
private Set<Object> spawnPackets = new HashSet<>();
private Set<Object> destroyPackets = new HashSet<>();
// Classes:
private static final Class<?> CHAT_COMPONENT_TEXT_CLAZZ = Reflection.getMinecraftClass("ChatComponentText");
private static final Class<?> CHAT_BASE_COMPONENT_CLAZZ = Reflection.getMinecraftClass("IChatBaseComponent");
private static final Class<?> ENTITY_ARMOR_STAND_CLAZZ = Reflection.getMinecraftClass("EntityArmorStand");
private static final Class<?> ENTITY_LIVING_CLAZZ = Reflection.getMinecraftClass("EntityLiving");
private static final Class<?> ENTITY_CLAZZ = Reflection.getMinecraftClass("Entity");
private static final Class<?> CRAFT_BUKKIT_CLASS = Reflection.getCraftBukkitClass("CraftWorld");
private static final Class<?> CRAFT_PLAYER_CLAZZ = Reflection.getCraftBukkitClass("entity.CraftPlayer");
private static final Class<?> PACKET_PLAY_OUT_SPAWN_ENTITY_LIVING_CLAZZ = Reflection.getMinecraftClass(
"PacketPlayOutSpawnEntityLiving");
private static final Class<?> PACKET_PLAY_OUT_ENTITY_DESTROY_CLAZZ = Reflection.getMinecraftClass(
"PacketPlayOutEntityDestroy");
private static final Class<?> ENTITY_PLAYER_CLAZZ = Reflection.getMinecraftClass("EntityPlayer");
private static final Class<?> PLAYER_CONNECTION_CLAZZ = Reflection.getMinecraftClass("PlayerConnection");
private static final Class<?> PACKET_CLAZZ = Reflection.getMinecraftClass("Packet");
// Constructors:
private static final Reflection.ConstructorInvoker CHAT_COMPONENT_TEXT_CONSTRUCTOR = Reflection
.getConstructor(CHAT_COMPONENT_TEXT_CLAZZ, String.class);
private static final Reflection.ConstructorInvoker PACKET_PLAY_OUT_SPAWN_ENTITY_LIVING_CONSTRUCTOR = Reflection
.getConstructor(PACKET_PLAY_OUT_SPAWN_ENTITY_LIVING_CLAZZ, ENTITY_LIVING_CLAZZ);
private static final Reflection.ConstructorInvoker PACKET_PLAY_OUT_ENTITY_DESTROY_CONSTRUCTOR = Reflection
.getConstructor(PACKET_PLAY_OUT_ENTITY_DESTROY_CLAZZ, int[].class);
// Fields:
private static final Reflection.FieldAccessor playerConnectionField = Reflection.getField(ENTITY_PLAYER_CLAZZ,
"playerConnection", PLAYER_CONNECTION_CLAZZ);
// Methods:
private static final Reflection.MethodInvoker SET_LOCATION_METHOD = Reflection.getMethod(ENTITY_ARMOR_STAND_CLAZZ,
"setLocation", double.class, double.class, double.class, float.class, float.class);
private static final Reflection.MethodInvoker SET_SMALL_METHOD = Reflection.getMethod(ENTITY_ARMOR_STAND_CLAZZ,
"setSmall", boolean.class);
private static final Reflection.MethodInvoker SET_INVISIBLE_METHOD = Reflection.getMethod(ENTITY_ARMOR_STAND_CLAZZ,
"setInvisible", boolean.class);
private static final Reflection.MethodInvoker SET_BASE_PLATE_METHOD = Reflection.getMethod(ENTITY_ARMOR_STAND_CLAZZ,
"setBasePlate", boolean.class);
private static final Reflection.MethodInvoker SET_ARMS_METHOD = Reflection.getMethod(ENTITY_ARMOR_STAND_CLAZZ,
"setArms", boolean.class);
private static final Reflection.MethodInvoker PLAYER_GET_HANDLE_METHOD = Reflection.getMethod(CRAFT_PLAYER_CLAZZ,
"getHandle");
private static final Reflection.MethodInvoker SEND_PACKET_METHOD = Reflection.getMethod(PLAYER_CONNECTION_CLAZZ,
"sendPacket", PACKET_CLAZZ);
private static final Reflection.MethodInvoker GET_ID_METHOD = Reflection.getMethod(ENTITY_ARMOR_STAND_CLAZZ,
"getId");
private final Location start;
private final List<String> lines;
private final Object worldServer;
public _Hologram(Location location, List<String> lines) {
this.start = location;
this.lines = lines;
this.worldServer = Reflection.getMethod(CRAFT_BUKKIT_CLASS, "getHandle")
.invoke(CRAFT_BUKKIT_CLASS.cast(location.getWorld()));
}
public void generatePackets(MinecraftVersion version) {
// TODO: Check when this method was changed (1.9 R2 is giving an exception...
Reflection.MethodInvoker gravityMethod = (version.isAboveOrEqual(MinecraftVersion.V1_9_R2) ?
Reflection.getMethod(ENTITY_CLAZZ, "setNoGravity", boolean.class) :
Reflection.getMethod(ENTITY_ARMOR_STAND_CLAZZ, "setGravity", boolean.class));
Reflection.MethodInvoker customNameMethod = (version.isAboveOrEqual(MinecraftVersion.V1_12_R1)
? Reflection.getMethod(ENTITY_CLAZZ, "setCustomName", version.isAboveOrEqual(MinecraftVersion.V1_13_R1) ? CHAT_BASE_COMPONENT_CLAZZ : String.class)
: Reflection.getMethod(ENTITY_ARMOR_STAND_CLAZZ, "setCustomName", String.class));
Reflection.MethodInvoker customNameVisibilityMethod = (version.isAboveOrEqual(MinecraftVersion.V1_12_R1) ?
Reflection.getMethod(ENTITY_CLAZZ, "setCustomNameVisible", boolean.class) :
Reflection.getMethod(ENTITY_ARMOR_STAND_CLAZZ, "setCustomNameVisible", boolean.class));
Location location = start.clone().add(0, delta * lines.size(), 0);
Class<?> worldClass = worldServer.getClass().getSuperclass();
if (start.getWorld().getEnvironment() != World.Environment.NORMAL) {
worldClass = worldClass.getSuperclass();
}
Reflection.ConstructorInvoker entityArmorStandConstructor = (version.isAboveOrEqual(MinecraftVersion.V1_14_R1) ?
Reflection.getConstructor(ENTITY_ARMOR_STAND_CLAZZ, worldClass, double.class, double.class, double.class) :
Reflection.getConstructor(ENTITY_ARMOR_STAND_CLAZZ, worldClass));
for (String line : lines) {
Object entityArmorStand = (version.isAboveOrEqual(MinecraftVersion.V1_14_R1) ?
entityArmorStandConstructor.invoke(worldServer, location.getX(), location.getY(), location.getZ()) :
entityArmorStandConstructor.invoke(worldServer));
if (!version.isAboveOrEqual(MinecraftVersion.V1_14_R1)) {
SET_LOCATION_METHOD.invoke(entityArmorStand, location.getX(), location.getY(), location.getZ(), 0, 0);
}
customNameMethod.invoke(entityArmorStand, version.isAboveOrEqual(MinecraftVersion.V1_13_R1) ?
CHAT_COMPONENT_TEXT_CONSTRUCTOR.invoke(line) : line);
customNameVisibilityMethod.invoke(entityArmorStand, true);
gravityMethod.invoke(entityArmorStand, version.isAboveOrEqual(MinecraftVersion.V1_9_R2));
SET_SMALL_METHOD.invoke(entityArmorStand, true);
SET_INVISIBLE_METHOD.invoke(entityArmorStand, true);
SET_BASE_PLATE_METHOD.invoke(entityArmorStand, false);
SET_ARMS_METHOD.invoke(entityArmorStand, false);
location.subtract(0, delta, 0);
if (line.isEmpty()) {
continue;
}
armorStands.add(entityArmorStand);
Object spawnPacket = PACKET_PLAY_OUT_SPAWN_ENTITY_LIVING_CONSTRUCTOR.invoke(entityArmorStand);
spawnPackets.add(spawnPacket);
Object destroyPacket = PACKET_PLAY_OUT_ENTITY_DESTROY_CONSTRUCTOR
.invoke(new int[]{(int) GET_ID_METHOD.invoke(entityArmorStand)});
destroyPackets.add(destroyPacket);
}
}
// public void updateText(List<String> newLines) {
// if (lines.size() != newLines.size()) {
// throw new IllegalArgumentException("New NPC text cannot differ in size from old text.");
// return;
// }
//
// int i = 0;
// for (String oldLine : lines) {
// if (oldLine.isEmpty() && !newLines.get(i).isEmpty()) {
// // Need to spawn
// }
// i++;
// }
// customNameMethod.invoke(entityArmorStand, above_1_12_r1 ? CHAT_COMPONENT_TEXT_CONSTRUCTOR.invoke(line) : line);
// }
public void spawn(Player player) {
Object playerConnection = playerConnectionField.get(PLAYER_GET_HANDLE_METHOD
.invoke(CRAFT_PLAYER_CLAZZ.cast(player)));
for (Object packet : spawnPackets) {
SEND_PACKET_METHOD.invoke(playerConnection, packet);
}
}
public void destroy(Player player) {
Object playerConnection = playerConnectionField.get(PLAYER_GET_HANDLE_METHOD
.invoke(CRAFT_PLAYER_CLAZZ.cast(player)));
for (Object packet : destroyPackets) {
SEND_PACKET_METHOD.invoke(playerConnection, packet);
}
}
}

View File

@ -22,15 +22,13 @@ import org.bukkit.util.Vector;
import java.util.*;
public abstract class SimpleNPC implements NPC, PacketHandler {
public abstract class NPCBase implements NPC, NPCPacketHandler {
protected final UUID uuid = UUID.randomUUID();
protected final int entityId = Integer.MAX_VALUE - NPCManager.getAllNPCs().size();
protected final String name = uuid.toString().replace("-", "").substring(0, 10);
protected final GameProfile gameProfile = new GameProfile(uuid, name);
protected final List<String> lines;
private final Set<UUID> shown = new HashSet<>();
private final Set<UUID> autoHidden = new HashSet<>();
@ -38,15 +36,16 @@ public abstract class SimpleNPC implements NPC, PacketHandler {
protected NPCState[] activeStates = new NPCState[]{};
protected NPCLib instance;
protected List<String> text;
protected Location location;
protected Skin skin;
// offHand support in 1.9 R1 and later.
protected ItemStack helmet, chestplate, leggings, boots, inHand, offHand;
public SimpleNPC(NPCLib instance, List<String> lines) {
public NPCBase(NPCLib instance, List<String> text) {
this.instance = instance;
this.lines = lines == null ? Collections.emptyList() : lines;
this.text = text == null ? Collections.emptyList() : text;
NPCManager.add(this);
}
@ -299,4 +298,16 @@ public abstract class SimpleNPC implements NPC, PacketHandler {
}
return this;
}
@Override
public NPC setText(List<String> text) {
for (UUID shownUuid : shown) {
Player player = Bukkit.getPlayer(shownUuid);
if (player != null && isShown(player)) {
sendTextUpdatePackets(this.text, text, player);
}
}
this.text = text;
return this;
}
}

View File

@ -12,17 +12,17 @@ import java.util.Set;
*/
public final class NPCManager {
private static Set<SimpleNPC> npcs = new HashSet<>();
private static Set<NPCBase> npcs = new HashSet<>();
public static Set<SimpleNPC> getAllNPCs() {
public static Set<NPCBase> getAllNPCs() {
return npcs;
}
public static void add(SimpleNPC npc) {
public static void add(NPCBase npc) {
npcs.add(npc);
}
public static void remove(SimpleNPC npc) {
public static void remove(NPCBase npc) {
npcs.remove(npc);
}

View File

@ -10,7 +10,7 @@ import org.bukkit.entity.Player;
/**
* @author Jitse Boonstra
*/
interface PacketHandler {
interface NPCPacketHandler {
void createPackets();

View File

@ -5,8 +5,8 @@
package net.jitse.npclib.listeners;
import net.jitse.npclib.NPCLib;
import net.jitse.npclib.internal.NPCBase;
import net.jitse.npclib.internal.NPCManager;
import net.jitse.npclib.internal.SimpleNPC;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Location;
@ -34,7 +34,7 @@ public class ChunkListener implements Listener {
public void onChunkUnload(ChunkUnloadEvent event) {
Chunk chunk = event.getChunk();
for (SimpleNPC npc : NPCManager.getAllNPCs()) {
for (NPCBase npc : NPCManager.getAllNPCs()) {
if (npc.getLocation() == null || !isSameChunk(npc.getLocation(), chunk))
continue; // We aren't unloading the chunk with the NPC in it.
@ -55,7 +55,7 @@ public class ChunkListener implements Listener {
public void onChunkLoad(ChunkLoadEvent event) {
Chunk chunk = event.getChunk();
for (SimpleNPC npc : NPCManager.getAllNPCs()) {
for (NPCBase npc : NPCManager.getAllNPCs()) {
if (!isSameChunk(npc.getLocation(), chunk))
continue; // The NPC is not in the loaded chunk.

View File

@ -8,8 +8,8 @@ import com.comphenix.tinyprotocol.Reflection;
import com.comphenix.tinyprotocol.TinyProtocol;
import net.jitse.npclib.NPCLib;
import net.jitse.npclib.api.events.NPCInteractEvent;
import net.jitse.npclib.internal.NPCBase;
import net.jitse.npclib.internal.NPCManager;
import net.jitse.npclib.internal.SimpleNPC;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
@ -53,7 +53,7 @@ public class PacketListener {
if (!packetPlayInUseEntityClazz.isInstance(packet))
return true; // We aren't handling the packet.
SimpleNPC npc = null;
NPCBase npc = null;
int packetEntityId = (int) entityIdField.get(packet);
// Not using streams here is an intentional choice.
@ -62,7 +62,7 @@ public class PacketListener {
// So, we're avoiding them here.
// ~ Kneesnap, 9 / 20 / 2019.
for (SimpleNPC testNPC : NPCManager.getAllNPCs()) {
for (NPCBase testNPC : NPCManager.getAllNPCs()) {
if (testNPC.isShown(player) && testNPC.getEntityId() == packetEntityId) {
npc = testNPC;
break;

View File

@ -5,8 +5,8 @@
package net.jitse.npclib.listeners;
import net.jitse.npclib.NPCLib;
import net.jitse.npclib.internal.NPCBase;
import net.jitse.npclib.internal.NPCManager;
import net.jitse.npclib.internal.SimpleNPC;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
@ -38,7 +38,7 @@ public class PlayerListener implements Listener {
}
private void onPlayerLeave(Player player) {
for (SimpleNPC npc : NPCManager.getAllNPCs())
for (NPCBase npc : NPCManager.getAllNPCs())
npc.onLogout(player);
}
@ -48,7 +48,7 @@ public class PlayerListener implements Listener {
World from = event.getFrom();
// The PlayerTeleportEvent is call, and will handle visibility in the new world.
for (SimpleNPC npc : NPCManager.getAllNPCs()) {
for (NPCBase npc : NPCManager.getAllNPCs()) {
if (npc.getWorld().equals(from)) {
if (!npc.getAutoHidden().contains(player.getUniqueId())) {
npc.getAutoHidden().add(player.getUniqueId());
@ -75,7 +75,7 @@ public class PlayerListener implements Listener {
private void handleMove(Player player) {
World world = player.getWorld();
for (SimpleNPC npc : NPCManager.getAllNPCs()) {
for (NPCBase npc : NPCManager.getAllNPCs()) {
if (!npc.getShown().contains(player.getUniqueId())) {
continue; // NPC was never supposed to be shown to the player.
}

View File

@ -6,9 +6,9 @@ package net.jitse.npclib.nms.v1_10_R1;
import net.jitse.npclib.NPCLib;
import net.jitse.npclib.api.state.NPCSlot;
import net.jitse.npclib.hologram.Hologram;
import net.jitse.npclib.hologram._Hologram;
import net.jitse.npclib.internal.MinecraftVersion;
import net.jitse.npclib.internal.SimpleNPC;
import net.jitse.npclib.internal.NPCBase;
import net.jitse.npclib.nms.v1_10_R1.packets.*;
import net.minecraft.server.v1_10_R1.*;
import org.bukkit.Bukkit;
@ -25,9 +25,9 @@ import java.util.UUID;
/**
* @author Jitse Boonstra
*/
public class NPC_v1_10_R1 extends SimpleNPC {
public class NPC_v1_10_R1 extends NPCBase {
private Hologram hologram;
private _Hologram hologram;
private PacketPlayOutNamedEntitySpawn packetPlayOutNamedEntitySpawn;
private PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeamRegister;
private PacketPlayOutPlayerInfo packetPlayOutPlayerInfoAdd, packetPlayOutPlayerInfoRemove;
@ -41,7 +41,7 @@ public class NPC_v1_10_R1 extends SimpleNPC {
@Override
public void createPackets() {
this.hologram = new Hologram(location.clone().subtract(0, 0.5, 0), lines);
this.hologram = new _Hologram(location.clone().subtract(0, 0.5, 0), text);
hologram.generatePackets(MinecraftVersion.V1_10_R1);
PacketPlayOutPlayerInfoWrapper packetPlayOutPlayerInfoWrapper = new PacketPlayOutPlayerInfoWrapper();

View File

@ -6,9 +6,9 @@ package net.jitse.npclib.nms.v1_11_R1;
import net.jitse.npclib.NPCLib;
import net.jitse.npclib.api.state.NPCSlot;
import net.jitse.npclib.hologram.Hologram;
import net.jitse.npclib.hologram._Hologram;
import net.jitse.npclib.internal.MinecraftVersion;
import net.jitse.npclib.internal.SimpleNPC;
import net.jitse.npclib.internal.NPCBase;
import net.jitse.npclib.nms.v1_11_R1.packets.*;
import net.minecraft.server.v1_11_R1.*;
import org.bukkit.Bukkit;
@ -25,9 +25,9 @@ import java.util.UUID;
/**
* @author Jitse Boonstra
*/
public class NPC_v1_11_R1 extends SimpleNPC {
public class NPC_v1_11_R1 extends NPCBase {
private Hologram hologram;
private _Hologram hologram;
private PacketPlayOutNamedEntitySpawn packetPlayOutNamedEntitySpawn;
private PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeamRegister;
private PacketPlayOutPlayerInfo packetPlayOutPlayerInfoAdd, packetPlayOutPlayerInfoRemove;
@ -41,7 +41,7 @@ public class NPC_v1_11_R1 extends SimpleNPC {
@Override
public void createPackets() {
this.hologram = new Hologram(location.clone().add(0, 0.5, 0), lines);
this.hologram = new _Hologram(location.clone().add(0, 0.5, 0), text);
hologram.generatePackets(MinecraftVersion.V1_11_R1);
PacketPlayOutPlayerInfoWrapper packetPlayOutPlayerInfoWrapper = new PacketPlayOutPlayerInfoWrapper();

View File

@ -6,9 +6,9 @@ package net.jitse.npclib.nms.v1_12_R1;
import net.jitse.npclib.NPCLib;
import net.jitse.npclib.api.state.NPCSlot;
import net.jitse.npclib.hologram.Hologram;
import net.jitse.npclib.hologram._Hologram;
import net.jitse.npclib.internal.MinecraftVersion;
import net.jitse.npclib.internal.SimpleNPC;
import net.jitse.npclib.internal.NPCBase;
import net.jitse.npclib.nms.v1_12_R1.packets.*;
import net.minecraft.server.v1_12_R1.*;
import org.bukkit.Bukkit;
@ -25,8 +25,8 @@ import java.util.UUID;
/**
* @author Jitse Boonstra
*/
public class NPC_v1_12_R1 extends SimpleNPC {
private Hologram hologram;
public class NPC_v1_12_R1 extends NPCBase {
private _Hologram hologram;
private PacketPlayOutNamedEntitySpawn packetPlayOutNamedEntitySpawn;
private PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeamRegister;
private PacketPlayOutPlayerInfo packetPlayOutPlayerInfoAdd, packetPlayOutPlayerInfoRemove;
@ -40,7 +40,7 @@ public class NPC_v1_12_R1 extends SimpleNPC {
@Override
public void createPackets() {
this.hologram = new Hologram(location.clone().add(0, 0.5, 0), lines);
this.hologram = new _Hologram(location.clone().add(0, 0.5, 0), text);
hologram.generatePackets(MinecraftVersion.V1_12_R1);
PacketPlayOutPlayerInfoWrapper packetPlayOutPlayerInfoWrapper = new PacketPlayOutPlayerInfoWrapper();

View File

@ -6,9 +6,9 @@ package net.jitse.npclib.nms.v1_13_R1;
import net.jitse.npclib.NPCLib;
import net.jitse.npclib.api.state.NPCSlot;
import net.jitse.npclib.hologram.Hologram;
import net.jitse.npclib.hologram._Hologram;
import net.jitse.npclib.internal.MinecraftVersion;
import net.jitse.npclib.internal.SimpleNPC;
import net.jitse.npclib.internal.NPCBase;
import net.jitse.npclib.nms.v1_13_R1.packets.*;
import net.minecraft.server.v1_13_R1.*;
import org.bukkit.Bukkit;
@ -25,9 +25,9 @@ import java.util.UUID;
/**
* @author Jitse Boonstra
*/
public class NPC_v1_13_R1 extends SimpleNPC {
public class NPC_v1_13_R1 extends NPCBase {
private Hologram hologram;
private _Hologram hologram;
private PacketPlayOutNamedEntitySpawn packetPlayOutNamedEntitySpawn;
private PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeamRegister;
private PacketPlayOutPlayerInfo packetPlayOutPlayerInfoAdd, packetPlayOutPlayerInfoRemove;
@ -41,7 +41,7 @@ public class NPC_v1_13_R1 extends SimpleNPC {
@Override
public void createPackets() {
this.hologram = new Hologram(location.clone().add(0, 0.5, 0), lines);
this.hologram = new _Hologram(location.clone().add(0, 0.5, 0), text);
hologram.generatePackets(MinecraftVersion.V1_13_R1);
PacketPlayOutPlayerInfoWrapper packetPlayOutPlayerInfoWrapper = new PacketPlayOutPlayerInfoWrapper();

View File

@ -6,9 +6,9 @@ package net.jitse.npclib.nms.v1_13_R2;
import net.jitse.npclib.NPCLib;
import net.jitse.npclib.api.state.NPCSlot;
import net.jitse.npclib.hologram.Hologram;
import net.jitse.npclib.hologram._Hologram;
import net.jitse.npclib.internal.MinecraftVersion;
import net.jitse.npclib.internal.SimpleNPC;
import net.jitse.npclib.internal.NPCBase;
import net.jitse.npclib.nms.v1_13_R2.packets.*;
import net.minecraft.server.v1_13_R2.*;
import org.bukkit.Bukkit;
@ -25,9 +25,9 @@ import java.util.UUID;
/**
* @author Jitse Boonstra
*/
public class NPC_v1_13_R2 extends SimpleNPC {
public class NPC_v1_13_R2 extends NPCBase {
private Hologram hologram;
private _Hologram hologram;
private PacketPlayOutNamedEntitySpawn packetPlayOutNamedEntitySpawn;
private PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeamRegister;
private PacketPlayOutPlayerInfo packetPlayOutPlayerInfoAdd, packetPlayOutPlayerInfoRemove;
@ -41,7 +41,7 @@ public class NPC_v1_13_R2 extends SimpleNPC {
@Override
public void createPackets() {
this.hologram = new Hologram(location.clone().add(0, 0.5, 0), lines);
this.hologram = new _Hologram(location.clone().add(0, 0.5, 0), text);
hologram.generatePackets(MinecraftVersion.V1_13_R2);
PacketPlayOutPlayerInfoWrapper packetPlayOutPlayerInfoWrapper = new PacketPlayOutPlayerInfoWrapper();

View File

@ -2,9 +2,9 @@ package net.jitse.npclib.nms.v1_14_R1;
import net.jitse.npclib.NPCLib;
import net.jitse.npclib.api.state.NPCSlot;
import net.jitse.npclib.hologram.Hologram;
import net.jitse.npclib.hologram._Hologram;
import net.jitse.npclib.internal.MinecraftVersion;
import net.jitse.npclib.internal.SimpleNPC;
import net.jitse.npclib.internal.NPCBase;
import net.jitse.npclib.nms.v1_14_R1.packets.*;
import net.minecraft.server.v1_14_R1.*;
import org.bukkit.Bukkit;
@ -21,9 +21,9 @@ import java.util.UUID;
/**
* @author Jitse Boonstra
*/
public class NPC_v1_14_R1 extends SimpleNPC {
public class NPC_v1_14_R1 extends NPCBase {
private Hologram hologram;
private _Hologram hologram;
private PacketPlayOutNamedEntitySpawn packetPlayOutNamedEntitySpawn;
private PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeamRegister;
private PacketPlayOutPlayerInfo packetPlayOutPlayerInfoAdd, packetPlayOutPlayerInfoRemove;
@ -37,7 +37,7 @@ public class NPC_v1_14_R1 extends SimpleNPC {
@Override
public void createPackets() {
this.hologram = new Hologram(location.clone().add(0, 0.5, 0), lines);
this.hologram = new _Hologram(location.clone().add(0, 0.5, 0), text);
hologram.generatePackets(MinecraftVersion.V1_14_R1);
PacketPlayOutPlayerInfoWrapper packetPlayOutPlayerInfoWrapper = new PacketPlayOutPlayerInfoWrapper();

View File

@ -6,9 +6,9 @@ package net.jitse.npclib.nms.v1_8_R1;
import net.jitse.npclib.NPCLib;
import net.jitse.npclib.api.state.NPCSlot;
import net.jitse.npclib.hologram.Hologram;
import net.jitse.npclib.hologram._Hologram;
import net.jitse.npclib.internal.MinecraftVersion;
import net.jitse.npclib.internal.SimpleNPC;
import net.jitse.npclib.internal.NPCBase;
import net.jitse.npclib.nms.v1_8_R1.packets.*;
import net.minecraft.server.v1_8_R1.*;
import org.bukkit.Bukkit;
@ -25,9 +25,9 @@ import java.util.UUID;
/**
* @author Jitse Boonstra
*/
public class NPC_v1_8_R1 extends SimpleNPC {
public class NPC_v1_8_R1 extends NPCBase {
private Hologram hologram;
private _Hologram hologram;
private PacketPlayOutNamedEntitySpawn packetPlayOutNamedEntitySpawn;
private PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeamRegister;
private PacketPlayOutPlayerInfo packetPlayOutPlayerInfoAdd, packetPlayOutPlayerInfoRemove;
@ -41,7 +41,7 @@ public class NPC_v1_8_R1 extends SimpleNPC {
@Override
public void createPackets() {
this.hologram = new Hologram(location.clone().add(0, 0.5, 0), lines);
this.hologram = new _Hologram(location.clone().add(0, 0.5, 0), text);
hologram.generatePackets(MinecraftVersion.V1_8_R1);
PacketPlayOutPlayerInfoWrapper packetPlayOutPlayerInfoWrapper = new PacketPlayOutPlayerInfoWrapper();

View File

@ -0,0 +1,64 @@
package net.jitse.npclib.nms.v1_8_R1.hologram;
import net.jitse.npclib.hologram.HologramBase;
import org.bukkit.Location;
import java.util.List;
public class Hologram extends HologramBase {
// Perhaps all logic methods should be placed in the base class instead then
// use a similar approach to the NPCBase class, with a HologramPacketHandler class...
// That way I can't mess up logic on different version whilst implementing new features.
// *cough cough* hologram text updates. I can already see this go wrong.
public Hologram(Location start, List<String> text) {
super(start, text);
}
// @Override
// public void show(Player player) {
// UUID uuid = player.getUniqueId();
// if (shown.contains(uuid))
// throw new IllegalArgumentException("Hologram is already shown to player");
//
// // TODO: Send packets
//
// this.shown.add(uuid);
// }
//
// @Override
// public void hide(Player player) {
// UUID uuid = player.getUniqueId();
// if (!shown.contains(uuid))
// throw new IllegalArgumentException("Hologram is not shown to player");
//
// // TODO: Send packets
//
// this.shown.remove(uuid);
// }
//
// @Override
// public void silentHide(UUID uuid) {
// if (!shown.contains(uuid))
// throw new IllegalArgumentException("Hologram is not shown to player");
// this.shown.remove(uuid);
// }
//
// @Override
// public void updateText(List<String> text) {
//
// }
@Override
public void sendTextUpdatePackets(int index, String newLine) {
if (newLine.isEmpty()) {
// Check if line was empty before, if not, remove the hologram line.
} else {
// Check if line was empty before, if it was, create the hologram line.
// If the line was not empty before and it isn't now, update its text.
}
// Send the packets to all players that can see the hologram (i.e. shown set).
}
}

View File

@ -6,9 +6,9 @@ package net.jitse.npclib.nms.v1_8_R2;
import net.jitse.npclib.NPCLib;
import net.jitse.npclib.api.state.NPCSlot;
import net.jitse.npclib.hologram.Hologram;
import net.jitse.npclib.hologram._Hologram;
import net.jitse.npclib.internal.MinecraftVersion;
import net.jitse.npclib.internal.SimpleNPC;
import net.jitse.npclib.internal.NPCBase;
import net.jitse.npclib.nms.v1_8_R2.packets.*;
import net.minecraft.server.v1_8_R2.*;
import org.bukkit.Bukkit;
@ -25,9 +25,9 @@ import java.util.UUID;
/**
* @author Jitse Boonstra
*/
public class NPC_v1_8_R2 extends SimpleNPC {
public class NPC_v1_8_R2 extends NPCBase {
private Hologram hologram;
private _Hologram hologram;
private PacketPlayOutNamedEntitySpawn packetPlayOutNamedEntitySpawn;
private PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeamRegister;
private PacketPlayOutPlayerInfo packetPlayOutPlayerInfoAdd, packetPlayOutPlayerInfoRemove;
@ -41,7 +41,7 @@ public class NPC_v1_8_R2 extends SimpleNPC {
@Override
public void createPackets() {
this.hologram = new Hologram(location.clone().add(0, 0.5, 0), lines);
this.hologram = new _Hologram(location.clone().add(0, 0.5, 0), text);
hologram.generatePackets(MinecraftVersion.V1_8_R2);
PacketPlayOutPlayerInfoWrapper packetPlayOutPlayerInfoWrapper = new PacketPlayOutPlayerInfoWrapper();

View File

@ -6,9 +6,9 @@ package net.jitse.npclib.nms.v1_8_R3;
import net.jitse.npclib.NPCLib;
import net.jitse.npclib.api.state.NPCSlot;
import net.jitse.npclib.hologram.Hologram;
import net.jitse.npclib.hologram._Hologram;
import net.jitse.npclib.internal.MinecraftVersion;
import net.jitse.npclib.internal.SimpleNPC;
import net.jitse.npclib.internal.NPCBase;
import net.jitse.npclib.nms.v1_8_R3.packets.*;
import net.minecraft.server.v1_8_R3.*;
import org.bukkit.Bukkit;
@ -25,9 +25,9 @@ import java.util.UUID;
/**
* @author Jitse Boonstra
*/
public class NPC_v1_8_R3 extends SimpleNPC {
public class NPC_v1_8_R3 extends NPCBase {
private Hologram hologram;
private _Hologram hologram;
private PacketPlayOutNamedEntitySpawn packetPlayOutNamedEntitySpawn;
private PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeamRegister;
private PacketPlayOutPlayerInfo packetPlayOutPlayerInfoAdd, packetPlayOutPlayerInfoRemove;
@ -41,7 +41,7 @@ public class NPC_v1_8_R3 extends SimpleNPC {
@Override
public void createPackets() {
this.hologram = new Hologram(location.clone().add(0, 0.5, 0), lines);
this.hologram = new _Hologram(location.clone().add(0, 0.5, 0), text);
hologram.generatePackets(MinecraftVersion.V1_8_R3);
PacketPlayOutPlayerInfoWrapper packetPlayOutPlayerInfoWrapper = new PacketPlayOutPlayerInfoWrapper();

View File

@ -6,9 +6,9 @@ package net.jitse.npclib.nms.v1_9_R1;
import net.jitse.npclib.NPCLib;
import net.jitse.npclib.api.state.NPCSlot;
import net.jitse.npclib.hologram.Hologram;
import net.jitse.npclib.hologram._Hologram;
import net.jitse.npclib.internal.MinecraftVersion;
import net.jitse.npclib.internal.SimpleNPC;
import net.jitse.npclib.internal.NPCBase;
import net.jitse.npclib.nms.v1_9_R1.packets.*;
import net.minecraft.server.v1_9_R1.*;
import org.bukkit.Bukkit;
@ -25,9 +25,9 @@ import java.util.UUID;
/**
* @author Jitse Boonstra
*/
public class NPC_v1_9_R1 extends SimpleNPC {
public class NPC_v1_9_R1 extends NPCBase {
private Hologram hologram;
private _Hologram hologram;
private PacketPlayOutNamedEntitySpawn packetPlayOutNamedEntitySpawn;
private PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeamRegister;
private PacketPlayOutPlayerInfo packetPlayOutPlayerInfoAdd, packetPlayOutPlayerInfoRemove;
@ -41,7 +41,7 @@ public class NPC_v1_9_R1 extends SimpleNPC {
@Override
public void createPackets() {
this.hologram = new Hologram(location.clone().subtract(0, 0.5, 0), lines);
this.hologram = new _Hologram(location.clone().subtract(0, 0.5, 0), text);
hologram.generatePackets(MinecraftVersion.V1_9_R1);
PacketPlayOutPlayerInfoWrapper packetPlayOutPlayerInfoWrapper = new PacketPlayOutPlayerInfoWrapper();

View File

@ -6,9 +6,9 @@ package net.jitse.npclib.nms.v1_9_R2;
import net.jitse.npclib.NPCLib;
import net.jitse.npclib.api.state.NPCSlot;
import net.jitse.npclib.hologram.Hologram;
import net.jitse.npclib.hologram._Hologram;
import net.jitse.npclib.internal.MinecraftVersion;
import net.jitse.npclib.internal.SimpleNPC;
import net.jitse.npclib.internal.NPCBase;
import net.jitse.npclib.nms.v1_9_R2.packets.*;
import net.minecraft.server.v1_9_R2.*;
import org.bukkit.Bukkit;
@ -25,9 +25,9 @@ import java.util.UUID;
/**
* @author Jitse Boonstra
*/
public class NPC_v1_9_R2 extends SimpleNPC {
public class NPC_v1_9_R2 extends NPCBase {
private Hologram hologram;
private _Hologram hologram;
private PacketPlayOutNamedEntitySpawn packetPlayOutNamedEntitySpawn;
private PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeamRegister;
private PacketPlayOutPlayerInfo packetPlayOutPlayerInfoAdd, packetPlayOutPlayerInfoRemove;
@ -41,7 +41,7 @@ public class NPC_v1_9_R2 extends SimpleNPC {
@Override
public void createPackets() {
this.hologram = new Hologram(location.clone().subtract(0, 0.5, 0), lines);
this.hologram = new _Hologram(location.clone().subtract(0, 0.5, 0), text);
hologram.generatePackets(MinecraftVersion.V1_9_R2);
PacketPlayOutPlayerInfoWrapper packetPlayOutPlayerInfoWrapper = new PacketPlayOutPlayerInfoWrapper();