Added support for LabyMod EmoteAPI.
This commit is contained in:
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>npclib</artifactId>
|
<artifactId>npclib</artifactId>
|
||||||
<groupId>net.jitse</groupId>
|
<groupId>net.jitse</groupId>
|
||||||
<version>2.4.2-SNAPSHOT</version>
|
<version>2.5-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>npclib-api</artifactId>
|
<artifactId>npclib-api</artifactId>
|
||||||
|
|||||||
@@ -135,4 +135,14 @@ public interface NPC {
|
|||||||
* @return ItemStack item.
|
* @return ItemStack item.
|
||||||
*/
|
*/
|
||||||
ItemStack getItem(NPCSlot slot);
|
ItemStack getItem(NPCSlot slot);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LABYMOD ONLY
|
||||||
|
* Let the NPC play an emote.
|
||||||
|
* (https://docs.labymod.net/pages/server/emote_api/)
|
||||||
|
*
|
||||||
|
* @param receiver The player who should see the emote.
|
||||||
|
* @param emoteId The emote id (see link).
|
||||||
|
*/
|
||||||
|
void forceLabyModEmote(Player receiver, int emoteId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
package net.jitse.npclib.internal;
|
package net.jitse.npclib.internal;
|
||||||
|
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
import com.mojang.authlib.GameProfile;
|
import com.mojang.authlib.GameProfile;
|
||||||
import com.mojang.authlib.properties.Property;
|
import com.mojang.authlib.properties.Property;
|
||||||
import net.jitse.npclib.NPCLib;
|
import net.jitse.npclib.NPCLib;
|
||||||
@@ -14,6 +16,7 @@ import net.jitse.npclib.api.skin.Skin;
|
|||||||
import net.jitse.npclib.api.state.NPCSlot;
|
import net.jitse.npclib.api.state.NPCSlot;
|
||||||
import net.jitse.npclib.api.state.NPCState;
|
import net.jitse.npclib.api.state.NPCState;
|
||||||
import net.jitse.npclib.hologram.Hologram;
|
import net.jitse.npclib.hologram.Hologram;
|
||||||
|
import net.labymod.utilities.LMCUtils;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
@@ -25,10 +28,7 @@ import java.util.*;
|
|||||||
|
|
||||||
public abstract class NPCBase implements NPC, NPCPacketHandler {
|
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 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 Set<UUID> hasTeamRegistered = new HashSet<>();
|
protected final Set<UUID> hasTeamRegistered = new HashSet<>();
|
||||||
protected final Set<NPCState> activeStates = EnumSet.noneOf(NPCState.class);
|
protected final Set<NPCState> activeStates = EnumSet.noneOf(NPCState.class);
|
||||||
|
|
||||||
@@ -36,6 +36,11 @@ public abstract class NPCBase implements NPC, NPCPacketHandler {
|
|||||||
private final Set<UUID> autoHidden = new HashSet<>();
|
private final Set<UUID> autoHidden = new HashSet<>();
|
||||||
|
|
||||||
protected double cosFOV = Math.cos(Math.toRadians(60));
|
protected double cosFOV = Math.cos(Math.toRadians(60));
|
||||||
|
// 12/4/20, JMB: Changed the UUID in order to enable LabyMod Emotes:
|
||||||
|
// This gives a format similar to: 528086a2-4f5f-2ec2-0000-000000000000
|
||||||
|
protected UUID uuid = new UUID(new Random().nextLong(), 0);
|
||||||
|
protected String name = uuid.toString().replace("-", "").substring(0, 10);
|
||||||
|
protected GameProfile gameProfile = new GameProfile(uuid, name);
|
||||||
|
|
||||||
protected NPCLib instance;
|
protected NPCLib instance;
|
||||||
protected List<String> text;
|
protected List<String> text;
|
||||||
@@ -86,6 +91,16 @@ public abstract class NPCBase implements NPC, NPCPacketHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void forceLabyModEmote(Player receiver, int emoteId) {
|
||||||
|
JsonArray array = new JsonArray();
|
||||||
|
JsonObject forcedEmote = new JsonObject();
|
||||||
|
forcedEmote.addProperty("uuid", uuid.toString());
|
||||||
|
forcedEmote.addProperty("emote_id", emoteId);
|
||||||
|
array.add(forcedEmote);
|
||||||
|
LMCUtils.sendLMCMessage(receiver, "emote_api", array.getAsJsonObject());
|
||||||
|
}
|
||||||
|
|
||||||
public void disableFOV() {
|
public void disableFOV() {
|
||||||
this.cosFOV = 0; // Or equals Math.cos(1/2 * Math.PI).
|
this.cosFOV = 0; // Or equals Math.cos(1/2 * Math.PI).
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,152 @@
|
|||||||
|
package net.labymod.utilities;
|
||||||
|
|
||||||
|
import com.comphenix.tinyprotocol.Reflection;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
import io.netty.handler.codec.DecoderException;
|
||||||
|
import io.netty.handler.codec.EncoderException;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
|
public class LMCUtils {
|
||||||
|
|
||||||
|
private static final Class<?> CRAFT_PLAYER_CLASS = Reflection.getCraftBukkitClass("CraftPlayer");
|
||||||
|
private static final Reflection.MethodInvoker GET_HANDLE_METHOD = Reflection.getMethod(CRAFT_PLAYER_CLASS, "getHandle");
|
||||||
|
private static final Class<?> PLAYER_CONNECTION_CLASS = Reflection.getMinecraftClass("PlayerConnection");
|
||||||
|
private static final Reflection.FieldAccessor PLAYER_CONNECTION_FIELD = Reflection.getField(Reflection.getMinecraftClass("EntityPlayer"),
|
||||||
|
"playerConnection", PLAYER_CONNECTION_CLASS);
|
||||||
|
private static final Reflection.MethodInvoker SEND_PACKET_METHOD = Reflection.getMethod(PLAYER_CONNECTION_CLASS,
|
||||||
|
"sendPacket", Reflection.getMinecraftClass("Packet"));
|
||||||
|
private static final Class<?> PACKET_DATA_SERIALIZER_CLASS = Reflection.getMinecraftClass("PacketDataSerializer");
|
||||||
|
private static final Reflection.ConstructorInvoker PACKET_DATA_SERIALIZER_CONSTRUCTOR = Reflection.getConstructor(
|
||||||
|
PACKET_DATA_SERIALIZER_CLASS, ByteBuf.class);
|
||||||
|
private static final Reflection.ConstructorInvoker PACKET_PLAY_OUT_CUSTOM_PAYLOAD_CONSTRUCTOR = Reflection.getConstructor(
|
||||||
|
Reflection.getMinecraftClass("PacketPlayOutCustomPayload"), String.class, PACKET_DATA_SERIALIZER_CLASS);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a LMC message to the minecraft client
|
||||||
|
*
|
||||||
|
* @param player Minecraft Client
|
||||||
|
* @param key LMC message key
|
||||||
|
* @param messageContent json object content
|
||||||
|
*/
|
||||||
|
public static void sendLMCMessage(Player player, String key, JsonObject messageContent) {
|
||||||
|
byte[] bytes = LMCUtils.getBytesToSend(key, messageContent.toString());
|
||||||
|
|
||||||
|
// 12/4/20, JMB: Converted into reflections for multi-version support:
|
||||||
|
// PacketDataSerializer pds = new PacketDataSerializer(Unpooled.wrappedBuffer(bytes));
|
||||||
|
// PacketPlayOutCustomPayload payloadPacket = new PacketPlayOutCustomPayload("LMC", pds);
|
||||||
|
// ((CraftPlayer) player).getHandle().playerConnection.sendPacket(payloadPacket);
|
||||||
|
Object pds = PACKET_DATA_SERIALIZER_CONSTRUCTOR.invoke(Unpooled.wrappedBuffer(bytes));
|
||||||
|
Object payloadPacket = PACKET_PLAY_OUT_CUSTOM_PAYLOAD_CONSTRUCTOR.invoke("LMC", pds);
|
||||||
|
SEND_PACKET_METHOD.invoke(PLAYER_CONNECTION_FIELD.get(GET_HANDLE_METHOD.invoke(CRAFT_PLAYER_CLASS.cast(player))), payloadPacket);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the bytes that are required to send the given message
|
||||||
|
*
|
||||||
|
* @param messageKey the message's key
|
||||||
|
* @param messageContents the message's contents
|
||||||
|
* @return the byte array that should be the payload
|
||||||
|
*/
|
||||||
|
public static byte[] getBytesToSend(String messageKey, String messageContents) {
|
||||||
|
// Getting an empty buffer
|
||||||
|
ByteBuf byteBuf = Unpooled.buffer();
|
||||||
|
|
||||||
|
// Writing the message-key to the buffer
|
||||||
|
writeString(byteBuf, messageKey);
|
||||||
|
|
||||||
|
// Writing the contents to the buffer
|
||||||
|
writeString(byteBuf, messageContents);
|
||||||
|
|
||||||
|
// Copying the buffer's bytes to the byte array
|
||||||
|
byte[] bytes = new byte[byteBuf.readableBytes()];
|
||||||
|
byteBuf.readBytes(bytes);
|
||||||
|
|
||||||
|
// Returning the byte array
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a varint to the given byte buffer
|
||||||
|
*
|
||||||
|
* @param buf the byte buffer the int should be written to
|
||||||
|
* @param input the int that should be written to the buffer
|
||||||
|
*/
|
||||||
|
private static void writeVarIntToBuffer(ByteBuf buf, int input) {
|
||||||
|
while ((input & -128) != 0) {
|
||||||
|
buf.writeByte(input & 127 | 128);
|
||||||
|
input >>>= 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.writeByte(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a string to the given byte buffer
|
||||||
|
*
|
||||||
|
* @param buf the byte buffer the string should be written to
|
||||||
|
* @param string the string that should be written to the buffer
|
||||||
|
*/
|
||||||
|
private static void writeString(ByteBuf buf, String string) {
|
||||||
|
byte[] abyte = string.getBytes(Charset.forName("UTF-8"));
|
||||||
|
|
||||||
|
if (abyte.length > Short.MAX_VALUE) {
|
||||||
|
throw new EncoderException("String too big (was " + string.length() + " bytes encoded, max " + Short.MAX_VALUE + ")");
|
||||||
|
} else {
|
||||||
|
writeVarIntToBuffer(buf, abyte.length);
|
||||||
|
buf.writeBytes(abyte);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a varint from the given byte buffer
|
||||||
|
*
|
||||||
|
* @param buf the byte buffer the varint should be read from
|
||||||
|
* @return the int read
|
||||||
|
*/
|
||||||
|
public static int readVarIntFromBuffer(ByteBuf buf) {
|
||||||
|
int i = 0;
|
||||||
|
int j = 0;
|
||||||
|
|
||||||
|
byte b0;
|
||||||
|
do {
|
||||||
|
b0 = buf.readByte();
|
||||||
|
i |= (b0 & 127) << j++ * 7;
|
||||||
|
if (j > 5) {
|
||||||
|
throw new RuntimeException("VarInt too big");
|
||||||
|
}
|
||||||
|
} while ((b0 & 128) == 128);
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a string from the given byte buffer
|
||||||
|
*
|
||||||
|
* @param buf the byte buffer the string should be read from
|
||||||
|
* @param maxLength the string's max-length
|
||||||
|
* @return the string read
|
||||||
|
*/
|
||||||
|
public static String readString(ByteBuf buf, int maxLength) {
|
||||||
|
int i = readVarIntFromBuffer(buf);
|
||||||
|
|
||||||
|
if (i > maxLength * 4) {
|
||||||
|
throw new DecoderException("The received encoded string buffer length is longer than maximum allowed (" + i + " > " + maxLength * 4 + ")");
|
||||||
|
} else if (i < 0) {
|
||||||
|
throw new DecoderException("The received encoded string buffer length is less than zero! Weird string!");
|
||||||
|
} else {
|
||||||
|
byte[] bytes = new byte[i];
|
||||||
|
buf.readBytes(bytes);
|
||||||
|
|
||||||
|
String s = new String(bytes, Charset.forName("UTF-8"));
|
||||||
|
if (s.length() > maxLength) {
|
||||||
|
throw new DecoderException("The received string length is longer than maximum allowed (" + i + " > " + maxLength + ")");
|
||||||
|
} else {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>net.jitse</groupId>
|
<groupId>net.jitse</groupId>
|
||||||
<artifactId>npclib</artifactId>
|
<artifactId>npclib</artifactId>
|
||||||
<version>2.4.2-SNAPSHOT</version>
|
<version>2.5-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>npclib-nms</artifactId>
|
<artifactId>npclib-nms</artifactId>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>net.jitse</groupId>
|
<groupId>net.jitse</groupId>
|
||||||
<artifactId>npclib-nms</artifactId>
|
<artifactId>npclib-nms</artifactId>
|
||||||
<version>2.4.2-SNAPSHOT</version>
|
<version>2.5-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>npclib-nms-v1_10_R1</artifactId>
|
<artifactId>npclib-nms-v1_10_R1</artifactId>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>net.jitse</groupId>
|
<groupId>net.jitse</groupId>
|
||||||
<artifactId>npclib-nms</artifactId>
|
<artifactId>npclib-nms</artifactId>
|
||||||
<version>2.4.2-SNAPSHOT</version>
|
<version>2.5-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>npclib-nms-v1_11_R1</artifactId>
|
<artifactId>npclib-nms-v1_11_R1</artifactId>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>net.jitse</groupId>
|
<groupId>net.jitse</groupId>
|
||||||
<artifactId>npclib-nms</artifactId>
|
<artifactId>npclib-nms</artifactId>
|
||||||
<version>2.4.2-SNAPSHOT</version>
|
<version>2.5-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>npclib-nms-v1_12_R1</artifactId>
|
<artifactId>npclib-nms-v1_12_R1</artifactId>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>net.jitse</groupId>
|
<groupId>net.jitse</groupId>
|
||||||
<artifactId>npclib-nms</artifactId>
|
<artifactId>npclib-nms</artifactId>
|
||||||
<version>2.4.2-SNAPSHOT</version>
|
<version>2.5-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>npclib-nms-v1_13_R1</artifactId>
|
<artifactId>npclib-nms-v1_13_R1</artifactId>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>net.jitse</groupId>
|
<groupId>net.jitse</groupId>
|
||||||
<artifactId>npclib-nms</artifactId>
|
<artifactId>npclib-nms</artifactId>
|
||||||
<version>2.4.2-SNAPSHOT</version>
|
<version>2.5-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>npclib-nms-v1_13_R2</artifactId>
|
<artifactId>npclib-nms-v1_13_R2</artifactId>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>net.jitse</groupId>
|
<groupId>net.jitse</groupId>
|
||||||
<artifactId>npclib-nms</artifactId>
|
<artifactId>npclib-nms</artifactId>
|
||||||
<version>2.4.2-SNAPSHOT</version>
|
<version>2.5-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>npclib-nms-v1_14_R1</artifactId>
|
<artifactId>npclib-nms-v1_14_R1</artifactId>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>net.jitse</groupId>
|
<groupId>net.jitse</groupId>
|
||||||
<artifactId>npclib-nms</artifactId>
|
<artifactId>npclib-nms</artifactId>
|
||||||
<version>2.4.2-SNAPSHOT</version>
|
<version>2.5-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>npclib-nms-v1_15_R1</artifactId>
|
<artifactId>npclib-nms-v1_15_R1</artifactId>
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>net.jitse</groupId>
|
<groupId>net.jitse</groupId>
|
||||||
<artifactId>npclib-nms</artifactId>
|
<artifactId>npclib-nms</artifactId>
|
||||||
<version>2.4.2-SNAPSHOT</version>
|
<version>2.5-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>npclib-nms-v1_8_R2</artifactId>
|
<artifactId>npclib-nms-v1_8_R2</artifactId>
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>net.jitse</groupId>
|
<groupId>net.jitse</groupId>
|
||||||
<artifactId>npclib-nms</artifactId>
|
<artifactId>npclib-nms</artifactId>
|
||||||
<version>2.4.2-SNAPSHOT</version>
|
<version>2.5-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>npclib-nms-v1_8_R3</artifactId>
|
<artifactId>npclib-nms-v1_8_R3</artifactId>
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>net.jitse</groupId>
|
<groupId>net.jitse</groupId>
|
||||||
<artifactId>npclib-nms</artifactId>
|
<artifactId>npclib-nms</artifactId>
|
||||||
<version>2.4.2-SNAPSHOT</version>
|
<version>2.5-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>npclib-nms-v1_9_R1</artifactId>
|
<artifactId>npclib-nms-v1_9_R1</artifactId>
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>net.jitse</groupId>
|
<groupId>net.jitse</groupId>
|
||||||
<artifactId>npclib-nms</artifactId>
|
<artifactId>npclib-nms</artifactId>
|
||||||
<version>2.4.2-SNAPSHOT</version>
|
<version>2.5-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>npclib-nms-v1_9_R2</artifactId>
|
<artifactId>npclib-nms-v1_9_R2</artifactId>
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>net.jitse</groupId>
|
<groupId>net.jitse</groupId>
|
||||||
<artifactId>npclib</artifactId>
|
<artifactId>npclib</artifactId>
|
||||||
<version>2.4.2-SNAPSHOT</version>
|
<version>2.5-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>npclib-plugin</artifactId>
|
<artifactId>npclib-plugin</artifactId>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
<groupId>net.jitse</groupId>
|
<groupId>net.jitse</groupId>
|
||||||
<artifactId>npclib</artifactId>
|
<artifactId>npclib</artifactId>
|
||||||
<version>2.4.2-SNAPSHOT</version>
|
<version>2.5-SNAPSHOT</version>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
|||||||
Reference in New Issue
Block a user