diff --git a/src/main/java/net/hypixel/modapi/HypixelModAPI.java b/src/main/java/net/hypixel/modapi/HypixelModAPI.java index 937dd16..64de208 100644 --- a/src/main/java/net/hypixel/modapi/HypixelModAPI.java +++ b/src/main/java/net/hypixel/modapi/HypixelModAPI.java @@ -1,5 +1,7 @@ package net.hypixel.modapi; +import net.hypixel.modapi.error.ErrorReason; +import net.hypixel.modapi.error.ModAPIException; import net.hypixel.modapi.handler.ClientboundPacketHandler; import net.hypixel.modapi.packet.HypixelPacket; import net.hypixel.modapi.packet.HypixelPacketType; @@ -36,8 +38,8 @@ public void handle(String identifier, PacketSerializer serializer) { // All responses contain a boolean of if the response is a success, if not then a string is included with the error message if (!serializer.readBoolean()) { - String errorMessage = serializer.readString(); - throw new RuntimeException("Received error response for packet " + packetType + ": " + errorMessage); + ErrorReason reason = ErrorReason.getById(serializer.readVarInt()); + throw new ModAPIException(packetType, reason); } HypixelPacket packet = packetType.getPacketFactory().apply(serializer); diff --git a/src/main/java/net/hypixel/modapi/error/BuiltinErrorReason.java b/src/main/java/net/hypixel/modapi/error/BuiltinErrorReason.java new file mode 100644 index 0000000..5d8b907 --- /dev/null +++ b/src/main/java/net/hypixel/modapi/error/BuiltinErrorReason.java @@ -0,0 +1,33 @@ +package net.hypixel.modapi.error; + +import java.util.Arrays; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +public enum BuiltinErrorReason implements ErrorReason { + DISABLED(1), + INTERNAL_SERVER_ERROR(2), + RATE_LIMITED(3), + INVALID_PACKET_VERSION(4), + NO_LONGER_SUPPORTED(5), + ; + + private static final Map BY_ID = Arrays.stream(values()) + .collect(Collectors.toMap(BuiltinErrorReason::getId, Function.identity())); + + static BuiltinErrorReason getById(int id) { + return BY_ID.get(id); + } + + private final int id; + + BuiltinErrorReason(int id) { + this.id = id; + } + + @Override + public int getId() { + return id; + } +} diff --git a/src/main/java/net/hypixel/modapi/error/ErrorReason.java b/src/main/java/net/hypixel/modapi/error/ErrorReason.java new file mode 100644 index 0000000..a50eed6 --- /dev/null +++ b/src/main/java/net/hypixel/modapi/error/ErrorReason.java @@ -0,0 +1,14 @@ +package net.hypixel.modapi.error; + +public interface ErrorReason { + int getId(); + + static ErrorReason getById(int id) { + BuiltinErrorReason reason = BuiltinErrorReason.getById(id); + if (reason != null) { + return reason; + } + + return new UnknownErrorReason(id); + } +} diff --git a/src/main/java/net/hypixel/modapi/error/ModAPIException.java b/src/main/java/net/hypixel/modapi/error/ModAPIException.java new file mode 100644 index 0000000..2b8857b --- /dev/null +++ b/src/main/java/net/hypixel/modapi/error/ModAPIException.java @@ -0,0 +1,30 @@ +package net.hypixel.modapi.error; + +import net.hypixel.modapi.packet.HypixelPacketType; + +public class ModAPIException extends RuntimeException { + private final HypixelPacketType packetType; + 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; + this.reason = reason; + } + + public HypixelPacketType getPacketType() { + return packetType; + } + + public ErrorReason getReason() { + return reason; + } + + @Override + public String toString() { + return "ModAPIException{" + + "packetType=" + packetType + + ", reason=" + reason + + "} " + super.toString(); + } +} diff --git a/src/main/java/net/hypixel/modapi/error/UnknownErrorReason.java b/src/main/java/net/hypixel/modapi/error/UnknownErrorReason.java new file mode 100644 index 0000000..2530337 --- /dev/null +++ b/src/main/java/net/hypixel/modapi/error/UnknownErrorReason.java @@ -0,0 +1,21 @@ +package net.hypixel.modapi.error; + +public class UnknownErrorReason implements ErrorReason { + private final int id; + + UnknownErrorReason(int id) { + this.id = id; + } + + @Override + public int getId() { + return id; + } + + @Override + public String toString() { + return "UnknownErrorReason{" + + "id=" + id + + '}'; + } +}