diff --git a/pom.xml b/pom.xml
index 3cdb3d3..a633051 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
net.hypixel
mod-api
- 0.2.1
+ dev-SNAPSHOT
8
@@ -14,6 +14,13 @@
UTF-8
+
+
+ Hypixel
+ https://repo.hypixel.net/repository/Hypixel/
+
+
+
Hypixel
@@ -39,6 +46,12 @@
hypixel-data
0.1.2
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ 5.9.2
+ test
+
@@ -66,6 +79,11 @@
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 2.22.2
+
diff --git a/src/main/java/net/hypixel/modapi/HypixelModAPI.java b/src/main/java/net/hypixel/modapi/HypixelModAPI.java
index 64de208..3f3dff9 100644
--- a/src/main/java/net/hypixel/modapi/HypixelModAPI.java
+++ b/src/main/java/net/hypixel/modapi/HypixelModAPI.java
@@ -4,7 +4,15 @@
import net.hypixel.modapi.error.ModAPIException;
import net.hypixel.modapi.handler.ClientboundPacketHandler;
import net.hypixel.modapi.packet.HypixelPacket;
-import net.hypixel.modapi.packet.HypixelPacketType;
+import net.hypixel.modapi.packet.PacketRegistry;
+import net.hypixel.modapi.packet.impl.clientbound.ClientboundLocationPacket;
+import net.hypixel.modapi.packet.impl.clientbound.ClientboundPartyInfoPacket;
+import net.hypixel.modapi.packet.impl.clientbound.ClientboundPingPacket;
+import net.hypixel.modapi.packet.impl.clientbound.ClientboundPlayerInfoPacket;
+import net.hypixel.modapi.packet.impl.serverbound.ServerboundLocationPacket;
+import net.hypixel.modapi.packet.impl.serverbound.ServerboundPartyInfoPacket;
+import net.hypixel.modapi.packet.impl.serverbound.ServerboundPingPacket;
+import net.hypixel.modapi.packet.impl.serverbound.ServerboundPlayerInfoPacket;
import net.hypixel.modapi.serializer.PacketSerializer;
import java.util.List;
@@ -17,33 +25,49 @@ public static HypixelModAPI getInstance() {
return INSTANCE;
}
- private final List packetHandlers = new CopyOnWriteArrayList<>();
+ private final PacketRegistry registry = new PacketRegistry();
+ private final List handlers = new CopyOnWriteArrayList<>();
private HypixelModAPI() {
+ registry.registerPacketType("hypixel:ping",
+ ClientboundPingPacket.class, ClientboundPingPacket::new,
+ ServerboundPingPacket.class, ServerboundPingPacket::new);
+ registry.registerPacketType("hypixel:location",
+ ClientboundLocationPacket.class, ClientboundLocationPacket::new,
+ ServerboundLocationPacket.class, ServerboundLocationPacket::new);
+ registry.registerPacketType("hypixel:party_info",
+ ClientboundPartyInfoPacket.class, ClientboundPartyInfoPacket::new,
+ ServerboundPartyInfoPacket.class, ServerboundPartyInfoPacket::new);
+ registry.registerPacketType("hypixel:player_info",
+ ClientboundPlayerInfoPacket.class, ClientboundPlayerInfoPacket::new,
+ ServerboundPlayerInfoPacket.class, ServerboundPlayerInfoPacket::new);
+ }
+
+ public PacketRegistry getRegistry() {
+ return registry;
}
public void registerHandler(ClientboundPacketHandler handler) {
- packetHandlers.add(handler);
+ handlers.add(handler);
}
public void handle(String identifier, PacketSerializer serializer) {
- if (packetHandlers.isEmpty()) {
+ if (handlers.isEmpty()) {
return;
}
- HypixelPacketType packetType = HypixelPacketType.getByIdentifier(identifier);
- if (packetType == null) {
+ if (!registry.isRegistered(identifier)) {
return;
}
- // All responses contain a boolean of if the response is a success, if not then a string is included with the error message
+ // All responses contain a boolean of if the response is a success, if not then a further var int is included to identify the error
if (!serializer.readBoolean()) {
ErrorReason reason = ErrorReason.getById(serializer.readVarInt());
- throw new ModAPIException(packetType, reason);
+ throw new ModAPIException(identifier, reason);
}
- HypixelPacket packet = packetType.getPacketFactory().apply(serializer);
- for (ClientboundPacketHandler handler : packetHandlers) {
+ HypixelPacket packet = registry.createClientboundPacket(identifier, serializer);
+ for (ClientboundPacketHandler handler : handlers) {
handler.handle(packet);
}
}
diff --git a/src/main/java/net/hypixel/modapi/error/ModAPIException.java b/src/main/java/net/hypixel/modapi/error/ModAPIException.java
index 2b8857b..934474d 100644
--- a/src/main/java/net/hypixel/modapi/error/ModAPIException.java
+++ b/src/main/java/net/hypixel/modapi/error/ModAPIException.java
@@ -1,19 +1,17 @@
package net.hypixel.modapi.error;
-import net.hypixel.modapi.packet.HypixelPacketType;
-
public class ModAPIException extends RuntimeException {
- private final HypixelPacketType packetType;
+ private final String identifier;
private final ErrorReason reason;
- public ModAPIException(HypixelPacketType packetType, ErrorReason reason) {
- super(String.format("Received error response '%s' from packet '%s'", reason, packetType));
- this.packetType = packetType;
+ public ModAPIException(String identifier, ErrorReason reason) {
+ super(String.format("Received error response '%s' from packet '%s'", reason, identifier));
+ this.identifier = identifier;
this.reason = reason;
}
- public HypixelPacketType getPacketType() {
- return packetType;
+ public String getIdentifier() {
+ return identifier;
}
public ErrorReason getReason() {
@@ -23,7 +21,7 @@ public ErrorReason getReason() {
@Override
public String toString() {
return "ModAPIException{" +
- "packetType=" + packetType +
+ "identifier='" + identifier + '\'' +
", reason=" + reason +
"} " + super.toString();
}
diff --git a/src/main/java/net/hypixel/modapi/packet/HypixelPacket.java b/src/main/java/net/hypixel/modapi/packet/HypixelPacket.java
index f71492e..610d9cd 100644
--- a/src/main/java/net/hypixel/modapi/packet/HypixelPacket.java
+++ b/src/main/java/net/hypixel/modapi/packet/HypixelPacket.java
@@ -1,11 +1,14 @@
package net.hypixel.modapi.packet;
+import net.hypixel.modapi.HypixelModAPI;
import net.hypixel.modapi.serializer.PacketSerializer;
public interface HypixelPacket {
- HypixelPacketType getType();
-
void write(PacketSerializer serializer);
+ default String getIdentifier() {
+ return HypixelModAPI.getInstance().getRegistry().getIdentifier(getClass());
+ }
+
}
diff --git a/src/main/java/net/hypixel/modapi/packet/HypixelPacketType.java b/src/main/java/net/hypixel/modapi/packet/HypixelPacketType.java
deleted file mode 100644
index fff4652..0000000
--- a/src/main/java/net/hypixel/modapi/packet/HypixelPacketType.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package net.hypixel.modapi.packet;
-
-import net.hypixel.modapi.packet.impl.clientbound.ClientboundLocationPacket;
-import net.hypixel.modapi.packet.impl.clientbound.ClientboundPartyInfoPacket;
-import net.hypixel.modapi.packet.impl.clientbound.ClientboundPingPacket;
-import net.hypixel.modapi.packet.impl.clientbound.ClientboundPlayerInfoPacket;
-import net.hypixel.modapi.serializer.PacketSerializer;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.function.Function;
-
-public enum HypixelPacketType {
- PING(ClientboundPingPacket::new),
- LOCATION(ClientboundLocationPacket::new),
- PARTY_INFO(ClientboundPartyInfoPacket::new),
- PLAYER_INFO(ClientboundPlayerInfoPacket::new),
- ;
- private static final String IDENTIFIER_PREFIX = "hypixel:";
- private static final Map BY_IDENTIFIER = Arrays.stream(values()).collect(HashMap::new, (map, type) -> map.put(type.getIdentifier(), type), HashMap::putAll);
- private final Function packetFactory;
-
- @Nullable
- public static HypixelPacketType getByIdentifier(String identifier) {
- return BY_IDENTIFIER.get(identifier);
- }
-
- private final String identifier;
-
- HypixelPacketType(Function packetFactory) {
- this.identifier = IDENTIFIER_PREFIX + name().toLowerCase();
- this.packetFactory = packetFactory;
- }
-
- public String getIdentifier() {
- return identifier;
- }
-
- public Function getPacketFactory() {
- return packetFactory;
- }
-}
diff --git a/src/main/java/net/hypixel/modapi/packet/PacketRegistry.java b/src/main/java/net/hypixel/modapi/packet/PacketRegistry.java
new file mode 100644
index 0000000..8161015
--- /dev/null
+++ b/src/main/java/net/hypixel/modapi/packet/PacketRegistry.java
@@ -0,0 +1,68 @@
+package net.hypixel.modapi.packet;
+
+import net.hypixel.modapi.serializer.PacketSerializer;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Function;
+
+public class PacketRegistry {
+
+ private final Map registrations = new ConcurrentHashMap<>();
+ private final Map, String> classToIdentifier = new ConcurrentHashMap<>();
+
+ public void registerPacketType(String identifier,
+ Class extends HypixelPacket> clientboundClazz, Function clientPacketFactory,
+ Class extends HypixelPacket> serverboundClazz, Function serverPacketFactory) {
+ registrations.put(identifier, new RegisteredType(clientboundClazz, clientPacketFactory, serverboundClazz, serverPacketFactory));
+ classToIdentifier.put(clientboundClazz, identifier);
+ classToIdentifier.put(serverboundClazz, identifier);
+ }
+
+ private RegisteredType getRegisteredType(String identifier) {
+ RegisteredType registeredType = registrations.get(identifier);
+ if (registeredType == null) {
+ throw new IllegalArgumentException("Unknown packet identifier: " + identifier);
+ }
+ return registeredType;
+ }
+
+ public boolean isRegistered(String identifier) {
+ return registrations.containsKey(identifier);
+ }
+
+ public HypixelPacket createClientboundPacket(String identifier, PacketSerializer serializer) {
+ return getRegisteredType(identifier).clientPacketFactory.apply(serializer);
+ }
+
+ public HypixelPacket createServerboundPacket(String identifier, PacketSerializer serializer) {
+ return getRegisteredType(identifier).serverPacketFactory.apply(serializer);
+ }
+
+ public String getIdentifier(Class extends HypixelPacket> clazz) {
+ return classToIdentifier.get(clazz);
+ }
+
+ public Set getIdentifiers() {
+ return Collections.unmodifiableSet(registrations.keySet());
+ }
+
+ private static final class RegisteredType {
+
+ private final Class extends HypixelPacket> clientboundClazz;
+ private final Function clientPacketFactory;
+ private final Class extends HypixelPacket> serverboundClazz;
+ private final Function serverPacketFactory;
+
+ public RegisteredType(Class extends HypixelPacket> clientboundClazz, Function clientPacketFactory,
+ Class extends HypixelPacket> serverboundClazz, Function serverPacketFactory) {
+ this.clientboundClazz = clientboundClazz;
+ this.clientPacketFactory = clientPacketFactory;
+ this.serverboundClazz = serverboundClazz;
+ this.serverPacketFactory = serverPacketFactory;
+ }
+ }
+
+}
diff --git a/src/main/java/net/hypixel/modapi/packet/impl/clientbound/ClientboundLocationPacket.java b/src/main/java/net/hypixel/modapi/packet/impl/clientbound/ClientboundLocationPacket.java
index e607fa1..8fd44fc 100644
--- a/src/main/java/net/hypixel/modapi/packet/impl/clientbound/ClientboundLocationPacket.java
+++ b/src/main/java/net/hypixel/modapi/packet/impl/clientbound/ClientboundLocationPacket.java
@@ -2,7 +2,6 @@
import net.hypixel.data.region.Environment;
import net.hypixel.data.type.ServerType;
-import net.hypixel.modapi.packet.HypixelPacketType;
import net.hypixel.modapi.packet.impl.VersionedPacket;
import net.hypixel.modapi.serializer.PacketSerializer;
import org.jetbrains.annotations.Nullable;
@@ -46,11 +45,6 @@ public ClientboundLocationPacket(PacketSerializer serializer) {
this.map = serializer.readBoolean() ? serializer.readString() : null;
}
- @Override
- public HypixelPacketType getType() {
- return HypixelPacketType.LOCATION;
- }
-
@Override
public void write(PacketSerializer serializer) {
super.write(serializer);
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 a716523..bbb5cb5 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,5 @@
package net.hypixel.modapi.packet.impl.clientbound;
-import net.hypixel.modapi.packet.HypixelPacketType;
import net.hypixel.modapi.packet.impl.VersionedPacket;
import net.hypixel.modapi.serializer.PacketSerializer;
import org.jetbrains.annotations.Nullable;
@@ -40,11 +39,6 @@ public ClientboundPartyInfoPacket(PacketSerializer serializer) {
this.members = Collections.unmodifiableSet(members);
}
- @Override
- public HypixelPacketType getType() {
- return HypixelPacketType.PARTY_INFO;
- }
-
@Override
public void write(PacketSerializer serializer) {
super.write(serializer);
diff --git a/src/main/java/net/hypixel/modapi/packet/impl/clientbound/ClientboundPingPacket.java b/src/main/java/net/hypixel/modapi/packet/impl/clientbound/ClientboundPingPacket.java
index ef694ef..5079612 100644
--- a/src/main/java/net/hypixel/modapi/packet/impl/clientbound/ClientboundPingPacket.java
+++ b/src/main/java/net/hypixel/modapi/packet/impl/clientbound/ClientboundPingPacket.java
@@ -1,6 +1,5 @@
package net.hypixel.modapi.packet.impl.clientbound;
-import net.hypixel.modapi.packet.HypixelPacketType;
import net.hypixel.modapi.packet.impl.VersionedPacket;
import net.hypixel.modapi.serializer.PacketSerializer;
@@ -19,11 +18,6 @@ public ClientboundPingPacket(PacketSerializer serializer) {
this.response = serializer.readString();
}
- @Override
- public HypixelPacketType getType() {
- return HypixelPacketType.PING;
- }
-
@Override
public void write(PacketSerializer serializer) {
super.write(serializer);
diff --git a/src/main/java/net/hypixel/modapi/packet/impl/clientbound/ClientboundPlayerInfoPacket.java b/src/main/java/net/hypixel/modapi/packet/impl/clientbound/ClientboundPlayerInfoPacket.java
index e13f5de..85215f1 100644
--- a/src/main/java/net/hypixel/modapi/packet/impl/clientbound/ClientboundPlayerInfoPacket.java
+++ b/src/main/java/net/hypixel/modapi/packet/impl/clientbound/ClientboundPlayerInfoPacket.java
@@ -3,7 +3,6 @@
import net.hypixel.data.rank.MonthlyPackageRank;
import net.hypixel.data.rank.PackageRank;
import net.hypixel.data.rank.PlayerRank;
-import net.hypixel.modapi.packet.HypixelPacketType;
import net.hypixel.modapi.packet.impl.VersionedPacket;
import net.hypixel.modapi.serializer.PacketSerializer;
import org.jetbrains.annotations.Nullable;
@@ -35,11 +34,6 @@ public ClientboundPlayerInfoPacket(PacketSerializer serializer) {
this.prefix = serializer.readBoolean() ? serializer.readString() : null;
}
- @Override
- public HypixelPacketType getType() {
- return HypixelPacketType.PLAYER_INFO;
- }
-
@Override
public void write(PacketSerializer serializer) {
super.write(serializer);
diff --git a/src/main/java/net/hypixel/modapi/packet/impl/serverbound/ServerboundLocationPacket.java b/src/main/java/net/hypixel/modapi/packet/impl/serverbound/ServerboundLocationPacket.java
index 77b1978..01bfc95 100644
--- a/src/main/java/net/hypixel/modapi/packet/impl/serverbound/ServerboundLocationPacket.java
+++ b/src/main/java/net/hypixel/modapi/packet/impl/serverbound/ServerboundLocationPacket.java
@@ -1,6 +1,5 @@
package net.hypixel.modapi.packet.impl.serverbound;
-import net.hypixel.modapi.packet.HypixelPacketType;
import net.hypixel.modapi.packet.impl.VersionedPacket;
import net.hypixel.modapi.serializer.PacketSerializer;
@@ -15,8 +14,4 @@ public ServerboundLocationPacket(PacketSerializer serializer) {
super(serializer);
}
- @Override
- public HypixelPacketType getType() {
- return HypixelPacketType.LOCATION;
- }
}
diff --git a/src/main/java/net/hypixel/modapi/packet/impl/serverbound/ServerboundPartyInfoPacket.java b/src/main/java/net/hypixel/modapi/packet/impl/serverbound/ServerboundPartyInfoPacket.java
index e980283..5727bf4 100644
--- a/src/main/java/net/hypixel/modapi/packet/impl/serverbound/ServerboundPartyInfoPacket.java
+++ b/src/main/java/net/hypixel/modapi/packet/impl/serverbound/ServerboundPartyInfoPacket.java
@@ -1,6 +1,5 @@
package net.hypixel.modapi.packet.impl.serverbound;
-import net.hypixel.modapi.packet.HypixelPacketType;
import net.hypixel.modapi.packet.impl.VersionedPacket;
import net.hypixel.modapi.serializer.PacketSerializer;
@@ -15,8 +14,4 @@ public ServerboundPartyInfoPacket(PacketSerializer serializer) {
super(serializer);
}
- @Override
- public HypixelPacketType getType() {
- return HypixelPacketType.PARTY_INFO;
- }
}
diff --git a/src/main/java/net/hypixel/modapi/packet/impl/serverbound/ServerboundPingPacket.java b/src/main/java/net/hypixel/modapi/packet/impl/serverbound/ServerboundPingPacket.java
index fbd31e0..b0ced64 100644
--- a/src/main/java/net/hypixel/modapi/packet/impl/serverbound/ServerboundPingPacket.java
+++ b/src/main/java/net/hypixel/modapi/packet/impl/serverbound/ServerboundPingPacket.java
@@ -1,6 +1,5 @@
package net.hypixel.modapi.packet.impl.serverbound;
-import net.hypixel.modapi.packet.HypixelPacketType;
import net.hypixel.modapi.packet.impl.VersionedPacket;
import net.hypixel.modapi.serializer.PacketSerializer;
@@ -15,8 +14,4 @@ public ServerboundPingPacket(PacketSerializer serializer) {
super(serializer);
}
- @Override
- public HypixelPacketType getType() {
- return HypixelPacketType.PING;
- }
}
diff --git a/src/main/java/net/hypixel/modapi/packet/impl/serverbound/ServerboundPlayerInfoPacket.java b/src/main/java/net/hypixel/modapi/packet/impl/serverbound/ServerboundPlayerInfoPacket.java
index 71454d9..32e8ea8 100644
--- a/src/main/java/net/hypixel/modapi/packet/impl/serverbound/ServerboundPlayerInfoPacket.java
+++ b/src/main/java/net/hypixel/modapi/packet/impl/serverbound/ServerboundPlayerInfoPacket.java
@@ -1,6 +1,5 @@
package net.hypixel.modapi.packet.impl.serverbound;
-import net.hypixel.modapi.packet.HypixelPacketType;
import net.hypixel.modapi.packet.impl.VersionedPacket;
import net.hypixel.modapi.serializer.PacketSerializer;
@@ -15,8 +14,4 @@ public ServerboundPlayerInfoPacket(PacketSerializer serializer) {
super(serializer);
}
- @Override
- public HypixelPacketType getType() {
- return HypixelPacketType.PLAYER_INFO;
- }
}
diff --git a/src/test/java/net/hypixe/modapi/TestPacketIdentifierLength.java b/src/test/java/net/hypixe/modapi/TestPacketIdentifierLength.java
new file mode 100644
index 0000000..9932960
--- /dev/null
+++ b/src/test/java/net/hypixe/modapi/TestPacketIdentifierLength.java
@@ -0,0 +1,17 @@
+package net.hypixe.modapi;
+
+import net.hypixel.modapi.HypixelModAPI;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class TestPacketIdentifierLength {
+ private static final int LIMIT = 20;
+
+ @Test
+ void testPacketIdentifierLength() {
+ for (String identifier : HypixelModAPI.getInstance().getRegistry().getIdentifiers()) {
+ Assertions.assertTrue(identifier.length() <= LIMIT, String.format("Identifier %s is too long (length %d)", identifier, identifier.length()));
+ }
+ }
+
+}