2022-11-16 14:58:05 +01:00
|
|
|
package net.citizensnpcs;
|
|
|
|
|
2022-11-28 16:10:50 +01:00
|
|
|
import java.util.Set;
|
|
|
|
|
2022-11-16 14:58:05 +01:00
|
|
|
import org.bukkit.entity.Entity;
|
|
|
|
|
2022-12-20 14:27:01 +01:00
|
|
|
import com.comphenix.protocol.PacketType;
|
2022-11-16 14:58:05 +01:00
|
|
|
import com.comphenix.protocol.PacketType.Play.Server;
|
|
|
|
import com.comphenix.protocol.ProtocolLibrary;
|
|
|
|
import com.comphenix.protocol.ProtocolManager;
|
|
|
|
import com.comphenix.protocol.events.ListenerPriority;
|
|
|
|
import com.comphenix.protocol.events.PacketAdapter;
|
2022-11-28 16:10:50 +01:00
|
|
|
import com.comphenix.protocol.events.PacketContainer;
|
2022-11-16 14:58:05 +01:00
|
|
|
import com.comphenix.protocol.events.PacketEvent;
|
2022-12-20 14:27:01 +01:00
|
|
|
import com.comphenix.protocol.reflect.FieldAccessException;
|
2022-11-28 16:10:50 +01:00
|
|
|
import com.comphenix.protocol.reflect.StructureModifier;
|
|
|
|
import com.comphenix.protocol.utility.MinecraftReflection;
|
|
|
|
import com.comphenix.protocol.wrappers.EnumWrappers;
|
2022-11-16 14:58:05 +01:00
|
|
|
|
|
|
|
import net.citizensnpcs.api.npc.NPC;
|
|
|
|
import net.citizensnpcs.npc.ai.NPCHolder;
|
2022-11-29 23:13:55 +01:00
|
|
|
import net.citizensnpcs.trait.RotationTrait;
|
2022-12-06 16:50:11 +01:00
|
|
|
import net.citizensnpcs.trait.RotationTrait.PacketRotationSession;
|
2022-11-16 14:58:05 +01:00
|
|
|
|
|
|
|
public class ProtocolLibListener {
|
2022-11-28 16:10:50 +01:00
|
|
|
private final Class<?> flagsClass;
|
2022-11-16 14:58:05 +01:00
|
|
|
private final ProtocolManager manager;
|
|
|
|
private final Citizens plugin;
|
|
|
|
|
|
|
|
public ProtocolLibListener(Citizens plugin) {
|
|
|
|
this.plugin = plugin;
|
|
|
|
this.manager = ProtocolLibrary.getProtocolManager();
|
2022-11-28 16:10:50 +01:00
|
|
|
flagsClass = MinecraftReflection.getMinecraftClass("EnumPlayerTeleportFlags",
|
|
|
|
"PacketPlayOutPosition$EnumPlayerTeleportFlags",
|
|
|
|
"network.protocol.game.PacketPlayOutPosition$EnumPlayerTeleportFlags");
|
2022-11-16 14:58:05 +01:00
|
|
|
manager.addPacketListener(
|
|
|
|
new PacketAdapter(plugin, ListenerPriority.MONITOR, Server.ENTITY_HEAD_ROTATION, Server.ENTITY_LOOK) {
|
|
|
|
@Override
|
|
|
|
public void onPacketSending(PacketEvent event) {
|
2022-11-28 16:10:50 +01:00
|
|
|
PacketContainer packet = event.getPacket();
|
2022-12-20 14:27:01 +01:00
|
|
|
Entity entity = null;
|
|
|
|
try {
|
|
|
|
entity = manager.getEntityFromID(event.getPlayer().getWorld(),
|
|
|
|
packet.getIntegers().getValues().get(0));
|
|
|
|
} catch (FieldAccessException ex) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-11-16 14:58:05 +01:00
|
|
|
if (!(entity instanceof NPCHolder))
|
|
|
|
return;
|
2022-11-28 16:10:50 +01:00
|
|
|
|
2022-11-16 14:58:05 +01:00
|
|
|
NPC npc = ((NPCHolder) entity).getNPC();
|
2022-11-29 23:13:55 +01:00
|
|
|
RotationTrait trait = npc.getTraitNullable(RotationTrait.class);
|
2022-11-16 14:58:05 +01:00
|
|
|
if (trait == null)
|
|
|
|
return;
|
|
|
|
|
2022-12-06 16:50:11 +01:00
|
|
|
PacketRotationSession session = trait.getPacketSession(event.getPlayer());
|
2022-11-28 16:10:50 +01:00
|
|
|
if (session == null || !session.isActive())
|
|
|
|
return;
|
|
|
|
|
2022-12-20 14:27:01 +01:00
|
|
|
PacketType type = event.getPacketType();
|
|
|
|
if (type == Server.ENTITY_HEAD_ROTATION) {
|
2022-11-28 16:10:50 +01:00
|
|
|
packet.getBytes().write(0, degToByte(session.getHeadYaw()));
|
2022-12-20 14:27:01 +01:00
|
|
|
} else if (type == Server.ENTITY_LOOK) {
|
2022-11-28 16:10:50 +01:00
|
|
|
packet.getBytes().write(0, degToByte(session.getBodyYaw()));
|
|
|
|
packet.getBytes().write(1, degToByte(session.getPitch()));
|
2022-12-20 14:27:01 +01:00
|
|
|
} else if (type == Server.ENTITY_MOVE_LOOK || type == Server.REL_ENTITY_MOVE_LOOK) {
|
2022-11-28 16:10:50 +01:00
|
|
|
packet.getBytes().write(0, degToByte(session.getBodyYaw()));
|
|
|
|
packet.getBytes().write(1, degToByte(session.getPitch()));
|
2022-12-20 14:27:01 +01:00
|
|
|
} else if (type == Server.POSITION) {
|
2022-11-28 16:10:50 +01:00
|
|
|
Set<PlayerTeleportFlag> rel = getFlagsModifier(packet).read(0);
|
|
|
|
rel.remove(PlayerTeleportFlag.ZYAW);
|
|
|
|
rel.remove(PlayerTeleportFlag.ZPITCH);
|
|
|
|
getFlagsModifier(packet).write(0, rel);
|
|
|
|
packet.getFloat().write(0, session.getBodyYaw());
|
|
|
|
packet.getFloat().write(1, session.getPitch());
|
2022-11-16 14:58:05 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2022-11-28 16:10:50 +01:00
|
|
|
|
|
|
|
private StructureModifier<Set<PlayerTeleportFlag>> getFlagsModifier(PacketContainer handle) {
|
|
|
|
return handle.getSets(EnumWrappers.getGenericConverter(flagsClass, PlayerTeleportFlag.class));
|
|
|
|
}
|
|
|
|
|
|
|
|
public enum PlayerTeleportFlag {
|
|
|
|
X,
|
|
|
|
Y,
|
|
|
|
Z,
|
|
|
|
ZPITCH,
|
|
|
|
ZYAW,
|
|
|
|
}
|
2022-12-18 08:39:48 +01:00
|
|
|
|
|
|
|
private static byte degToByte(float in) {
|
|
|
|
return (byte) (in * 256.0F / 360.0F);
|
|
|
|
}
|
2022-11-16 14:58:05 +01:00
|
|
|
}
|