Skip to content

Commit f005226

Browse files
improvement: Add tests for packet roundtrips (#16)
1 parent c4f579b commit f005226

File tree

10 files changed

+193
-6
lines changed

10 files changed

+193
-6
lines changed

pom.xml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,13 @@
4949
<dependency>
5050
<groupId>org.junit.jupiter</groupId>
5151
<artifactId>junit-jupiter-engine</artifactId>
52-
<version>5.9.2</version>
52+
<version>5.9.3</version>
53+
<scope>test</scope>
54+
</dependency>
55+
<dependency>
56+
<groupId>org.junit.jupiter</groupId>
57+
<artifactId>junit-jupiter-params</artifactId>
58+
<version>5.9.3</version>
5359
<scope>test</scope>
5460
</dependency>
5561
</dependencies>

src/main/java/net/hypixel/modapi/packet/PacketRegistry.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import net.hypixel.modapi.serializer.PacketSerializer;
44

5+
import java.util.Collection;
56
import java.util.Collections;
67
import java.util.Map;
78
import java.util.Set;
@@ -38,6 +39,10 @@ private Registration getRegistration(String identifier) {
3839
return registration;
3940
}
4041

42+
Collection<Registration> getRegistrations() {
43+
return registrations.values();
44+
}
45+
4146
public boolean isRegistered(String identifier) {
4247
return registrations.containsKey(identifier);
4348
}
@@ -92,7 +97,7 @@ public void register() {
9297

9398
}
9499

95-
private static final class Registration {
100+
static final class Registration {
96101

97102
private final Class<? extends ClientboundHypixelPacket> clientboundClazz;
98103
private final Function<PacketSerializer, ? extends ClientboundHypixelPacket> clientPacketFactory;
@@ -107,13 +112,19 @@ public Registration(Class<? extends ClientboundHypixelPacket> clientboundClazz,
107112
this.serverPacketFactory = serverPacketFactory;
108113
}
109114

115+
Class<? extends ClientboundHypixelPacket> getClientboundClazz() {
116+
return clientboundClazz;
117+
}
118+
119+
Class<? extends HypixelPacket> getServerboundClazz() {
120+
return serverboundClazz;
121+
}
122+
110123
@Override
111124
public String toString() {
112125
return "Registration{" +
113126
"clientboundClazz=" + clientboundClazz +
114-
", clientPacketFactory=" + clientPacketFactory +
115127
", serverboundClazz=" + serverboundClazz +
116-
", serverPacketFactory=" + serverPacketFactory +
117128
'}';
118129
}
119130
}

src/test/java/net/hypixe/modapi/TestPacketIdentifierLength.java renamed to src/test/java/net/hypixel/modapi/TestPacketIdentifierLength.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
package net.hypixe.modapi;
1+
package net.hypixel.modapi;
22

3-
import net.hypixel.modapi.HypixelModAPI;
43
import org.junit.jupiter.api.Assertions;
54
import org.junit.jupiter.api.Test;
65

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package net.hypixel.modapi.packet;
2+
3+
import net.hypixel.modapi.packet.ClientboundHypixelPacket;
4+
import net.hypixel.modapi.packet.HypixelPacket;
5+
6+
public interface PacketHandler<T extends HypixelPacket> {
7+
8+
ClientboundHypixelPacket handle(String identifier, T packet);
9+
10+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package net.hypixel.modapi.packet;
2+
3+
import net.hypixel.modapi.packet.handler.LocationHandler;
4+
import net.hypixel.modapi.packet.handler.PartyInfoHandler;
5+
import net.hypixel.modapi.packet.handler.PingHandler;
6+
import net.hypixel.modapi.packet.handler.PlayerInfoHandler;
7+
import net.hypixel.modapi.packet.impl.serverbound.ServerboundLocationPacket;
8+
import net.hypixel.modapi.packet.impl.serverbound.ServerboundPartyInfoPacket;
9+
import net.hypixel.modapi.packet.impl.serverbound.ServerboundPingPacket;
10+
import net.hypixel.modapi.packet.impl.serverbound.ServerboundPlayerInfoPacket;
11+
12+
import java.util.HashMap;
13+
import java.util.Map;
14+
15+
class ServerboundPacketHandler {
16+
private final Map<Class<? extends HypixelPacket>, PacketHandler> packetHandlers = new HashMap<>();
17+
18+
ServerboundPacketHandler() {
19+
register(ServerboundPingPacket.class, new PingHandler());
20+
register(ServerboundLocationPacket.class, new LocationHandler());
21+
register(ServerboundPartyInfoPacket.class, new PartyInfoHandler());
22+
register(ServerboundPlayerInfoPacket.class, new PlayerInfoHandler());
23+
}
24+
25+
private <T extends HypixelPacket> void register(Class<T> packetClass, PacketHandler<T> handler) {
26+
packetHandlers.put(packetClass, handler);
27+
}
28+
29+
public ClientboundHypixelPacket handle(String identifier, HypixelPacket packet) {
30+
PacketHandler handler = packetHandlers.get(packet.getClass());
31+
if (handler == null) {
32+
return null;
33+
}
34+
35+
return handler.handle(identifier, packet);
36+
}
37+
38+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package net.hypixel.modapi.packet;
2+
3+
import io.netty.buffer.Unpooled;
4+
import net.hypixel.modapi.HypixelModAPI;
5+
import net.hypixel.modapi.serializer.PacketSerializer;
6+
import org.junit.jupiter.api.Assertions;
7+
import org.junit.jupiter.params.ParameterizedTest;
8+
import org.junit.jupiter.params.provider.Arguments;
9+
import org.junit.jupiter.params.provider.MethodSource;
10+
11+
import java.lang.reflect.InvocationTargetException;
12+
import java.util.stream.Stream;
13+
14+
public class TestPacketRoundtrip {
15+
private static final ServerboundPacketHandler HANDLER = new ServerboundPacketHandler();
16+
17+
private static ClientboundHypixelPacket handleServerbound(String identifier, PacketSerializer serializer) {
18+
HypixelPacket packet = HypixelModAPI.getInstance().getRegistry().createServerboundPacket(identifier, serializer);
19+
if (packet == null) {
20+
throw new IllegalArgumentException("Unknown packet identifier: " + identifier);
21+
}
22+
23+
return HANDLER.handle(identifier, packet);
24+
}
25+
26+
private static ClientboundHypixelPacket doPacketRoundtrip(HypixelPacket packet) {
27+
PacketSerializer serializer = new PacketSerializer(Unpooled.buffer());
28+
packet.write(serializer);
29+
return handleServerbound(packet.getIdentifier(), serializer);
30+
}
31+
32+
private static Stream<Arguments> packetProvider() {
33+
return HypixelModAPI.getInstance().getRegistry().getRegistrations().stream()
34+
.filter(registration -> registration.getServerboundClazz() != null)
35+
.map(Arguments::of);
36+
}
37+
38+
@ParameterizedTest
39+
@MethodSource("packetProvider")
40+
void testPacketRoundtrip(PacketRegistry.Registration registration) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
41+
HypixelPacket serverbound = registration.getServerboundClazz().getConstructor().newInstance();
42+
ClientboundHypixelPacket response = doPacketRoundtrip(serverbound);
43+
Assertions.assertNotNull(response, "No response for packet " + registration.getServerboundClazz().getSimpleName());
44+
Assertions.assertEquals(registration.getClientboundClazz(), response.getClass(), "Unexpected response for packet " + registration.getServerboundClazz().getSimpleName());
45+
}
46+
47+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package net.hypixel.modapi.packet.handler;
2+
3+
import net.hypixel.data.region.Environment;
4+
import net.hypixel.data.type.GameType;
5+
import net.hypixel.modapi.packet.ClientboundHypixelPacket;
6+
import net.hypixel.modapi.packet.PacketHandler;
7+
import net.hypixel.modapi.packet.impl.clientbound.ClientboundLocationPacket;
8+
import net.hypixel.modapi.packet.impl.serverbound.ServerboundLocationPacket;
9+
10+
public class LocationHandler implements PacketHandler<ServerboundLocationPacket> {
11+
@Override
12+
public ClientboundHypixelPacket handle(String identifier, ServerboundLocationPacket packet) {
13+
return new ClientboundLocationPacket(
14+
Environment.TEST,
15+
"chi-hp-bungee1",
16+
"mini1A",
17+
GameType.HOUSING,
18+
null,
19+
null,
20+
null
21+
);
22+
}
23+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package net.hypixel.modapi.packet.handler;
2+
3+
import net.hypixel.modapi.packet.ClientboundHypixelPacket;
4+
import net.hypixel.modapi.packet.PacketHandler;
5+
import net.hypixel.modapi.packet.impl.clientbound.ClientboundPartyInfoPacket;
6+
import net.hypixel.modapi.packet.impl.serverbound.ServerboundPartyInfoPacket;
7+
8+
import java.util.Collections;
9+
10+
public class PartyInfoHandler implements PacketHandler<ServerboundPartyInfoPacket> {
11+
@Override
12+
public ClientboundHypixelPacket handle(String identifier, ServerboundPartyInfoPacket packet) {
13+
return new ClientboundPartyInfoPacket(
14+
false,
15+
null,
16+
Collections.emptySet()
17+
);
18+
}
19+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package net.hypixel.modapi.packet.handler;
2+
3+
import net.hypixel.modapi.packet.PacketHandler;
4+
import net.hypixel.modapi.packet.ClientboundHypixelPacket;
5+
import net.hypixel.modapi.packet.impl.clientbound.ClientboundPingPacket;
6+
import net.hypixel.modapi.packet.impl.serverbound.ServerboundPingPacket;
7+
8+
public class PingHandler implements PacketHandler<ServerboundPingPacket> {
9+
@Override
10+
public ClientboundHypixelPacket handle(String identifier, ServerboundPingPacket packet) {
11+
return new ClientboundPingPacket("pong");
12+
}
13+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package net.hypixel.modapi.packet.handler;
2+
3+
import net.hypixel.data.rank.MonthlyPackageRank;
4+
import net.hypixel.data.rank.PackageRank;
5+
import net.hypixel.data.rank.PlayerRank;
6+
import net.hypixel.modapi.packet.ClientboundHypixelPacket;
7+
import net.hypixel.modapi.packet.PacketHandler;
8+
import net.hypixel.modapi.packet.impl.clientbound.ClientboundPlayerInfoPacket;
9+
import net.hypixel.modapi.packet.impl.serverbound.ServerboundPlayerInfoPacket;
10+
11+
public class PlayerInfoHandler implements PacketHandler<ServerboundPlayerInfoPacket> {
12+
@Override
13+
public ClientboundHypixelPacket handle(String identifier, ServerboundPlayerInfoPacket packet) {
14+
return new ClientboundPlayerInfoPacket(
15+
PlayerRank.NORMAL,
16+
PackageRank.MVP_PLUS,
17+
MonthlyPackageRank.SUPERSTAR,
18+
null
19+
);
20+
}
21+
}

0 commit comments

Comments
 (0)