diff --git a/README.md b/README.md
index f0cb43d..5d44ae0 100755
--- a/README.md
+++ b/README.md
@@ -49,7 +49,7 @@ If you have NPCLib under your `plugins` folder, you may use the following:
net.jitse
npclib-api
- 2.9-SNAPSHOT
+ 2.11-SNAPSHOT
compile
diff --git a/api/pom.xml b/api/pom.xml
index a4ab543..30f80c0 100644
--- a/api/pom.xml
+++ b/api/pom.xml
@@ -8,7 +8,7 @@
npclib
net.jitse
- 2.9-SNAPSHOT
+ 2.11-SNAPSHOT
npclib-api
@@ -28,7 +28,7 @@
org.spigotmc
spigot-api
- 1.16.1-R0.1-SNAPSHOT
+ 1.16.3-R0.1-SNAPSHOT
provided
diff --git a/api/src/main/java/net/jitse/npclib/NPCLib.java b/api/src/main/java/net/jitse/npclib/NPCLib.java
index c8f16ba..969426f 100644
--- a/api/src/main/java/net/jitse/npclib/NPCLib.java
+++ b/api/src/main/java/net/jitse/npclib/NPCLib.java
@@ -111,7 +111,9 @@ public final class NPCLib {
*/
public NPC createNPC(List text) {
try {
- return (NPC) npcClass.getConstructors()[0].newInstance(this, text);
+ return (NPC) npcClass
+ .getConstructors()[0]
+ .newInstance(this, text);
} catch (Exception exception) {
logger.warning("Failed to create NPC. Please report the following stacktrace message", exception);
}
diff --git a/api/src/main/java/net/jitse/npclib/internal/MinecraftVersion.java b/api/src/main/java/net/jitse/npclib/internal/MinecraftVersion.java
index db98d68..b52b5fd 100644
--- a/api/src/main/java/net/jitse/npclib/internal/MinecraftVersion.java
+++ b/api/src/main/java/net/jitse/npclib/internal/MinecraftVersion.java
@@ -17,7 +17,8 @@ public enum MinecraftVersion {
V1_13_R2,
V1_14_R1,
V1_15_R1,
- V1_16_R1;
+ V1_16_R1,
+ V1_16_R3;
public boolean isAboveOrEqual(MinecraftVersion compare) {
return ordinal() >= compare.ordinal();
diff --git a/nms/pom.xml b/nms/pom.xml
index ddc43b7..b6dd375 100644
--- a/nms/pom.xml
+++ b/nms/pom.xml
@@ -8,7 +8,7 @@
net.jitse
npclib
- 2.9-SNAPSHOT
+ 2.11-SNAPSHOT
npclib-nms
@@ -25,6 +25,7 @@
v1_14_R1
v1_15_R1
v1_16_R1
+ v1_16_R3
diff --git a/nms/v1_10_R1/pom.xml b/nms/v1_10_R1/pom.xml
index 7d18f5f..98bb837 100755
--- a/nms/v1_10_R1/pom.xml
+++ b/nms/v1_10_R1/pom.xml
@@ -8,7 +8,7 @@
net.jitse
npclib-nms
- 2.9-SNAPSHOT
+ 2.11-SNAPSHOT
npclib-nms-v1_10_R1
diff --git a/nms/v1_11_R1/pom.xml b/nms/v1_11_R1/pom.xml
index 5fa1c32..ae85fd9 100755
--- a/nms/v1_11_R1/pom.xml
+++ b/nms/v1_11_R1/pom.xml
@@ -8,7 +8,7 @@
net.jitse
npclib-nms
- 2.9-SNAPSHOT
+ 2.11-SNAPSHOT
npclib-nms-v1_11_R1
diff --git a/nms/v1_12_R1/pom.xml b/nms/v1_12_R1/pom.xml
index aa9b953..f62533c 100755
--- a/nms/v1_12_R1/pom.xml
+++ b/nms/v1_12_R1/pom.xml
@@ -8,7 +8,7 @@
net.jitse
npclib-nms
- 2.9-SNAPSHOT
+ 2.11-SNAPSHOT
npclib-nms-v1_12_R1
diff --git a/nms/v1_13_R1/pom.xml b/nms/v1_13_R1/pom.xml
index 2c0742b..0fe1aee 100755
--- a/nms/v1_13_R1/pom.xml
+++ b/nms/v1_13_R1/pom.xml
@@ -8,7 +8,7 @@
net.jitse
npclib-nms
- 2.9-SNAPSHOT
+ 2.11-SNAPSHOT
npclib-nms-v1_13_R1
diff --git a/nms/v1_13_R2/pom.xml b/nms/v1_13_R2/pom.xml
index 4c544ae..8012cc1 100755
--- a/nms/v1_13_R2/pom.xml
+++ b/nms/v1_13_R2/pom.xml
@@ -8,7 +8,7 @@
net.jitse
npclib-nms
- 2.9-SNAPSHOT
+ 2.11-SNAPSHOT
npclib-nms-v1_13_R2
diff --git a/nms/v1_14_R1/pom.xml b/nms/v1_14_R1/pom.xml
index 6814941..8316a0e 100755
--- a/nms/v1_14_R1/pom.xml
+++ b/nms/v1_14_R1/pom.xml
@@ -8,7 +8,7 @@
net.jitse
npclib-nms
- 2.9-SNAPSHOT
+ 2.11-SNAPSHOT
npclib-nms-v1_14_R1
diff --git a/nms/v1_15_R1/pom.xml b/nms/v1_15_R1/pom.xml
index 0708d81..e495c1a 100644
--- a/nms/v1_15_R1/pom.xml
+++ b/nms/v1_15_R1/pom.xml
@@ -8,7 +8,7 @@
net.jitse
npclib-nms
- 2.9-SNAPSHOT
+ 2.11-SNAPSHOT
npclib-nms-v1_15_R1
diff --git a/nms/v1_16_R1/pom.xml b/nms/v1_16_R1/pom.xml
index 62cae7a..de46871 100644
--- a/nms/v1_16_R1/pom.xml
+++ b/nms/v1_16_R1/pom.xml
@@ -8,7 +8,7 @@
net.jitse
npclib-nms
- 2.9-SNAPSHOT
+ 2.11-SNAPSHOT
npclib-nms-v1_16_R1
diff --git a/nms/v1_16_R3/pom.xml b/nms/v1_16_R3/pom.xml
new file mode 100644
index 0000000..cd5ec5c
--- /dev/null
+++ b/nms/v1_16_R3/pom.xml
@@ -0,0 +1,24 @@
+
+
+ 4.0.0
+ jar
+
+
+ net.jitse
+ npclib-nms
+ 2.11-SNAPSHOT
+
+
+ npclib-nms-v1_16_R3
+
+
+
+ org.spigotmc
+ spigot
+ 1.16.4-R0.1-SNAPSHOT
+ provided
+
+
+
diff --git a/nms/v1_16_R3/src/main/java/net/jitse/npclib/nms/v1_16_R3/NPC_v1_16_R3.java b/nms/v1_16_R3/src/main/java/net/jitse/npclib/nms/v1_16_R3/NPC_v1_16_R3.java
new file mode 100644
index 0000000..d678d0c
--- /dev/null
+++ b/nms/v1_16_R3/src/main/java/net/jitse/npclib/nms/v1_16_R3/NPC_v1_16_R3.java
@@ -0,0 +1,150 @@
+package net.jitse.npclib.nms.v1_16_R3;
+
+import com.mojang.authlib.GameProfile;
+import com.mojang.authlib.properties.Property;
+import com.mojang.datafixers.util.Pair;
+import net.jitse.npclib.NPCLib;
+import net.jitse.npclib.api.skin.Skin;
+import net.jitse.npclib.api.state.NPCAnimation;
+import net.jitse.npclib.api.state.NPCSlot;
+import net.jitse.npclib.hologram.Hologram;
+import net.jitse.npclib.internal.MinecraftVersion;
+import net.jitse.npclib.internal.NPCBase;
+import net.jitse.npclib.nms.v1_16_R3.packets.*;
+import net.minecraft.server.v1_16_R3.*;
+import org.bukkit.Bukkit;
+import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer;
+import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author Jitse Boonstra
+ */
+public class NPC_v1_16_R3 extends NPCBase {
+
+ private PacketPlayOutNamedEntitySpawn packetPlayOutNamedEntitySpawn;
+ private PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeamRegister;
+ private PacketPlayOutPlayerInfo packetPlayOutPlayerInfoAdd, packetPlayOutPlayerInfoRemove;
+ private PacketPlayOutEntityHeadRotation packetPlayOutEntityHeadRotation;
+ private PacketPlayOutEntityDestroy packetPlayOutEntityDestroy;
+ private PacketPlayOutAnimation packetPlayOutAnimation;
+
+ public NPC_v1_16_R3(NPCLib instance, List lines) {
+ super(instance, lines);
+ }
+
+ @Override
+ public Hologram getPlayerHologram(Player player) {
+ Hologram holo = super.getPlayerHologram(player);
+ if (holo == null) {
+ holo = new Hologram(MinecraftVersion.V1_16_R3, location.clone().add(0, 0.5, 0), getPlayerLines(player));
+ }
+ super.textDisplayHolograms.put(player.getUniqueId(), holo);
+ return holo;
+ }
+
+ @Override
+ public void createPackets() {
+ Bukkit.getOnlinePlayers().forEach(this::createPackets);
+ }
+
+ @Override
+ public void createPackets(Player player) {
+
+ PacketPlayOutPlayerInfoWrapper packetPlayOutPlayerInfoWrapper = new PacketPlayOutPlayerInfoWrapper();
+
+ // Packets for spawning the NPC:
+ this.packetPlayOutScoreboardTeamRegister = new PacketPlayOutScoreboardTeamWrapper()
+ .createRegisterTeam(name); // First packet to send.
+
+ this.packetPlayOutPlayerInfoAdd = packetPlayOutPlayerInfoWrapper
+ .create(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, gameProfile, name); // Second packet to send.
+
+ this.packetPlayOutNamedEntitySpawn = new PacketPlayOutNamedEntitySpawnWrapper()
+ .create(uuid, location, entityId); // Third packet to send.
+
+ this.packetPlayOutEntityHeadRotation = new PacketPlayOutEntityHeadRotationWrapper()
+ .create(location, entityId); // Fourth packet to send.
+
+ this.packetPlayOutPlayerInfoRemove = packetPlayOutPlayerInfoWrapper
+ .create(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, gameProfile, name); // Fifth packet to send (delayed).
+
+ // Packet for destroying the NPC:
+ this.packetPlayOutEntityDestroy = new PacketPlayOutEntityDestroy(entityId); // First packet to send.
+ }
+
+ @Override
+ public void sendShowPackets(Player player) {
+ PlayerConnection playerConnection = ((CraftPlayer) player).getHandle().playerConnection;
+
+ if (hasTeamRegistered.add(player.getUniqueId()))
+ playerConnection.sendPacket(packetPlayOutScoreboardTeamRegister);
+ playerConnection.sendPacket(packetPlayOutPlayerInfoAdd);
+ playerConnection.sendPacket(packetPlayOutNamedEntitySpawn);
+ playerConnection.sendPacket(packetPlayOutEntityHeadRotation);
+ sendMetadataPacket(player);
+
+ getPlayerHologram(player).show(player);
+
+ // Removing the player info after 10 seconds.
+ Bukkit.getScheduler().runTaskLater(instance.getPlugin(), () ->
+ playerConnection.sendPacket(packetPlayOutPlayerInfoRemove), 200);
+ }
+
+ @Override
+ public void sendHidePackets(Player player) {
+ PlayerConnection playerConnection = ((CraftPlayer) player).getHandle().playerConnection;
+
+ playerConnection.sendPacket(packetPlayOutEntityDestroy);
+ playerConnection.sendPacket(packetPlayOutPlayerInfoRemove);
+
+ getPlayerHologram(player).hide(player);
+ }
+
+ @Override
+ public void sendMetadataPacket(Player player) {
+ PlayerConnection playerConnection = ((CraftPlayer) player).getHandle().playerConnection;
+ PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadataWrapper().create(activeStates, entityId);
+
+ playerConnection.sendPacket(packet);
+ }
+
+ @Override
+ public void sendEquipmentPacket(Player player, NPCSlot slot, boolean auto) {
+ PlayerConnection playerConnection = ((CraftPlayer) player).getHandle().playerConnection;
+
+ EnumItemSlot nmsSlot = slot.getNmsEnum(EnumItemSlot.class);
+ ItemStack item = getItem(slot);
+
+ Pair pair = new Pair<>(nmsSlot, CraftItemStack.asNMSCopy(item));
+ PacketPlayOutEntityEquipment packet = new PacketPlayOutEntityEquipment(entityId, Collections.singletonList(pair));
+ playerConnection.sendPacket(packet);
+ }
+
+ @Override
+ public void sendAnimationPacket(Player player, NPCAnimation animation) {
+ PlayerConnection playerConnection = ((CraftPlayer) player).getHandle().playerConnection;
+
+ PacketPlayOutAnimation packet = new PacketPlayOutAnimationWrapper().create(animation, entityId);
+ playerConnection.sendPacket(packet);
+ }
+
+ @Override
+ public void updateSkin(Skin skin) {
+ GameProfile newProfile = new GameProfile(uuid, name);
+ newProfile.getProperties().get("textures").clear();
+ newProfile.getProperties().put("textures", new Property("textures", skin.getValue(), skin.getSignature()));
+ this.packetPlayOutPlayerInfoAdd = new PacketPlayOutPlayerInfoWrapper().create(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, newProfile, name);
+ for (Player player : Bukkit.getOnlinePlayers()) {
+ PlayerConnection playerConnection = ((CraftPlayer) player).getHandle().playerConnection;
+ playerConnection.sendPacket(packetPlayOutPlayerInfoRemove);
+ playerConnection.sendPacket(packetPlayOutEntityDestroy);
+ playerConnection.sendPacket(packetPlayOutPlayerInfoAdd);
+ playerConnection.sendPacket(packetPlayOutNamedEntitySpawn);
+ }
+ }
+}
diff --git a/nms/v1_16_R3/src/main/java/net/jitse/npclib/nms/v1_16_R3/packets/PacketPlayOutAnimationWrapper.java b/nms/v1_16_R3/src/main/java/net/jitse/npclib/nms/v1_16_R3/packets/PacketPlayOutAnimationWrapper.java
new file mode 100644
index 0000000..3a67df1
--- /dev/null
+++ b/nms/v1_16_R3/src/main/java/net/jitse/npclib/nms/v1_16_R3/packets/PacketPlayOutAnimationWrapper.java
@@ -0,0 +1,20 @@
+package net.jitse.npclib.nms.v1_16_R3.packets;
+
+import com.comphenix.tinyprotocol.Reflection;
+import net.jitse.npclib.api.state.NPCAnimation;
+import net.minecraft.server.v1_16_R3.PacketPlayOutAnimation;
+
+public class PacketPlayOutAnimationWrapper {
+
+ public PacketPlayOutAnimation create(NPCAnimation npcAnimation, int entityId) {
+ PacketPlayOutAnimation packetPlayOutAnimation = new PacketPlayOutAnimation();
+
+ Reflection.getField(packetPlayOutAnimation.getClass(), "a", int.class)
+ .set(packetPlayOutAnimation, entityId);
+ Reflection.getField(packetPlayOutAnimation.getClass(), "b", int.class)
+ .set(packetPlayOutAnimation, npcAnimation.getId());
+
+ return packetPlayOutAnimation;
+ }
+
+}
diff --git a/nms/v1_16_R3/src/main/java/net/jitse/npclib/nms/v1_16_R3/packets/PacketPlayOutEntityHeadRotationWrapper.java b/nms/v1_16_R3/src/main/java/net/jitse/npclib/nms/v1_16_R3/packets/PacketPlayOutEntityHeadRotationWrapper.java
new file mode 100644
index 0000000..adfdf48
--- /dev/null
+++ b/nms/v1_16_R3/src/main/java/net/jitse/npclib/nms/v1_16_R3/packets/PacketPlayOutEntityHeadRotationWrapper.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2018 Jitse Boonstra
+ */
+
+package net.jitse.npclib.nms.v1_16_R3.packets;
+
+import com.comphenix.tinyprotocol.Reflection;
+import net.minecraft.server.v1_16_R3.PacketPlayOutEntityHeadRotation;
+import org.bukkit.Location;
+
+/**
+ * @author Jitse Boonstra
+ */
+public class PacketPlayOutEntityHeadRotationWrapper {
+
+ public PacketPlayOutEntityHeadRotation create(Location location, int entityId) {
+ PacketPlayOutEntityHeadRotation packetPlayOutEntityHeadRotation = new PacketPlayOutEntityHeadRotation();
+
+ Reflection.getField(packetPlayOutEntityHeadRotation.getClass(), "a", int.class).
+ set(packetPlayOutEntityHeadRotation, entityId);
+ Reflection.getField(packetPlayOutEntityHeadRotation.getClass(), "b", byte.class)
+ .set(packetPlayOutEntityHeadRotation, (byte) ((int) location.getYaw() * 256.0F / 360.0F));
+
+ return packetPlayOutEntityHeadRotation;
+ }
+}
diff --git a/nms/v1_16_R3/src/main/java/net/jitse/npclib/nms/v1_16_R3/packets/PacketPlayOutEntityMetadataWrapper.java b/nms/v1_16_R3/src/main/java/net/jitse/npclib/nms/v1_16_R3/packets/PacketPlayOutEntityMetadataWrapper.java
new file mode 100644
index 0000000..9f2a1c0
--- /dev/null
+++ b/nms/v1_16_R3/src/main/java/net/jitse/npclib/nms/v1_16_R3/packets/PacketPlayOutEntityMetadataWrapper.java
@@ -0,0 +1,39 @@
+package net.jitse.npclib.nms.v1_16_R3.packets;
+
+import net.jitse.npclib.api.state.NPCState;
+import net.minecraft.server.v1_16_R3.DataWatcher;
+import net.minecraft.server.v1_16_R3.DataWatcherObject;
+import net.minecraft.server.v1_16_R3.DataWatcherRegistry;
+import net.minecraft.server.v1_16_R3.PacketPlayOutEntityMetadata;
+
+import java.util.Collection;
+
+public class PacketPlayOutEntityMetadataWrapper {
+
+ public PacketPlayOutEntityMetadata create(Collection activateStates, int entityId) {
+ DataWatcher dataWatcher = new DataWatcher(null);
+ dataWatcher.register(new DataWatcherObject<>(16, DataWatcherRegistry.a), (byte) 127);
+
+ byte masked = NPCState.getMasked(activateStates);
+ // TODO: Find out why NPCState#CROUCHED doesn't work.
+ dataWatcher.register(new DataWatcherObject<>(0, DataWatcherRegistry.a), masked);
+
+// for (Player online : Bukkit.getOnlinePlayers()) {
+// DataWatcher watcher = ((CraftPlayer) online).getHandle().getDataWatcher();
+// try {
+// Field entriesField = watcher.getClass().getDeclaredField("entries");
+// entriesField.setAccessible(true);
+//
+// Int2ObjectOpenHashMap> entries = (Int2ObjectOpenHashMap>) entriesField.get(watcher);
+// entries.forEach((integer, item) -> {
+// if (item.b() instanceof Boolean || item.b() instanceof Byte)
+// online.sendMessage(integer + ": " + item.b() + " type = " + item.b().getClass().toString());
+// });
+// } catch (NoSuchFieldException | IllegalAccessException e) {
+// e.printStackTrace();
+// }
+// }
+
+ return new PacketPlayOutEntityMetadata(entityId, dataWatcher, true);
+ }
+}
diff --git a/nms/v1_16_R3/src/main/java/net/jitse/npclib/nms/v1_16_R3/packets/PacketPlayOutNamedEntitySpawnWrapper.java b/nms/v1_16_R3/src/main/java/net/jitse/npclib/nms/v1_16_R3/packets/PacketPlayOutNamedEntitySpawnWrapper.java
new file mode 100644
index 0000000..5b5c5ed
--- /dev/null
+++ b/nms/v1_16_R3/src/main/java/net/jitse/npclib/nms/v1_16_R3/packets/PacketPlayOutNamedEntitySpawnWrapper.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018 Jitse Boonstra
+ */
+
+package net.jitse.npclib.nms.v1_16_R3.packets;
+
+import com.comphenix.tinyprotocol.Reflection;
+import net.minecraft.server.v1_16_R3.PacketPlayOutNamedEntitySpawn;
+import org.bukkit.Location;
+
+import java.util.UUID;
+
+/**
+ * @author Jitse Boonstra
+ */
+public class PacketPlayOutNamedEntitySpawnWrapper {
+
+ public PacketPlayOutNamedEntitySpawn create(UUID uuid, Location location, int entityId) {
+ PacketPlayOutNamedEntitySpawn packetPlayOutNamedEntitySpawn = new PacketPlayOutNamedEntitySpawn();
+
+ Reflection.getField(packetPlayOutNamedEntitySpawn.getClass(), "a", int.class)
+ .set(packetPlayOutNamedEntitySpawn, entityId);
+ Reflection.getField(packetPlayOutNamedEntitySpawn.getClass(), "b", UUID.class)
+ .set(packetPlayOutNamedEntitySpawn, uuid);
+ Reflection.getField(packetPlayOutNamedEntitySpawn.getClass(), "c", double.class)
+ .set(packetPlayOutNamedEntitySpawn, location.getX());
+ Reflection.getField(packetPlayOutNamedEntitySpawn.getClass(), "d", double.class)
+ .set(packetPlayOutNamedEntitySpawn, location.getY());
+ Reflection.getField(packetPlayOutNamedEntitySpawn.getClass(), "e", double.class)
+ .set(packetPlayOutNamedEntitySpawn, location.getZ());
+ Reflection.getField(packetPlayOutNamedEntitySpawn.getClass(), "f", byte.class)
+ .set(packetPlayOutNamedEntitySpawn, (byte) ((int) (location.getYaw() * 256.0F / 360.0F)));
+ Reflection.getField(packetPlayOutNamedEntitySpawn.getClass(), "g", byte.class)
+ .set(packetPlayOutNamedEntitySpawn, (byte) ((int) (location.getPitch() * 256.0F / 360.0F)));
+
+ return packetPlayOutNamedEntitySpawn;
+ }
+}
diff --git a/nms/v1_16_R3/src/main/java/net/jitse/npclib/nms/v1_16_R3/packets/PacketPlayOutPlayerInfoWrapper.java b/nms/v1_16_R3/src/main/java/net/jitse/npclib/nms/v1_16_R3/packets/PacketPlayOutPlayerInfoWrapper.java
new file mode 100644
index 0000000..e08b510
--- /dev/null
+++ b/nms/v1_16_R3/src/main/java/net/jitse/npclib/nms/v1_16_R3/packets/PacketPlayOutPlayerInfoWrapper.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2018 Jitse Boonstra
+ */
+
+package net.jitse.npclib.nms.v1_16_R3.packets;
+
+import com.comphenix.tinyprotocol.Reflection;
+import com.mojang.authlib.GameProfile;
+import net.minecraft.server.v1_16_R3.EnumGamemode;
+import net.minecraft.server.v1_16_R3.IChatBaseComponent;
+import net.minecraft.server.v1_16_R3.PacketPlayOutPlayerInfo;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author Jitse Boonstra
+ */
+public class PacketPlayOutPlayerInfoWrapper {
+
+ private final Class> packetPlayOutPlayerInfoClazz = Reflection.getMinecraftClass("PacketPlayOutPlayerInfo");
+ private final Class> playerInfoDataClazz = Reflection.getMinecraftClass("PacketPlayOutPlayerInfo$PlayerInfoData");
+ private final Reflection.ConstructorInvoker playerInfoDataConstructor = Reflection.getConstructor(playerInfoDataClazz,
+ packetPlayOutPlayerInfoClazz, GameProfile.class, int.class, EnumGamemode.class, IChatBaseComponent.class);
+
+ public PacketPlayOutPlayerInfo create(PacketPlayOutPlayerInfo.EnumPlayerInfoAction action, GameProfile gameProfile, String name) {
+ PacketPlayOutPlayerInfo packetPlayOutPlayerInfo = new PacketPlayOutPlayerInfo();
+ Reflection.getField(packetPlayOutPlayerInfo.getClass(), "a", PacketPlayOutPlayerInfo.EnumPlayerInfoAction.class)
+ .set(packetPlayOutPlayerInfo, action);
+
+ Object playerInfoData = playerInfoDataConstructor.invoke(packetPlayOutPlayerInfo, gameProfile, 1, EnumGamemode.NOT_SET,
+ IChatBaseComponent.ChatSerializer.b("{\"text\":\"[NPC] " + name + "\",\"color\":\"dark_gray\"}"));
+
+ Reflection.FieldAccessor fieldAccessor = Reflection.getField(packetPlayOutPlayerInfo.getClass(), "b", List.class);
+ fieldAccessor.set(packetPlayOutPlayerInfo, Collections.singletonList(playerInfoData));
+
+ return packetPlayOutPlayerInfo;
+ }
+}
diff --git a/nms/v1_16_R3/src/main/java/net/jitse/npclib/nms/v1_16_R3/packets/PacketPlayOutScoreboardTeamWrapper.java b/nms/v1_16_R3/src/main/java/net/jitse/npclib/nms/v1_16_R3/packets/PacketPlayOutScoreboardTeamWrapper.java
new file mode 100644
index 0000000..49b127e
--- /dev/null
+++ b/nms/v1_16_R3/src/main/java/net/jitse/npclib/nms/v1_16_R3/packets/PacketPlayOutScoreboardTeamWrapper.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2018 Jitse Boonstra
+ */
+
+package net.jitse.npclib.nms.v1_16_R3.packets;
+
+import com.comphenix.tinyprotocol.Reflection;
+import net.minecraft.server.v1_16_R3.ChatComponentText;
+import net.minecraft.server.v1_16_R3.IChatBaseComponent;
+import net.minecraft.server.v1_16_R3.PacketPlayOutScoreboardTeam;
+
+import java.util.Collection;
+import java.util.Collections;
+
+/**
+ * @author Jitse Boonstra
+ */
+public class PacketPlayOutScoreboardTeamWrapper {
+
+ public PacketPlayOutScoreboardTeam createRegisterTeam(String name) {
+ PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeam = new PacketPlayOutScoreboardTeam();
+
+ Reflection.getField(packetPlayOutScoreboardTeam.getClass(), "i", int.class)
+ .set(packetPlayOutScoreboardTeam, 0);
+ Reflection.getField(packetPlayOutScoreboardTeam.getClass(), "a", String.class)
+ .set(packetPlayOutScoreboardTeam, name);
+ Reflection.getField(packetPlayOutScoreboardTeam.getClass(), "b", IChatBaseComponent.class)
+ .set(packetPlayOutScoreboardTeam, new ChatComponentText(name));
+ Reflection.getField(packetPlayOutScoreboardTeam.getClass(), "e", String.class)
+ .set(packetPlayOutScoreboardTeam, "never");
+ Reflection.getField(packetPlayOutScoreboardTeam.getClass(), "f", String.class)
+ .set(packetPlayOutScoreboardTeam, "never");
+ Reflection.getField(packetPlayOutScoreboardTeam.getClass(), "j", int.class)
+ .set(packetPlayOutScoreboardTeam, 0);
+ Reflection.FieldAccessor collectionFieldAccessor = Reflection.getField(
+ packetPlayOutScoreboardTeam.getClass(), "h", Collection.class);
+ collectionFieldAccessor.set(packetPlayOutScoreboardTeam, Collections.singletonList(name));
+
+ return packetPlayOutScoreboardTeam;
+ }
+
+ public PacketPlayOutScoreboardTeam createUnregisterTeam(String name) {
+ PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeam = new PacketPlayOutScoreboardTeam();
+
+ Reflection.getField(packetPlayOutScoreboardTeam.getClass(), "i", int.class)
+ .set(packetPlayOutScoreboardTeam, 1);
+ Reflection.getField(packetPlayOutScoreboardTeam.getClass(), "a", String.class)
+ .set(packetPlayOutScoreboardTeam, name);
+
+ return packetPlayOutScoreboardTeam;
+ }
+}
diff --git a/nms/v1_8_R3/pom.xml b/nms/v1_8_R3/pom.xml
index f79d2fd..39d38da 100755
--- a/nms/v1_8_R3/pom.xml
+++ b/nms/v1_8_R3/pom.xml
@@ -8,7 +8,7 @@
net.jitse
npclib-nms
- 2.9-SNAPSHOT
+ 2.11-SNAPSHOT
npclib-nms-v1_8_R3
diff --git a/nms/v1_9_R1/pom.xml b/nms/v1_9_R1/pom.xml
index 6760a1f..5471526 100755
--- a/nms/v1_9_R1/pom.xml
+++ b/nms/v1_9_R1/pom.xml
@@ -8,7 +8,7 @@
net.jitse
npclib-nms
- 2.9-SNAPSHOT
+ 2.11-SNAPSHOT
npclib-nms-v1_9_R1
diff --git a/nms/v1_9_R2/pom.xml b/nms/v1_9_R2/pom.xml
index 0a13be4..a496f18 100755
--- a/nms/v1_9_R2/pom.xml
+++ b/nms/v1_9_R2/pom.xml
@@ -8,7 +8,7 @@
net.jitse
npclib-nms
- 2.9-SNAPSHOT
+ 2.11-SNAPSHOT
npclib-nms-v1_9_R2
diff --git a/plugin/pom.xml b/plugin/pom.xml
index a5bca0c..7bf90ad 100644
--- a/plugin/pom.xml
+++ b/plugin/pom.xml
@@ -8,7 +8,7 @@
net.jitse
npclib
- 2.9-SNAPSHOT
+ 2.11-SNAPSHOT
npclib-plugin
@@ -92,6 +92,12 @@
${project.version}
compile
+
+ net.jitse
+ npclib-nms-v1_16_R3
+ ${project.version}
+ compile
+
diff --git a/pom.xml b/pom.xml
index f82abf4..b430d36 100755
--- a/pom.xml
+++ b/pom.xml
@@ -7,7 +7,7 @@
net.jitse
npclib
- 2.9-SNAPSHOT
+ 2.11-SNAPSHOT
UTF-8