package com.alttd.halloween.leaderboard; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.ProtocolManager; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.reflect.FieldAccessException; import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.wrappers.WrappedChatComponent; import com.comphenix.protocol.wrappers.WrappedDataWatcher; import lombok.extern.slf4j.Slf4j; import org.bukkit.Location; import org.bukkit.entity.EntityType; import java.util.List; import java.util.Optional; import java.util.UUID; @Slf4j public class HoverText { private final ProtocolManager protocolManager; public HoverText(ProtocolManager protocolManager) { this.protocolManager = protocolManager; } public Optional setLine(LeaderboardLineEntity entity, String text) { return setLine(entity.entityId(), text); } public Optional createLeaderboardLineEntity(Location location) { try { PacketContainer spawnPacket = protocolManager.createPacket(PacketType.Play.Server.SPAWN_ENTITY); int entityId = (int) (Math.random() * Integer.MAX_VALUE); spawnPacket.getModifier().writeDefaults(); spawnPacket.getIntegers().write(0, entityId); spawnPacket.getUUIDs().write(0, UUID.randomUUID()); spawnPacket.getDoubles() .write(0, location.getX()) .write(1, location.getY()) .write(2, location.getZ()); spawnPacket.getIntegers().write(4, 0); // Pitch spawnPacket.getIntegers().write(5, 0); // Yaw spawnPacket.getEntityTypeModifier().write(0, EntityType.ARMOR_STAND); PacketContainer destroyPacket = protocolManager.createPacket(PacketType.Play.Server.ENTITY_DESTROY); destroyPacket.getIntLists().write(0, List.of(entityId)); return Optional.of(new LeaderboardLineEntity(entityId, spawnPacket, destroyPacket)); } catch (Exception e) { log.error("Failed to create hover text entity", e); } return Optional.empty(); } public Optional setLine(int entityId, String text) { try { PacketContainer metaPacket = protocolManager.createPacket(PacketType.Play.Server.ENTITY_METADATA); metaPacket.getIntegers().write(0, entityId); WrappedDataWatcher watcher = new WrappedDataWatcher(); WrappedDataWatcher.Serializer serializer = WrappedDataWatcher.Registry.get(MinecraftReflection.getIChatBaseComponentClass()); WrappedDataWatcher.WrappedDataWatcherObject displayName = new WrappedDataWatcher.WrappedDataWatcherObject(2, serializer); WrappedChatComponent component = WrappedChatComponent.fromText(text); watcher.setObject(displayName, Optional.of(component.getHandle())); watcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(3, WrappedDataWatcher.Registry.get(Boolean.class)), true); // Custom Name Visible watcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, WrappedDataWatcher.Registry.get(Byte.class)), (byte) 0x20); // Invisible metaPacket.getWatchableCollectionModifier().write(0, watcher.getWatchableObjects()); return Optional.of(metaPacket); } catch (FieldAccessException e) { log.error("Failed to edit line on hover text", e); } return Optional.empty(); } }