11package net .hypixel .modapi ;
22
33import net .hypixel .modapi .error .ErrorReason ;
4- import net .hypixel .modapi .error .ModAPIException ;
54import net .hypixel .modapi .handler .ClientboundPacketHandler ;
5+ import net .hypixel .modapi .handler .ErrorHandler ;
6+ import net .hypixel .modapi .handler .RegisteredHandler ;
67import net .hypixel .modapi .packet .ClientboundHypixelPacket ;
78import net .hypixel .modapi .packet .EventPacket ;
89import 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}
0 commit comments