From 00e5f380910b7ebea064bfe24d2dbd3f24c403fd Mon Sep 17 00:00:00 2001 From: Connor Linfoot Date: Tue, 23 Jul 2024 02:20:51 +0100 Subject: [PATCH 1/7] Annotate internal methods as so, remove custom Experimental annotation --- .../net/hypixel/modapi/HypixelModAPI.java | 61 ++++++++++--------- .../modapi/annotation/Experimental.java | 7 --- .../hypixel/modapi/error/ModAPIException.java | 3 + .../hypixel/modapi/packet/PacketRegistry.java | 2 + 4 files changed, 38 insertions(+), 35 deletions(-) delete mode 100644 src/main/java/net/hypixel/modapi/annotation/Experimental.java diff --git a/src/main/java/net/hypixel/modapi/HypixelModAPI.java b/src/main/java/net/hypixel/modapi/HypixelModAPI.java index 3df9218..f8ab034 100644 --- a/src/main/java/net/hypixel/modapi/HypixelModAPI.java +++ b/src/main/java/net/hypixel/modapi/HypixelModAPI.java @@ -14,6 +14,7 @@ import net.hypixel.modapi.packet.impl.serverbound.ServerboundPlayerInfoPacket; import net.hypixel.modapi.packet.impl.serverbound.ServerboundRegisterPacket; import net.hypixel.modapi.serializer.PacketSerializer; +import org.jetbrains.annotations.ApiStatus; import java.util.*; import java.util.concurrent.ConcurrentHashMap; @@ -74,38 +75,12 @@ private void registerDefaultHandler() { registerHandler(ClientboundHelloPacket.class, p -> sendRegisterPacket(true)); } + @ApiStatus.Internal public PacketRegistry getRegistry() { return registry; } - public void registerHandler(Class packetClass, ClientboundPacketHandler handler) { - if (packetClass == null || handler == null) return; - handlers.computeIfAbsent(packetClass, cls -> new CopyOnWriteArrayList<>()).add(handler); - } - - public void subscribeToEventPacket(Class packet) { - if (subscribedEvents.add(getRegistry().getIdentifier(packet))) { - sendRegisterPacket(false); - } - } - - private void sendRegisterPacket(boolean alwaysSendIfNotEmpty) { - if (packetSender == null) { - // Allow registering events before the mod has fully initialized - return; - } - - if (lastSubscribedEvents.equals(subscribedEvents) && !(alwaysSendIfNotEmpty && !subscribedEvents.isEmpty())) { - return; - } - - Set lastSubscribedEvents = new HashSet<>(subscribedEvents); - Map versionsMap = getRegistry().getEventVersions(lastSubscribedEvents); - if (sendPacket(new ServerboundRegisterPacket(versionsMap))) { - this.lastSubscribedEvents = lastSubscribedEvents; - } - } - + @ApiStatus.Internal public void handle(String identifier, PacketSerializer serializer) { if (handlers.isEmpty()) { return; @@ -130,6 +105,7 @@ public void handle(String identifier, PacketSerializer serializer) { handle(packet); } + @ApiStatus.Internal @SuppressWarnings("unchecked") public void handle(ClientboundHypixelPacket packet) { Collection> typedHandlers = handlers.get(packet.getClass()); @@ -141,6 +117,7 @@ public void handle(ClientboundHypixelPacket packet) { } } + @ApiStatus.Internal public void setPacketSender(Predicate packetSender) { if (this.packetSender != null) { throw new IllegalArgumentException("Packet sender already set"); @@ -148,6 +125,34 @@ public void setPacketSender(Predicate packetSender) { this.packetSender = packetSender; } + public void registerHandler(Class packetClass, ClientboundPacketHandler handler) { + if (packetClass == null || handler == null) return; + handlers.computeIfAbsent(packetClass, cls -> new CopyOnWriteArrayList<>()).add(handler); + } + + public void subscribeToEventPacket(Class packet) { + if (subscribedEvents.add(getRegistry().getIdentifier(packet))) { + sendRegisterPacket(false); + } + } + + private void sendRegisterPacket(boolean alwaysSendIfNotEmpty) { + if (packetSender == null) { + // Allow registering events before the mod has fully initialized + return; + } + + if (lastSubscribedEvents.equals(subscribedEvents) && !(alwaysSendIfNotEmpty && !subscribedEvents.isEmpty())) { + return; + } + + Set lastSubscribedEvents = new HashSet<>(subscribedEvents); + Map versionsMap = getRegistry().getEventVersions(lastSubscribedEvents); + if (sendPacket(new ServerboundRegisterPacket(versionsMap))) { + this.lastSubscribedEvents = lastSubscribedEvents; + } + } + /** * @return whether the packet was sent successfully */ diff --git a/src/main/java/net/hypixel/modapi/annotation/Experimental.java b/src/main/java/net/hypixel/modapi/annotation/Experimental.java deleted file mode 100644 index edeaa78..0000000 --- a/src/main/java/net/hypixel/modapi/annotation/Experimental.java +++ /dev/null @@ -1,7 +0,0 @@ -package net.hypixel.modapi.annotation; - -/** - * Marks a packet as experimental and subject to change or removal. - */ -public @interface Experimental { -} diff --git a/src/main/java/net/hypixel/modapi/error/ModAPIException.java b/src/main/java/net/hypixel/modapi/error/ModAPIException.java index 934474d..9b505db 100644 --- a/src/main/java/net/hypixel/modapi/error/ModAPIException.java +++ b/src/main/java/net/hypixel/modapi/error/ModAPIException.java @@ -1,9 +1,12 @@ package net.hypixel.modapi.error; +import org.jetbrains.annotations.ApiStatus; + public class ModAPIException extends RuntimeException { private final String identifier; private final ErrorReason reason; + @ApiStatus.Internal public ModAPIException(String identifier, ErrorReason reason) { super(String.format("Received error response '%s' from packet '%s'", reason, identifier)); this.identifier = identifier; diff --git a/src/main/java/net/hypixel/modapi/packet/PacketRegistry.java b/src/main/java/net/hypixel/modapi/packet/PacketRegistry.java index df6fc63..a921ba6 100644 --- a/src/main/java/net/hypixel/modapi/packet/PacketRegistry.java +++ b/src/main/java/net/hypixel/modapi/packet/PacketRegistry.java @@ -1,6 +1,7 @@ package net.hypixel.modapi.packet; import net.hypixel.modapi.serializer.PacketSerializer; +import org.jetbrains.annotations.ApiStatus; import java.util.Collection; import java.util.Collections; @@ -10,6 +11,7 @@ import java.util.function.Function; import java.util.stream.Collectors; +@ApiStatus.Internal public class PacketRegistry { private final Map registrations = new ConcurrentHashMap<>(); From ebf54aa15625be48010fac77dfb42540c9b92d58 Mon Sep 17 00:00:00 2001 From: Connor Linfoot Date: Tue, 23 Jul 2024 02:22:04 +0100 Subject: [PATCH 2/7] Mark PacketSerializer as internal --- .../java/net/hypixel/modapi/serializer/PacketSerializer.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/net/hypixel/modapi/serializer/PacketSerializer.java b/src/main/java/net/hypixel/modapi/serializer/PacketSerializer.java index c2a5fa9..a9bec7a 100644 --- a/src/main/java/net/hypixel/modapi/serializer/PacketSerializer.java +++ b/src/main/java/net/hypixel/modapi/serializer/PacketSerializer.java @@ -4,6 +4,7 @@ import io.netty.handler.codec.DecoderException; import io.netty.handler.codec.EncoderException; import io.netty.util.CharsetUtil; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; import java.util.Optional; @@ -11,6 +12,7 @@ import java.util.function.BiConsumer; import java.util.function.Function; +@ApiStatus.Internal public class PacketSerializer { private static final int MAX_BYTES_PER_CHAR_UTF8 = (int) CharsetUtil.getEncoder(CharsetUtil.UTF_8).maxBytesPerChar(); private static final int MAX_STRING_LENGTH = 32767; From 025c9b21873124cad0a27411e3cff636f981e6b9 Mon Sep 17 00:00:00 2001 From: Connor Linfoot Date: Tue, 23 Jul 2024 02:24:11 +0100 Subject: [PATCH 3/7] Mark packet methods and constructors as internal accordingly --- src/main/java/net/hypixel/modapi/packet/HypixelPacket.java | 3 +++ .../java/net/hypixel/modapi/packet/impl/VersionedPacket.java | 3 +++ .../packet/impl/clientbound/ClientboundHelloPacket.java | 3 +++ .../packet/impl/clientbound/ClientboundPartyInfoPacket.java | 5 +++++ .../packet/impl/clientbound/ClientboundPingPacket.java | 3 +++ .../packet/impl/clientbound/ClientboundPlayerInfoPacket.java | 3 +++ .../packet/impl/clientbound/ClientboundVersionedPacket.java | 4 ++++ .../impl/clientbound/event/ClientboundLocationPacket.java | 3 +++ .../packet/impl/serverbound/ServerboundPartyInfoPacket.java | 2 ++ .../packet/impl/serverbound/ServerboundPingPacket.java | 2 ++ .../packet/impl/serverbound/ServerboundPlayerInfoPacket.java | 2 ++ .../packet/impl/serverbound/ServerboundRegisterPacket.java | 3 +++ .../packet/impl/serverbound/ServerboundVersionedPacket.java | 3 +++ 13 files changed, 39 insertions(+) diff --git a/src/main/java/net/hypixel/modapi/packet/HypixelPacket.java b/src/main/java/net/hypixel/modapi/packet/HypixelPacket.java index 610d9cd..4f9a67d 100644 --- a/src/main/java/net/hypixel/modapi/packet/HypixelPacket.java +++ b/src/main/java/net/hypixel/modapi/packet/HypixelPacket.java @@ -2,11 +2,14 @@ import net.hypixel.modapi.HypixelModAPI; import net.hypixel.modapi.serializer.PacketSerializer; +import org.jetbrains.annotations.ApiStatus; public interface HypixelPacket { + @ApiStatus.Internal void write(PacketSerializer serializer); + @ApiStatus.Internal default String getIdentifier() { return HypixelModAPI.getInstance().getRegistry().getIdentifier(getClass()); } diff --git a/src/main/java/net/hypixel/modapi/packet/impl/VersionedPacket.java b/src/main/java/net/hypixel/modapi/packet/impl/VersionedPacket.java index 3fd96c5..5e4d934 100644 --- a/src/main/java/net/hypixel/modapi/packet/impl/VersionedPacket.java +++ b/src/main/java/net/hypixel/modapi/packet/impl/VersionedPacket.java @@ -2,6 +2,7 @@ import net.hypixel.modapi.packet.HypixelPacket; import net.hypixel.modapi.serializer.PacketSerializer; +import org.jetbrains.annotations.ApiStatus; /** * Represents a packet that is backed by a version. Versioned packets will only be handled if the incoming packet matches the version of the packet known. @@ -9,10 +10,12 @@ public abstract class VersionedPacket implements HypixelPacket { protected int version; + @ApiStatus.Internal public VersionedPacket(int version) { this.version = version; } + @ApiStatus.Internal public VersionedPacket(PacketSerializer serializer) { read(serializer); } diff --git a/src/main/java/net/hypixel/modapi/packet/impl/clientbound/ClientboundHelloPacket.java b/src/main/java/net/hypixel/modapi/packet/impl/clientbound/ClientboundHelloPacket.java index 952431c..350a554 100644 --- a/src/main/java/net/hypixel/modapi/packet/impl/clientbound/ClientboundHelloPacket.java +++ b/src/main/java/net/hypixel/modapi/packet/impl/clientbound/ClientboundHelloPacket.java @@ -3,6 +3,7 @@ import net.hypixel.data.region.Environment; import net.hypixel.modapi.packet.ClientboundHypixelPacket; import net.hypixel.modapi.serializer.PacketSerializer; +import org.jetbrains.annotations.ApiStatus; /** * This packet is automatically sent on every join to Hypixel to indicate that the client has connected to a Hypixel server. @@ -11,10 +12,12 @@ public class ClientboundHelloPacket implements ClientboundHypixelPacket { private final Environment environment; + @ApiStatus.Internal public ClientboundHelloPacket(Environment environment) { this.environment = environment; } + @ApiStatus.Internal public ClientboundHelloPacket(PacketSerializer serializer) { this.environment = Environment.getById(serializer.readVarInt()).orElseThrow(() -> new IllegalArgumentException("Invalid environment ID")); diff --git a/src/main/java/net/hypixel/modapi/packet/impl/clientbound/ClientboundPartyInfoPacket.java b/src/main/java/net/hypixel/modapi/packet/impl/clientbound/ClientboundPartyInfoPacket.java index 6dfcfd4..8989d55 100644 --- a/src/main/java/net/hypixel/modapi/packet/impl/clientbound/ClientboundPartyInfoPacket.java +++ b/src/main/java/net/hypixel/modapi/packet/impl/clientbound/ClientboundPartyInfoPacket.java @@ -1,6 +1,7 @@ package net.hypixel.modapi.packet.impl.clientbound; import net.hypixel.modapi.serializer.PacketSerializer; +import org.jetbrains.annotations.ApiStatus; import java.util.*; @@ -10,6 +11,7 @@ public class ClientboundPartyInfoPacket extends ClientboundVersionedPacket { private boolean inParty; private Map memberMap; + @ApiStatus.Internal public ClientboundPartyInfoPacket(int version, boolean inParty, Map memberMap) { super(version); if (version > CURRENT_VERSION) { @@ -20,6 +22,7 @@ public ClientboundPartyInfoPacket(int version, boolean inParty, Map subscribedEvents; + @ApiStatus.Internal public ServerboundRegisterPacket(Map subscribedEvents) { super(CURRENT_VERSION); this.subscribedEvents = subscribedEvents; @@ -27,6 +29,7 @@ public ServerboundRegisterPacket(Map subscribedEvents) { } } + @ApiStatus.Internal public ServerboundRegisterPacket(PacketSerializer serializer) { super(serializer); } diff --git a/src/main/java/net/hypixel/modapi/packet/impl/serverbound/ServerboundVersionedPacket.java b/src/main/java/net/hypixel/modapi/packet/impl/serverbound/ServerboundVersionedPacket.java index 25002bc..3c155f0 100644 --- a/src/main/java/net/hypixel/modapi/packet/impl/serverbound/ServerboundVersionedPacket.java +++ b/src/main/java/net/hypixel/modapi/packet/impl/serverbound/ServerboundVersionedPacket.java @@ -3,13 +3,16 @@ import net.hypixel.modapi.packet.HypixelPacket; import net.hypixel.modapi.packet.impl.VersionedPacket; import net.hypixel.modapi.serializer.PacketSerializer; +import org.jetbrains.annotations.ApiStatus; public abstract class ServerboundVersionedPacket extends VersionedPacket implements HypixelPacket { + @ApiStatus.Internal public ServerboundVersionedPacket(int version) { super(version); } + @ApiStatus.Internal public ServerboundVersionedPacket(PacketSerializer serializer) { super(serializer); } From 7ee1c9d8f14b0c89b25051d86708f0b875432905 Mon Sep 17 00:00:00 2001 From: Connor Linfoot Date: Tue, 23 Jul 2024 02:28:30 +0100 Subject: [PATCH 4/7] Move private method up --- .../net/hypixel/modapi/HypixelModAPI.java | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/main/java/net/hypixel/modapi/HypixelModAPI.java b/src/main/java/net/hypixel/modapi/HypixelModAPI.java index f8ab034..c11b4ff 100644 --- a/src/main/java/net/hypixel/modapi/HypixelModAPI.java +++ b/src/main/java/net/hypixel/modapi/HypixelModAPI.java @@ -75,6 +75,23 @@ private void registerDefaultHandler() { registerHandler(ClientboundHelloPacket.class, p -> sendRegisterPacket(true)); } + private void sendRegisterPacket(boolean alwaysSendIfNotEmpty) { + if (packetSender == null) { + // Allow registering events before the mod has fully initialized + return; + } + + if (lastSubscribedEvents.equals(subscribedEvents) && !(alwaysSendIfNotEmpty && !subscribedEvents.isEmpty())) { + return; + } + + Set lastSubscribedEvents = new HashSet<>(subscribedEvents); + Map versionsMap = getRegistry().getEventVersions(lastSubscribedEvents); + if (sendPacket(new ServerboundRegisterPacket(versionsMap))) { + this.lastSubscribedEvents = lastSubscribedEvents; + } + } + @ApiStatus.Internal public PacketRegistry getRegistry() { return registry; @@ -136,23 +153,6 @@ public void subscribeToEventPacket(Class packet) { } } - private void sendRegisterPacket(boolean alwaysSendIfNotEmpty) { - if (packetSender == null) { - // Allow registering events before the mod has fully initialized - return; - } - - if (lastSubscribedEvents.equals(subscribedEvents) && !(alwaysSendIfNotEmpty && !subscribedEvents.isEmpty())) { - return; - } - - Set lastSubscribedEvents = new HashSet<>(subscribedEvents); - Map versionsMap = getRegistry().getEventVersions(lastSubscribedEvents); - if (sendPacket(new ServerboundRegisterPacket(versionsMap))) { - this.lastSubscribedEvents = lastSubscribedEvents; - } - } - /** * @return whether the packet was sent successfully */ From 8383418e074bf26d69ad413c3f1d9aa3665b5393 Mon Sep 17 00:00:00 2001 From: Connor Linfoot Date: Tue, 23 Jul 2024 02:30:08 +0100 Subject: [PATCH 5/7] ServerboundRegisterPacket Internal --- .../packet/impl/serverbound/ServerboundRegisterPacket.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/net/hypixel/modapi/packet/impl/serverbound/ServerboundRegisterPacket.java b/src/main/java/net/hypixel/modapi/packet/impl/serverbound/ServerboundRegisterPacket.java index e241b10..8868ba6 100644 --- a/src/main/java/net/hypixel/modapi/packet/impl/serverbound/ServerboundRegisterPacket.java +++ b/src/main/java/net/hypixel/modapi/packet/impl/serverbound/ServerboundRegisterPacket.java @@ -12,6 +12,7 @@ *

* You should not use this packet manually, instead, use {@link net.hypixel.modapi.HypixelModAPI#subscribeToEventPacket(Class)} to subscribe to event packets. */ +@ApiStatus.Internal public class ServerboundRegisterPacket extends ServerboundVersionedPacket { private static final int MAX_IDENTIFIER_LENGTH = 20; private static final int MAX_IDENTIFIERS = 5; @@ -62,6 +63,7 @@ public void write(PacketSerializer serializer) { } } + @ApiStatus.Internal public Map getSubscribedEvents() { return Collections.unmodifiableMap(subscribedEvents); } From 4745bc78e4fc51e8da670f99e5cfbfaba70edb5c Mon Sep 17 00:00:00 2001 From: Connor Linfoot Date: Tue, 23 Jul 2024 02:30:28 +0100 Subject: [PATCH 6/7] ServerboundRegisterPacket remove method internals --- .../packet/impl/serverbound/ServerboundRegisterPacket.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/net/hypixel/modapi/packet/impl/serverbound/ServerboundRegisterPacket.java b/src/main/java/net/hypixel/modapi/packet/impl/serverbound/ServerboundRegisterPacket.java index 8868ba6..c13ffca 100644 --- a/src/main/java/net/hypixel/modapi/packet/impl/serverbound/ServerboundRegisterPacket.java +++ b/src/main/java/net/hypixel/modapi/packet/impl/serverbound/ServerboundRegisterPacket.java @@ -20,7 +20,6 @@ public class ServerboundRegisterPacket extends ServerboundVersionedPacket { private Map subscribedEvents; - @ApiStatus.Internal public ServerboundRegisterPacket(Map subscribedEvents) { super(CURRENT_VERSION); this.subscribedEvents = subscribedEvents; @@ -30,7 +29,6 @@ public ServerboundRegisterPacket(Map subscribedEvents) { } } - @ApiStatus.Internal public ServerboundRegisterPacket(PacketSerializer serializer) { super(serializer); } @@ -63,7 +61,6 @@ public void write(PacketSerializer serializer) { } } - @ApiStatus.Internal public Map getSubscribedEvents() { return Collections.unmodifiableMap(subscribedEvents); } From d18b01a6b772aa23ed8e444a944bb6aaf2161e14 Mon Sep 17 00:00:00 2001 From: Connor Linfoot Date: Tue, 23 Jul 2024 02:32:42 +0100 Subject: [PATCH 7/7] Prevent accidental usage of ServerboundRegisterPacket Makes it not possible to send custom versions that the Mod API doesn't understand --- src/main/java/net/hypixel/modapi/HypixelModAPI.java | 3 +-- .../packet/impl/serverbound/ServerboundRegisterPacket.java | 6 ++++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/hypixel/modapi/HypixelModAPI.java b/src/main/java/net/hypixel/modapi/HypixelModAPI.java index c11b4ff..eecc7d7 100644 --- a/src/main/java/net/hypixel/modapi/HypixelModAPI.java +++ b/src/main/java/net/hypixel/modapi/HypixelModAPI.java @@ -86,8 +86,7 @@ private void sendRegisterPacket(boolean alwaysSendIfNotEmpty) { } Set lastSubscribedEvents = new HashSet<>(subscribedEvents); - Map versionsMap = getRegistry().getEventVersions(lastSubscribedEvents); - if (sendPacket(new ServerboundRegisterPacket(versionsMap))) { + if (sendPacket(new ServerboundRegisterPacket(registry, lastSubscribedEvents))) { this.lastSubscribedEvents = lastSubscribedEvents; } } diff --git a/src/main/java/net/hypixel/modapi/packet/impl/serverbound/ServerboundRegisterPacket.java b/src/main/java/net/hypixel/modapi/packet/impl/serverbound/ServerboundRegisterPacket.java index c13ffca..24af97f 100644 --- a/src/main/java/net/hypixel/modapi/packet/impl/serverbound/ServerboundRegisterPacket.java +++ b/src/main/java/net/hypixel/modapi/packet/impl/serverbound/ServerboundRegisterPacket.java @@ -1,11 +1,13 @@ package net.hypixel.modapi.packet.impl.serverbound; +import net.hypixel.modapi.packet.PacketRegistry; import net.hypixel.modapi.serializer.PacketSerializer; import org.jetbrains.annotations.ApiStatus; import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.Set; /** * Notifys the remote server what versions of event packets we want to receive. @@ -20,9 +22,9 @@ public class ServerboundRegisterPacket extends ServerboundVersionedPacket { private Map subscribedEvents; - public ServerboundRegisterPacket(Map subscribedEvents) { + public ServerboundRegisterPacket(PacketRegistry registry, Set subscribedEventIdentifiers) { super(CURRENT_VERSION); - this.subscribedEvents = subscribedEvents; + this.subscribedEvents = registry.getEventVersions(subscribedEventIdentifiers); if (subscribedEvents.size() > MAX_IDENTIFIERS) { throw new IllegalArgumentException("wantedPackets cannot contain more than " + MAX_IDENTIFIERS + " identifiers");