From 849eb7bc4f947ca4ef72f572de9c10ed41dee99f Mon Sep 17 00:00:00 2001 From: thamid-gamer <60953955+thamid-gamer@users.noreply.github.com> Date: Mon, 11 Oct 2021 19:15:03 -0400 Subject: [PATCH 1/6] Packet classes --- .../nms/v1_16_R3/ArenaNMSBridge_v1_16_R3.java | 25 ++++++++++++- .../packet/PacketBridge_v1_16_R3.java | 16 ++++++++ .../arenaapi/nms/common/ArenaNMSBridge.java | 9 ++++- .../nms/common/packet/MultiPacket.java | 26 +++++++++++++ .../arenaapi/nms/common/packet/Packet.java | 19 ++++++++++ .../nms/common/packet/PacketBridge.java | 7 ++++ .../nms/common/packet/ProtocolLibPacket.java | 37 +++++++++++++++++++ 7 files changed, 137 insertions(+), 2 deletions(-) create mode 100644 nms/nms-1_16_R3/src/main/java/io/github/zap/arenaapi/nms/v1_16_R3/packet/PacketBridge_v1_16_R3.java create mode 100644 nms/nms-common/src/main/java/io/github/zap/arenaapi/nms/common/packet/MultiPacket.java create mode 100644 nms/nms-common/src/main/java/io/github/zap/arenaapi/nms/common/packet/Packet.java create mode 100644 nms/nms-common/src/main/java/io/github/zap/arenaapi/nms/common/packet/PacketBridge.java create mode 100644 nms/nms-common/src/main/java/io/github/zap/arenaapi/nms/common/packet/ProtocolLibPacket.java diff --git a/nms/nms-1_16_R3/src/main/java/io/github/zap/arenaapi/nms/v1_16_R3/ArenaNMSBridge_v1_16_R3.java b/nms/nms-1_16_R3/src/main/java/io/github/zap/arenaapi/nms/v1_16_R3/ArenaNMSBridge_v1_16_R3.java index 2f84cbb..10811a2 100644 --- a/nms/nms-1_16_R3/src/main/java/io/github/zap/arenaapi/nms/v1_16_R3/ArenaNMSBridge_v1_16_R3.java +++ b/nms/nms-1_16_R3/src/main/java/io/github/zap/arenaapi/nms/v1_16_R3/ArenaNMSBridge_v1_16_R3.java @@ -1,21 +1,39 @@ package io.github.zap.arenaapi.nms.v1_16_R3; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.ProtocolManager; import io.github.zap.arenaapi.nms.common.ArenaNMSBridge; import io.github.zap.arenaapi.nms.common.entity.EntityBridge; import io.github.zap.arenaapi.nms.common.itemstack.ItemStackBridge; +import io.github.zap.arenaapi.nms.common.packet.PacketBridge; import io.github.zap.arenaapi.nms.common.player.PlayerBridge; import io.github.zap.arenaapi.nms.common.world.WorldBridge; import io.github.zap.arenaapi.nms.v1_16_R3.entity.EntityBridge_v1_16_R3; import io.github.zap.arenaapi.nms.v1_16_R3.itemstack.ItemStackBridge_v1_16_R3; +import io.github.zap.arenaapi.nms.v1_16_R3.packet.PacketBridge_v1_16_R3; import io.github.zap.arenaapi.nms.v1_16_R3.player.PlayerBridge_v1_16_R3; import io.github.zap.arenaapi.nms.v1_16_R3.world.WorldBridge_v1_16_R3; +import org.apache.commons.lang3.NotImplementedException; import org.jetbrains.annotations.NotNull; public class ArenaNMSBridge_v1_16_R3 implements ArenaNMSBridge { public static final ArenaNMSBridge_v1_16_R3 INSTANCE = new ArenaNMSBridge_v1_16_R3(); private static final String VERSION = "v1_16_R3"; - private ArenaNMSBridge_v1_16_R3() {} + private final PacketBridge packetBridge; + + private ArenaNMSBridge_v1_16_R3() { + try { + Class.forName("com.comphenix.protocol.ProtocolLibrary"); + } + catch (ClassNotFoundException error) { + throw new NotImplementedException("No minecraft PacketBridge implementation exists for version " + + VERSION + ", and ProtocolLibrary was not detected on the server!"); + } + + ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager(); + this.packetBridge = new PacketBridge_v1_16_R3(protocolManager); + } @Override public @NotNull String version() { @@ -32,6 +50,11 @@ private ArenaNMSBridge_v1_16_R3() {} return ItemStackBridge_v1_16_R3.INSTANCE; } + @Override + public @NotNull PacketBridge packetBridge() { + return packetBridge; + } + @Override public @NotNull PlayerBridge playerBridge() { return PlayerBridge_v1_16_R3.INSTANCE; diff --git a/nms/nms-1_16_R3/src/main/java/io/github/zap/arenaapi/nms/v1_16_R3/packet/PacketBridge_v1_16_R3.java b/nms/nms-1_16_R3/src/main/java/io/github/zap/arenaapi/nms/v1_16_R3/packet/PacketBridge_v1_16_R3.java new file mode 100644 index 0000000..a70832b --- /dev/null +++ b/nms/nms-1_16_R3/src/main/java/io/github/zap/arenaapi/nms/v1_16_R3/packet/PacketBridge_v1_16_R3.java @@ -0,0 +1,16 @@ +package io.github.zap.arenaapi.nms.v1_16_R3.packet; + +import com.comphenix.protocol.ProtocolManager; +import io.github.zap.arenaapi.nms.common.packet.PacketBridge; +import org.jetbrains.annotations.NotNull; + +@SuppressWarnings("ClassCanBeRecord") +public class PacketBridge_v1_16_R3 implements PacketBridge { + + private final ProtocolManager protocolManager; + + public PacketBridge_v1_16_R3(@NotNull ProtocolManager protocolManager) { + this.protocolManager = protocolManager; + } + +} diff --git a/nms/nms-common/src/main/java/io/github/zap/arenaapi/nms/common/ArenaNMSBridge.java b/nms/nms-common/src/main/java/io/github/zap/arenaapi/nms/common/ArenaNMSBridge.java index f8dd662..a6d914f 100644 --- a/nms/nms-common/src/main/java/io/github/zap/arenaapi/nms/common/ArenaNMSBridge.java +++ b/nms/nms-common/src/main/java/io/github/zap/arenaapi/nms/common/ArenaNMSBridge.java @@ -2,6 +2,7 @@ import io.github.zap.arenaapi.nms.common.entity.EntityBridge; import io.github.zap.arenaapi.nms.common.itemstack.ItemStackBridge; +import io.github.zap.arenaapi.nms.common.packet.PacketBridge; import io.github.zap.arenaapi.nms.common.player.PlayerBridge; import io.github.zap.arenaapi.nms.common.world.WorldBridge; import org.bukkit.Bukkit; @@ -37,10 +38,16 @@ private static String nmsVersion() { /** * Returns a bridge used to proxy methods relating to item stacks. - * @return A PlayerBridge instance + * @return A {@link ItemStackBridge} instance */ @NotNull ItemStackBridge itemStackBridge(); + /** + * Returns a bridge used to interact with packets + * @return A {@link PacketBridge} instance + */ + @NotNull PacketBridge packetBridge(); + /** * Returns a bridge used to proxy methods relating to players. * @return A PlayerBridge instance diff --git a/nms/nms-common/src/main/java/io/github/zap/arenaapi/nms/common/packet/MultiPacket.java b/nms/nms-common/src/main/java/io/github/zap/arenaapi/nms/common/packet/MultiPacket.java new file mode 100644 index 0000000..33d3e6c --- /dev/null +++ b/nms/nms-common/src/main/java/io/github/zap/arenaapi/nms/common/packet/MultiPacket.java @@ -0,0 +1,26 @@ +package io.github.zap.arenaapi.nms.common.packet; + +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; + +/** + * A packet formed from many other packets + */ +@SuppressWarnings("ClassCanBeRecord") +public class MultiPacket implements Packet { + + private final Packet[] packets; + + public MultiPacket(@NotNull Packet... packets) { + this.packets = packets; + } + + @Override + public void sendToPlayer(@NotNull Plugin plugin, @NotNull Player player) { + for (Packet packet : packets) { + packet.sendToPlayer(plugin, player); + } + } + +} diff --git a/nms/nms-common/src/main/java/io/github/zap/arenaapi/nms/common/packet/Packet.java b/nms/nms-common/src/main/java/io/github/zap/arenaapi/nms/common/packet/Packet.java new file mode 100644 index 0000000..499481f --- /dev/null +++ b/nms/nms-common/src/main/java/io/github/zap/arenaapi/nms/common/packet/Packet.java @@ -0,0 +1,19 @@ +package io.github.zap.arenaapi.nms.common.packet; + +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; + +/** + * A minecraft packet used to circumvent limitations of the Bukkit API + */ +public interface Packet { + + /** + * Sends the packet to a {@link Player}. + * @param plugin The {@link Plugin} from which the packet is being sent + * @param player The {@link Player} to send the packet to + */ + void sendToPlayer(@NotNull Plugin plugin, @NotNull Player player); + +} diff --git a/nms/nms-common/src/main/java/io/github/zap/arenaapi/nms/common/packet/PacketBridge.java b/nms/nms-common/src/main/java/io/github/zap/arenaapi/nms/common/packet/PacketBridge.java new file mode 100644 index 0000000..dae5ea1 --- /dev/null +++ b/nms/nms-common/src/main/java/io/github/zap/arenaapi/nms/common/packet/PacketBridge.java @@ -0,0 +1,7 @@ +package io.github.zap.arenaapi.nms.common.packet; + +/** + * A bridge used for creating and interacting with packets + */ +public interface PacketBridge { +} diff --git a/nms/nms-common/src/main/java/io/github/zap/arenaapi/nms/common/packet/ProtocolLibPacket.java b/nms/nms-common/src/main/java/io/github/zap/arenaapi/nms/common/packet/ProtocolLibPacket.java new file mode 100644 index 0000000..ba4876a --- /dev/null +++ b/nms/nms-common/src/main/java/io/github/zap/arenaapi/nms/common/packet/ProtocolLibPacket.java @@ -0,0 +1,37 @@ +package io.github.zap.arenaapi.nms.common.packet; + +import com.comphenix.protocol.ProtocolManager; +import com.comphenix.protocol.events.PacketContainer; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; + +import java.lang.reflect.InvocationTargetException; +import java.util.logging.Level; + +/** + * A packet using {@link PacketContainer}s + */ +@SuppressWarnings("ClassCanBeRecord") +public class ProtocolLibPacket implements Packet { + + private final ProtocolManager protocolManager; + + private final PacketContainer handle; + + public ProtocolLibPacket(@NotNull ProtocolManager protocolManager, @NotNull PacketContainer handle) { + this.protocolManager = protocolManager; + this.handle = handle; + } + + @Override + public void sendToPlayer(@NotNull Plugin plugin, @NotNull Player player) { + try { + protocolManager.sendServerPacket(player, handle); + } catch (InvocationTargetException e) { + plugin.getLogger().log(Level.WARNING, "Failed to send a packet to player with UUID " + + player.getUniqueId() + "!", e); + } + } + +} From 041c5c801247519f5f03a022552b476d8c5c77c0 Mon Sep 17 00:00:00 2001 From: thamid-gamer <60953955+thamid-gamer@users.noreply.github.com> Date: Sat, 16 Oct 2021 14:16:59 -0400 Subject: [PATCH 2/6] some new hologram classes (doesn't compile) --- .../packet/PacketBridge_v1_16_R3.java | 80 +++++++++- .../nms/common/packet/PacketBridge.java | 14 ++ .../zap/arenaapi/hologram2/Hologram.java | 140 ++++++++++++++++++ .../zap/arenaapi/hologram2/HologramLine.java | 87 +++++++++++ .../zap/arenaapi/hologram2/PacketLine.java | 42 ++++++ .../zap/arenaapi/hologram2/TextLine.java | 33 +++++ 6 files changed, 395 insertions(+), 1 deletion(-) create mode 100644 src/main/java/io/github/zap/arenaapi/hologram2/Hologram.java create mode 100644 src/main/java/io/github/zap/arenaapi/hologram2/HologramLine.java create mode 100644 src/main/java/io/github/zap/arenaapi/hologram2/PacketLine.java create mode 100644 src/main/java/io/github/zap/arenaapi/hologram2/TextLine.java diff --git a/nms/nms-1_16_R3/src/main/java/io/github/zap/arenaapi/nms/v1_16_R3/packet/PacketBridge_v1_16_R3.java b/nms/nms-1_16_R3/src/main/java/io/github/zap/arenaapi/nms/v1_16_R3/packet/PacketBridge_v1_16_R3.java index a70832b..7d7692e 100644 --- a/nms/nms-1_16_R3/src/main/java/io/github/zap/arenaapi/nms/v1_16_R3/packet/PacketBridge_v1_16_R3.java +++ b/nms/nms-1_16_R3/src/main/java/io/github/zap/arenaapi/nms/v1_16_R3/packet/PacketBridge_v1_16_R3.java @@ -1,16 +1,94 @@ package io.github.zap.arenaapi.nms.v1_16_R3.packet; +import com.comphenix.protocol.PacketType; import com.comphenix.protocol.ProtocolManager; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.AdventureComponentConverter; +import com.comphenix.protocol.wrappers.WrappedDataWatcher; +import io.github.zap.arenaapi.nms.common.packet.Packet; import io.github.zap.arenaapi.nms.common.packet.PacketBridge; +import io.github.zap.arenaapi.nms.common.packet.ProtocolLibPacket; +import net.kyori.adventure.text.Component; import org.jetbrains.annotations.NotNull; +import java.util.Optional; +import java.util.UUID; + @SuppressWarnings("ClassCanBeRecord") public class PacketBridge_v1_16_R3 implements PacketBridge { - private final ProtocolManager protocolManager; + private final static byte INVISIBLE_BYTE_MASK = (byte) 0x20; + + private final static byte MARKER_ARMOR_STAND_MARK = (byte) 0x10; + + protected final ProtocolManager protocolManager; public PacketBridge_v1_16_R3(@NotNull ProtocolManager protocolManager) { this.protocolManager = protocolManager; } + @Override + public @NotNull Packet createSpawnLivingEntityPacket(int entityId, int typeId, @NotNull UUID uuid, double x, + double y, double z) { + PacketContainer packetContainer = new PacketContainer(PacketType.Play.Server.SPAWN_ENTITY_LIVING); + packetContainer.getIntegers() + .write(0, entityId) + .write(1,typeId); + packetContainer.getUUIDs().write(0, uuid); + packetContainer.getDoubles() + .write(0, x) + .write(1, y) + .write(2, z); + + return createProtocolLibPacket(packetContainer); + } + + @Override + public @NotNull Packet createHologramLinePacket(int entityId, @NotNull Component line) { + PacketContainer packetContainer = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA); + packetContainer.getIntegers().write(0, entityId); + + WrappedDataWatcher wrappedDataWatcher = new WrappedDataWatcher(); + + WrappedDataWatcher.Serializer byteSerializer = WrappedDataWatcher.Registry.get(Byte.class); + WrappedDataWatcher.Serializer optChatSerializer = WrappedDataWatcher.Registry + .getChatComponentSerializer(true); + WrappedDataWatcher.Serializer booleanSerializer = WrappedDataWatcher.Registry.get(Boolean.class); + + WrappedDataWatcher.WrappedDataWatcherObject invisible + = new WrappedDataWatcher.WrappedDataWatcherObject(0, byteSerializer); + WrappedDataWatcher.WrappedDataWatcherObject customName + = new WrappedDataWatcher.WrappedDataWatcherObject(2, optChatSerializer); + WrappedDataWatcher.WrappedDataWatcherObject customNameVisible + = new WrappedDataWatcher.WrappedDataWatcherObject(3, booleanSerializer); + WrappedDataWatcher.WrappedDataWatcherObject marker + = new WrappedDataWatcher.WrappedDataWatcherObject(14, byteSerializer); + + wrappedDataWatcher.setObject(invisible, INVISIBLE_BYTE_MASK); + wrappedDataWatcher.setObject(customName, Optional.of(AdventureComponentConverter.fromComponent(line))); + wrappedDataWatcher.setObject(customNameVisible, true); + wrappedDataWatcher.setObject(marker, MARKER_ARMOR_STAND_MARK); + + packetContainer.getWatchableCollectionModifier().write(0, wrappedDataWatcher.getWatchableObjects()); + + return createProtocolLibPacket(packetContainer); + } + + @Override + public @NotNull Packet createDestroyEntityPacket(int id) { + return createDestroyEntitiesPacket(new int[] { id }); + } + + @Override + public @NotNull Packet createDestroyEntitiesPacket(int[] ids) { + PacketContainer packetContainer = new PacketContainer(PacketType.Play.Server.ENTITY_DESTROY); + packetContainer.getIntegerArrays().write(0, ids); + + return createProtocolLibPacket(packetContainer); + } + + protected @NotNull Packet createProtocolLibPacket(@NotNull PacketContainer packetContainer) { + return new ProtocolLibPacket(protocolManager, packetContainer); + } + } diff --git a/nms/nms-common/src/main/java/io/github/zap/arenaapi/nms/common/packet/PacketBridge.java b/nms/nms-common/src/main/java/io/github/zap/arenaapi/nms/common/packet/PacketBridge.java index dae5ea1..0c599dd 100644 --- a/nms/nms-common/src/main/java/io/github/zap/arenaapi/nms/common/packet/PacketBridge.java +++ b/nms/nms-common/src/main/java/io/github/zap/arenaapi/nms/common/packet/PacketBridge.java @@ -1,7 +1,21 @@ package io.github.zap.arenaapi.nms.common.packet; +import net.kyori.adventure.text.Component; +import org.jetbrains.annotations.NotNull; + +import java.util.UUID; + /** * A bridge used for creating and interacting with packets */ public interface PacketBridge { + + @NotNull Packet createSpawnLivingEntityPacket(int entityId, int typeId, @NotNull UUID uuid, double x, double y, + double z); + + @NotNull Packet createHologramLinePacket(int entityId, @NotNull Component line); + + @NotNull Packet createDestroyEntityPacket(int id); + + @NotNull Packet createDestroyEntitiesPacket(int[] ids); } diff --git a/src/main/java/io/github/zap/arenaapi/hologram2/Hologram.java b/src/main/java/io/github/zap/arenaapi/hologram2/Hologram.java new file mode 100644 index 0000000..344ce6a --- /dev/null +++ b/src/main/java/io/github/zap/arenaapi/hologram2/Hologram.java @@ -0,0 +1,140 @@ +package io.github.zap.arenaapi.hologram2; + +import io.github.zap.arenaapi.ArenaApi; +import io.github.zap.arenaapi.nms.common.packet.Packet; +import io.github.zap.arenaapi.nms.common.packet.PacketBridge; +import lombok.Getter; +import net.kyori.adventure.text.Component; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents a hologram which can show lines of text or items + */ +public class Hologram { + + public static final double DEFAULT_LINE_SPACE = 0.25; + + private final Plugin plugin; + + private final PacketBridge packetBridge; + + @Getter + private final List> hologramLines = new ArrayList<>(); + + private final double lineSpace; + + private final Location rootLocation; + + public Hologram(@NotNull Plugin plugin, @NotNull PacketBridge packetBridge, @NotNull Location location, + double lineSpace) { + this.plugin = plugin; + this.packetBridge = packetBridge; + this.rootLocation = location; + this.lineSpace = lineSpace; + } + + public Hologram(@NotNull ArenaApi arenaApi, @NotNull Location location) { + this(arenaApi, arenaApi.getNmsBridge().packetBridge(), location, DEFAULT_LINE_SPACE); + } + + @Deprecated + public Hologram(@NotNull Location location, double lineSpace) { + this(ArenaApi.getInstance(), ArenaApi.getInstance().getNmsBridge().packetBridge(), location, lineSpace); + } + + @Deprecated + public Hologram(@NotNull Location location) { + this(location, DEFAULT_LINE_SPACE); + } + + /** + * Adds a line with a message key and format arguments + * @param message A pair of the message key and format arguments + */ + public void addLine(Component message) { + PacketLine textLine = createTextLine(rootLocation.clone().subtract(0, lineSpace * hologramLines.size(), + 0), message); + hologramLines.add(textLine); + } + + private PacketLine createTextLine(Location location, Component message) { + PacketLine textLine = new PacketLine(location); + textLine.setVisualForEveryone(message); + + return textLine; + } + + /** + * Updates a text line for all players and overrides custom visuals + * @param index The index of the line to update + * @param message The updated line + */ + public void updateLineForEveryone(int index, Component message) { + HologramLine hologramLine = hologramLines.get(index); + if (hologramLine instanceof PacketLine textLine) { + textLine.setVisualForEveryone(message); + } else { + + } + } + + /** + * Updates a text line for all players + * @param index The index of the line to update + * @param message The updated line + */ + public void updateLine(int index, Component message) { + HologramLine hologramLine = hologramLines.get(index); + if (hologramLine instanceof PacketLine textLine) { + textLine.setVisual(message); + } else { + + } + } + + /** + * Updates a text line for a single player + * @param player The player to update the line for + * @param index The index of the line to update + * @param message The updated line + */ + public void updateLineForPlayer(Player player, int index, Component message) { + + } + + /** + * Creates and renders the hologram for a player + * @param player The player to render the hologram to + */ + public void renderToPlayer(Player player) { + for (HologramLine hologramLine : hologramLines) { + hologramLine.createVisualForPlayer(plugin, player); + hologramLine.updateVisualForPlayer(player); + } + } + + /** + * Destroys the hologram + */ + public void destroy() { + int idCount = hologramLines.size(); + + int[] ids = new int[idCount]; + for (int i = 0; i < idCount; i++) { + ids[i] = hologramLines.get(0).getEntityId(); + hologramLines.remove(0); + } + + Packet packet = packetBridge.createDestroyEntitiesPacket(ids); + for (Player player : rootLocation.getWorld().getPlayers()) { + packet.sendToPlayer(plugin, player); + } + } + +} diff --git a/src/main/java/io/github/zap/arenaapi/hologram2/HologramLine.java b/src/main/java/io/github/zap/arenaapi/hologram2/HologramLine.java new file mode 100644 index 0000000..b0d06c6 --- /dev/null +++ b/src/main/java/io/github/zap/arenaapi/hologram2/HologramLine.java @@ -0,0 +1,87 @@ +package io.github.zap.arenaapi.hologram2; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.UUID; + +/** + * A line of a hologram + */ +public abstract class HologramLine { + + private final Map visualMap = new HashMap<>(); + + private V defaultVisual; + + public HologramLine(@NotNull V defaultVisual) { + this.defaultVisual = defaultVisual; + } + + /** + * Sets the visual of the hologram for all players, overriding player specific visuals + * @param plugin The {@link Plugin} that cleared the visuals + */ + public void clearVisuals(@NotNull Plugin plugin) { + Iterator viewers = visualMap.keySet().iterator(); + while (viewers.hasNext()) { + UUID viewer = viewers.next(); + Player player = Bukkit.getPlayer(viewer); + + if (player != null) { + destroyVisualForPlayer(plugin, player); + } + + viewers.remove(); + } + } + + /** + * Sets the default visual of the hologram for all players + * @param visual The new visual + */ + public void setVisual(@NotNull V visual) { + defaultVisual = visual; + } + + /** + * Sets the visual for a single player + * @param plugin The {@link Plugin} to set the visual from + * @param player The player to set the visual for + * @param visual The new visual + */ + public void setVisualForPlayer(@NotNull Plugin plugin, @NotNull Player player, @NotNull V visual) { + visualMap.put(player.getUniqueId(), visual); + updateVisualForPlayer(plugin, player); + } + + /** + * Gets the visual for a player + * @param player The player to get the visual for + * @return The visual the player sees + */ + public @NotNull V getVisualForPlayer(@NotNull Player player) { + return visualMap.getOrDefault(player.getUniqueId(), defaultVisual); + } + /** + * Spawns the visual for a player + * @param plugin The {@link Plugin} to send the visual from + * @param player The player to spawn the visual for + */ + public abstract void createVisualForPlayer(@NotNull Plugin plugin, @NotNull Player player); + + /** + * Updates the visual for a player + * @param plugin The {@link Plugin} to update the visual from + * @param player The player to update for + */ + public abstract void updateVisualForPlayer(@NotNull Plugin plugin, @NotNull Player player); + + public abstract void destroyVisualForPlayer(@NotNull Plugin plugin, @NotNull Player player); + +} diff --git a/src/main/java/io/github/zap/arenaapi/hologram2/PacketLine.java b/src/main/java/io/github/zap/arenaapi/hologram2/PacketLine.java new file mode 100644 index 0000000..d6460a2 --- /dev/null +++ b/src/main/java/io/github/zap/arenaapi/hologram2/PacketLine.java @@ -0,0 +1,42 @@ +package io.github.zap.arenaapi.hologram2; + +import io.github.zap.arenaapi.nms.common.packet.Packet; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; + +import java.util.function.Function; + +public class PacketLine extends HologramLine { + + private final Packet spawnPacket; + + private final Function<@NotNull V, @NotNull Packet> updatePacket; + + private final Packet destructionPacket; + + public PacketLine(@NotNull Packet spawnPacket, @NotNull Function<@NotNull V, @NotNull Packet> updatePacket, + @NotNull Packet destructionPacket, @NotNull V defaultVisual) { + super(defaultVisual); + + this.spawnPacket = spawnPacket; + this.updatePacket = updatePacket; + this.destructionPacket = destructionPacket; + } + + @Override + public void createVisualForPlayer(@NotNull Plugin plugin, @NotNull Player player) { + spawnPacket.sendToPlayer(plugin, player); + } + + @Override + public void updateVisualForPlayer(@NotNull Plugin plugin, @NotNull Player player) { + updatePacket.apply(getVisualForPlayer(player)).sendToPlayer(plugin, player); + } + + @Override + public void destroyVisualForPlayer(@NotNull Plugin plugin, @NotNull Player player) { + destructionPacket.sendToPlayer(plugin, player); + } + +} diff --git a/src/main/java/io/github/zap/arenaapi/hologram2/TextLine.java b/src/main/java/io/github/zap/arenaapi/hologram2/TextLine.java new file mode 100644 index 0000000..ad049ad --- /dev/null +++ b/src/main/java/io/github/zap/arenaapi/hologram2/TextLine.java @@ -0,0 +1,33 @@ +package io.github.zap.arenaapi.hologram2; + +import io.github.zap.arenaapi.nms.common.entity.EntityBridge; +import io.github.zap.arenaapi.nms.common.packet.Packet; +import io.github.zap.arenaapi.nms.common.packet.PacketBridge; +import net.kyori.adventure.text.Component; +import org.bukkit.Location; +import org.bukkit.entity.EntityType; +import org.jetbrains.annotations.NotNull; + +import java.util.function.Function; + +public class TextLine extends PacketLine { + + private TextLine(@NotNull Packet spawnPacket, @NotNull Function<@NotNull Component, @NotNull Packet> updatePacket, + @NotNull Packet destroyPacket) { + super(spawnPacket, updatePacket, destroyPacket, Component.empty()); + } + + public TextLine textLine(@NotNull EntityBridge entityBridge, @NotNull PacketBridge packetBridge, + @NotNull Location location) { + int entityId = entityBridge.nextEntityID(); + Packet spawnPacket = packetBridge.createSpawnLivingEntityPacket(entityId, + entityBridge.getEntityTypeID(EntityType.ARMOR_STAND), entityBridge.randomUUID(), location.getX(), + location.getY(), location.getZ()); + Function<@NotNull Component, @NotNull Packet> updatePacket + = component -> packetBridge.createHologramLinePacket(entityId, component); + Packet destroyPacket = packetBridge.createDestroyEntityPacket(entityId); + + return new TextLine(spawnPacket, updatePacket, destroyPacket); + } + +} From 03816fd34b77ecfbbeb84c68f1a407c14e7f756e Mon Sep 17 00:00:00 2001 From: thamid-gamer <60953955+thamid-gamer@users.noreply.github.com> Date: Sat, 27 Nov 2021 23:04:58 -0500 Subject: [PATCH 3/6] compile error, still kind of iffy on polymorphism with different types of hologram lines --- .../zap/arenaapi/hologram2/Hologram.java | 63 ++++++++++--------- .../zap/arenaapi/hologram2/TextLine.java | 4 +- 2 files changed, 34 insertions(+), 33 deletions(-) diff --git a/src/main/java/io/github/zap/arenaapi/hologram2/Hologram.java b/src/main/java/io/github/zap/arenaapi/hologram2/Hologram.java index 344ce6a..5a7c685 100644 --- a/src/main/java/io/github/zap/arenaapi/hologram2/Hologram.java +++ b/src/main/java/io/github/zap/arenaapi/hologram2/Hologram.java @@ -1,9 +1,8 @@ package io.github.zap.arenaapi.hologram2; import io.github.zap.arenaapi.ArenaApi; -import io.github.zap.arenaapi.nms.common.packet.Packet; +import io.github.zap.arenaapi.nms.common.entity.EntityBridge; import io.github.zap.arenaapi.nms.common.packet.PacketBridge; -import lombok.Getter; import net.kyori.adventure.text.Component; import org.bukkit.Location; import org.bukkit.entity.Player; @@ -22,30 +21,34 @@ public class Hologram { private final Plugin plugin; + private final EntityBridge entityBridge; + private final PacketBridge packetBridge; - @Getter private final List> hologramLines = new ArrayList<>(); private final double lineSpace; private final Location rootLocation; - public Hologram(@NotNull Plugin plugin, @NotNull PacketBridge packetBridge, @NotNull Location location, - double lineSpace) { + public Hologram(@NotNull Plugin plugin, @NotNull EntityBridge entityBridge, @NotNull PacketBridge packetBridge, + @NotNull Location location, double lineSpace) { this.plugin = plugin; + this.entityBridge = entityBridge; this.packetBridge = packetBridge; this.rootLocation = location; this.lineSpace = lineSpace; } public Hologram(@NotNull ArenaApi arenaApi, @NotNull Location location) { - this(arenaApi, arenaApi.getNmsBridge().packetBridge(), location, DEFAULT_LINE_SPACE); + this(arenaApi, arenaApi.getNmsBridge().entityBridge(), arenaApi.getNmsBridge().packetBridge(), location, + DEFAULT_LINE_SPACE); } @Deprecated public Hologram(@NotNull Location location, double lineSpace) { - this(ArenaApi.getInstance(), ArenaApi.getInstance().getNmsBridge().packetBridge(), location, lineSpace); + this(ArenaApi.getInstance(), ArenaApi.getInstance().getNmsBridge().entityBridge(), + ArenaApi.getInstance().getNmsBridge().packetBridge(), location, lineSpace); } @Deprecated @@ -57,17 +60,15 @@ public Hologram(@NotNull Location location) { * Adds a line with a message key and format arguments * @param message A pair of the message key and format arguments */ - public void addLine(Component message) { - PacketLine textLine = createTextLine(rootLocation.clone().subtract(0, lineSpace * hologramLines.size(), - 0), message); + public void addLine(@NotNull Component message) { + PacketLine textLine = createTextLine(rootLocation.clone().subtract(0, + lineSpace * hologramLines.size(), 0), message); hologramLines.add(textLine); } - private PacketLine createTextLine(Location location, Component message) { - PacketLine textLine = new PacketLine(location); - textLine.setVisualForEveryone(message); + private @NotNull PacketLine createTextLine(@NotNull Location location, @NotNull Component message) { - return textLine; + return TextLine.textLine(entityBridge, packetBridge, location); } /** @@ -75,10 +76,12 @@ private PacketLine createTextLine(Location location, Component message) { * @param index The index of the line to update * @param message The updated line */ - public void updateLineForEveryone(int index, Component message) { + public void updateLineForEveryone(int index, @NotNull Component message) { HologramLine hologramLine = hologramLines.get(index); - if (hologramLine instanceof PacketLine textLine) { - textLine.setVisualForEveryone(message); + if (hologramLine instanceof TextLine textLine) { + for (Player player : rootLocation.getWorld().getPlayers()) { + textLine.setVisualForPlayer(plugin, player, message); + } } else { } @@ -89,9 +92,9 @@ public void updateLineForEveryone(int index, Component message) { * @param index The index of the line to update * @param message The updated line */ - public void updateLine(int index, Component message) { + public void updateLine(int index, @NotNull Component message) { HologramLine hologramLine = hologramLines.get(index); - if (hologramLine instanceof PacketLine textLine) { + if (hologramLine instanceof TextLine textLine) { textLine.setVisual(message); } else { @@ -112,10 +115,10 @@ public void updateLineForPlayer(Player player, int index, Component message) { * Creates and renders the hologram for a player * @param player The player to render the hologram to */ - public void renderToPlayer(Player player) { + public void renderToPlayer(@NotNull Player player) { for (HologramLine hologramLine : hologramLines) { hologramLine.createVisualForPlayer(plugin, player); - hologramLine.updateVisualForPlayer(player); + hologramLine.updateVisualForPlayer(plugin, player); } } @@ -123,18 +126,16 @@ public void renderToPlayer(Player player) { * Destroys the hologram */ public void destroy() { - int idCount = hologramLines.size(); - - int[] ids = new int[idCount]; - for (int i = 0; i < idCount; i++) { - ids[i] = hologramLines.get(0).getEntityId(); - hologramLines.remove(0); + while (!hologramLines.isEmpty()) { + HologramLine line = hologramLines.remove(0); + for (Player player : rootLocation.getWorld().getPlayers()) { + line.destroyVisualForPlayer(plugin, player); + } } + } - Packet packet = packetBridge.createDestroyEntitiesPacket(ids); - for (Player player : rootLocation.getWorld().getPlayers()) { - packet.sendToPlayer(plugin, player); - } + public @NotNull List> getHologramLines() { + return hologramLines; } } diff --git a/src/main/java/io/github/zap/arenaapi/hologram2/TextLine.java b/src/main/java/io/github/zap/arenaapi/hologram2/TextLine.java index ad049ad..b8c15a7 100644 --- a/src/main/java/io/github/zap/arenaapi/hologram2/TextLine.java +++ b/src/main/java/io/github/zap/arenaapi/hologram2/TextLine.java @@ -17,8 +17,8 @@ private TextLine(@NotNull Packet spawnPacket, @NotNull Function<@NotNull Compone super(spawnPacket, updatePacket, destroyPacket, Component.empty()); } - public TextLine textLine(@NotNull EntityBridge entityBridge, @NotNull PacketBridge packetBridge, - @NotNull Location location) { + public static @NotNull TextLine textLine(@NotNull EntityBridge entityBridge, @NotNull PacketBridge packetBridge, + @NotNull Location location) { int entityId = entityBridge.nextEntityID(); Packet spawnPacket = packetBridge.createSpawnLivingEntityPacket(entityId, entityBridge.getEntityTypeID(EntityType.ARMOR_STAND), entityBridge.randomUUID(), location.getX(), From bc1fc502b9b7e1df198a944a5fa643f0690b6fb5 Mon Sep 17 00:00:00 2001 From: thamid-gamer <60953955+thamid-gamer@users.noreply.github.com> Date: Sat, 27 Nov 2021 23:09:53 -0500 Subject: [PATCH 4/6] forgot to implement a method --- .../java/io/github/zap/arenaapi/hologram2/Hologram.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/io/github/zap/arenaapi/hologram2/Hologram.java b/src/main/java/io/github/zap/arenaapi/hologram2/Hologram.java index 5a7c685..27bef84 100644 --- a/src/main/java/io/github/zap/arenaapi/hologram2/Hologram.java +++ b/src/main/java/io/github/zap/arenaapi/hologram2/Hologram.java @@ -107,8 +107,13 @@ public void updateLine(int index, @NotNull Component message) { * @param index The index of the line to update * @param message The updated line */ - public void updateLineForPlayer(Player player, int index, Component message) { + public void updateLineForPlayer(@NotNull Player player, int index, @NotNull Component message) { + HologramLine hologramLine = hologramLines.get(index); + if (hologramLine instanceof TextLine textLine) { + textLine.setVisualForPlayer(plugin, player, message); + } else { + } } /** From 145de1f522e190bac5c825dd377c4788b5a6a72f Mon Sep 17 00:00:00 2001 From: thamid-gamer <60953955+thamid-gamer@users.noreply.github.com> Date: Sat, 27 Nov 2021 23:12:35 -0500 Subject: [PATCH 5/6] rename PacketBridge v1.16.3 --- .../arenaapi/nms/v1_16_R3/ArenaNMSBridge_v1_16_R3.java | 4 ++-- ...1_16_R3.java => ProtocolLibPacketBridge_v1_16_R3.java} | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) rename nms/nms-1_16_R3/src/main/java/io/github/zap/arenaapi/nms/v1_16_R3/packet/{PacketBridge_v1_16_R3.java => ProtocolLibPacketBridge_v1_16_R3.java} (94%) diff --git a/nms/nms-1_16_R3/src/main/java/io/github/zap/arenaapi/nms/v1_16_R3/ArenaNMSBridge_v1_16_R3.java b/nms/nms-1_16_R3/src/main/java/io/github/zap/arenaapi/nms/v1_16_R3/ArenaNMSBridge_v1_16_R3.java index 10811a2..e619aaa 100644 --- a/nms/nms-1_16_R3/src/main/java/io/github/zap/arenaapi/nms/v1_16_R3/ArenaNMSBridge_v1_16_R3.java +++ b/nms/nms-1_16_R3/src/main/java/io/github/zap/arenaapi/nms/v1_16_R3/ArenaNMSBridge_v1_16_R3.java @@ -10,7 +10,7 @@ import io.github.zap.arenaapi.nms.common.world.WorldBridge; import io.github.zap.arenaapi.nms.v1_16_R3.entity.EntityBridge_v1_16_R3; import io.github.zap.arenaapi.nms.v1_16_R3.itemstack.ItemStackBridge_v1_16_R3; -import io.github.zap.arenaapi.nms.v1_16_R3.packet.PacketBridge_v1_16_R3; +import io.github.zap.arenaapi.nms.v1_16_R3.packet.ProtocolLibPacketBridge_v1_16_R3; import io.github.zap.arenaapi.nms.v1_16_R3.player.PlayerBridge_v1_16_R3; import io.github.zap.arenaapi.nms.v1_16_R3.world.WorldBridge_v1_16_R3; import org.apache.commons.lang3.NotImplementedException; @@ -32,7 +32,7 @@ private ArenaNMSBridge_v1_16_R3() { } ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager(); - this.packetBridge = new PacketBridge_v1_16_R3(protocolManager); + this.packetBridge = new ProtocolLibPacketBridge_v1_16_R3(protocolManager); } @Override diff --git a/nms/nms-1_16_R3/src/main/java/io/github/zap/arenaapi/nms/v1_16_R3/packet/PacketBridge_v1_16_R3.java b/nms/nms-1_16_R3/src/main/java/io/github/zap/arenaapi/nms/v1_16_R3/packet/ProtocolLibPacketBridge_v1_16_R3.java similarity index 94% rename from nms/nms-1_16_R3/src/main/java/io/github/zap/arenaapi/nms/v1_16_R3/packet/PacketBridge_v1_16_R3.java rename to nms/nms-1_16_R3/src/main/java/io/github/zap/arenaapi/nms/v1_16_R3/packet/ProtocolLibPacketBridge_v1_16_R3.java index 7d7692e..0ba0052 100644 --- a/nms/nms-1_16_R3/src/main/java/io/github/zap/arenaapi/nms/v1_16_R3/packet/PacketBridge_v1_16_R3.java +++ b/nms/nms-1_16_R3/src/main/java/io/github/zap/arenaapi/nms/v1_16_R3/packet/ProtocolLibPacketBridge_v1_16_R3.java @@ -15,15 +15,15 @@ import java.util.UUID; @SuppressWarnings("ClassCanBeRecord") -public class PacketBridge_v1_16_R3 implements PacketBridge { +public class ProtocolLibPacketBridge_v1_16_R3 implements PacketBridge { private final static byte INVISIBLE_BYTE_MASK = (byte) 0x20; - private final static byte MARKER_ARMOR_STAND_MARK = (byte) 0x10; + private final static byte MARKER_ARMOR_STAND_MASK = (byte) 0x10; protected final ProtocolManager protocolManager; - public PacketBridge_v1_16_R3(@NotNull ProtocolManager protocolManager) { + public ProtocolLibPacketBridge_v1_16_R3(@NotNull ProtocolManager protocolManager) { this.protocolManager = protocolManager; } @@ -67,7 +67,7 @@ public PacketBridge_v1_16_R3(@NotNull ProtocolManager protocolManager) { wrappedDataWatcher.setObject(invisible, INVISIBLE_BYTE_MASK); wrappedDataWatcher.setObject(customName, Optional.of(AdventureComponentConverter.fromComponent(line))); wrappedDataWatcher.setObject(customNameVisible, true); - wrappedDataWatcher.setObject(marker, MARKER_ARMOR_STAND_MARK); + wrappedDataWatcher.setObject(marker, MARKER_ARMOR_STAND_MASK); packetContainer.getWatchableCollectionModifier().write(0, wrappedDataWatcher.getWatchableObjects()); From 2f667a702877ac05ea91cbd8b5f9013cc58762a0 Mon Sep 17 00:00:00 2001 From: thamid-gamer <60953955+thamid-gamer@users.noreply.github.com> Date: Sat, 27 Nov 2021 23:18:50 -0500 Subject: [PATCH 6/6] grab the latest ver of zap-party --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 4a2a022..16ff26d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -38,7 +38,7 @@ dependencies { relocate("org.apache.commons:commons-lang3:3.12.0") relocate("it.unimi.dsi:fastutil:8.5.6") - bukkitPlugin("io.github.zap:zap-party:1.0.0-SNAPSHOT-1630956414", qs()) + bukkitPlugin("io.github.zap:zap-party:1.0.0-SNAPSHOT-1638065973", qs()) bukkitPlugin("com.comphenix.protocol:ProtocolLib:4.7.0") compileOnly("org.projectlombok:lombok:1.18.20")