Skip to content

Commit 647523c

Browse files
Add the ability to register an error handler (#39)
Changes registerHandler to return a RegisteredHandler instance, which can then be used to register handling for errors received for that packet.
1 parent aac42d9 commit 647523c

File tree

3 files changed

+79
-10
lines changed

3 files changed

+79
-10
lines changed

src/main/java/net/hypixel/modapi/HypixelModAPI.java

Lines changed: 58 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
package net.hypixel.modapi;
22

33
import net.hypixel.modapi.error.ErrorReason;
4-
import net.hypixel.modapi.error.ModAPIException;
54
import net.hypixel.modapi.handler.ClientboundPacketHandler;
5+
import net.hypixel.modapi.handler.ErrorHandler;
6+
import net.hypixel.modapi.handler.RegisteredHandler;
67
import net.hypixel.modapi.packet.ClientboundHypixelPacket;
78
import net.hypixel.modapi.packet.EventPacket;
89
import net.hypixel.modapi.packet.HypixelPacket;
@@ -29,7 +30,7 @@ public static HypixelModAPI getInstance() {
2930
}
3031

3132
private final PacketRegistry registry = new PacketRegistry();
32-
private final Map<Class<? extends ClientboundHypixelPacket>, Collection<ClientboundPacketHandler<?>>> handlers = new ConcurrentHashMap<>();
33+
private final Map<String, Collection<RegisteredHandlerImpl<?>>> handlers = new ConcurrentHashMap<>();
3334
private final Set<String> subscribedEvents = ConcurrentHashMap.newKeySet();
3435
private Set<String> lastSubscribedEvents = Collections.emptySet();
3536
private Predicate<HypixelPacket> packetSender = null;
@@ -109,7 +110,8 @@ public void handle(String identifier, PacketSerializer serializer) {
109110
// 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
110111
if (!serializer.readBoolean()) {
111112
ErrorReason reason = ErrorReason.getById(serializer.readVarInt());
112-
throw new ModAPIException(identifier, reason);
113+
handleError(identifier, reason);
114+
return;
113115
}
114116

115117
ClientboundHypixelPacket packet = registry.createClientboundPacket(identifier, serializer);
@@ -124,12 +126,20 @@ public void handle(String identifier, PacketSerializer serializer) {
124126
@ApiStatus.Internal
125127
@SuppressWarnings("unchecked")
126128
public void handle(ClientboundHypixelPacket packet) {
127-
Collection<ClientboundPacketHandler<?>> typedHandlers = handlers.get(packet.getClass());
129+
Collection<RegisteredHandlerImpl<?>> typedHandlers = handlers.get(packet.getIdentifier());
128130
// nothing registered for this packet.
129131
if (typedHandlers == null) return;
130-
for (ClientboundPacketHandler<?> handler : typedHandlers) {
131-
// this cast is safe as we ensure its type when it is added to the handlers list in the first place.
132-
((ClientboundPacketHandler<ClientboundHypixelPacket>) handler).handle(packet);
132+
for (RegisteredHandlerImpl<?> handler : typedHandlers) {
133+
handler.handle(packet);
134+
}
135+
}
136+
137+
@ApiStatus.Internal
138+
public void handleError(String identifier, ErrorReason reason) {
139+
Collection<RegisteredHandlerImpl<?>> handlers = this.handlers.get(identifier);
140+
if (handlers == null) return;
141+
for (RegisteredHandlerImpl<?> handler : handlers) {
142+
handler.handleError(reason);
133143
}
134144
}
135145

@@ -141,9 +151,19 @@ public void setPacketSender(Predicate<HypixelPacket> packetSender) {
141151
this.packetSender = packetSender;
142152
}
143153

144-
public <T extends ClientboundHypixelPacket> void registerHandler(Class<T> packetClass, ClientboundPacketHandler<T> handler) {
145-
if (packetClass == null || handler == null) return;
146-
handlers.computeIfAbsent(packetClass, cls -> new CopyOnWriteArrayList<>()).add(handler);
154+
public <T extends ClientboundHypixelPacket> RegisteredHandler<T> registerHandler(Class<T> packetClass, ClientboundPacketHandler<T> handler) {
155+
if (packetClass == null) {
156+
throw new NullPointerException("packetClass cannot be null");
157+
}
158+
159+
if (handler == null) {
160+
throw new NullPointerException("handler cannot be null");
161+
}
162+
163+
RegisteredHandlerImpl<T> registeredHandler = new RegisteredHandlerImpl<>(handler);
164+
handlers.computeIfAbsent(getRegistry().getIdentifier(packetClass), cls -> new CopyOnWriteArrayList<>())
165+
.add(registeredHandler);
166+
return registeredHandler;
147167
}
148168

149169
public void subscribeToEventPacket(Class<? extends EventPacket> packet) {
@@ -162,4 +182,32 @@ public boolean sendPacket(HypixelPacket packet) {
162182

163183
return packetSender.test(packet);
164184
}
185+
186+
private static class RegisteredHandlerImpl<T extends ClientboundHypixelPacket> implements RegisteredHandler<T> {
187+
private final ClientboundPacketHandler<T> handler;
188+
private ErrorHandler<T> errorHandler;
189+
190+
RegisteredHandlerImpl(ClientboundPacketHandler<T> handler) {
191+
this.handler = handler;
192+
}
193+
194+
@Override
195+
public void onError(ErrorHandler<T> errorHandler) {
196+
if (this.errorHandler != null) {
197+
throw new IllegalStateException("Error handler already set");
198+
}
199+
this.errorHandler = errorHandler;
200+
}
201+
202+
void handle(ClientboundHypixelPacket packet) {
203+
// this cast is safe as we ensure its type when it is added to the handlers list in the first place.
204+
handler.handle((T) packet);
205+
}
206+
207+
void handleError(ErrorReason reason) {
208+
if (errorHandler != null) {
209+
errorHandler.onError(reason);
210+
}
211+
}
212+
}
165213
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package net.hypixel.modapi.handler;
2+
3+
import net.hypixel.modapi.error.ErrorReason;
4+
import net.hypixel.modapi.packet.ClientboundHypixelPacket;
5+
6+
@FunctionalInterface
7+
public interface ErrorHandler<T extends ClientboundHypixelPacket> {
8+
void onError(ErrorReason reason);
9+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package net.hypixel.modapi.handler;
2+
3+
import net.hypixel.modapi.packet.ClientboundHypixelPacket;
4+
5+
public interface RegisteredHandler<T extends ClientboundHypixelPacket> {
6+
/**
7+
* Handling for when an error is received for this registered handler.
8+
* <br>
9+
* Note: This error may be received due to any modification requesting the same packet type.
10+
*/
11+
void onError(ErrorHandler<T> errorHandler);
12+
}

0 commit comments

Comments
 (0)