diff --git a/src/main/java/net/hypixel/modapi/HypixelModAPI.java b/src/main/java/net/hypixel/modapi/HypixelModAPI.java index 0f3ca0e..389e3de 100644 --- a/src/main/java/net/hypixel/modapi/HypixelModAPI.java +++ b/src/main/java/net/hypixel/modapi/HypixelModAPI.java @@ -16,6 +16,7 @@ import net.hypixel.modapi.serializer.PacketSerializer; import java.util.List; +import java.util.Optional; import java.util.concurrent.CopyOnWriteArrayList; public class HypixelModAPI { @@ -65,9 +66,9 @@ public void handle(String identifier, PacketSerializer serializer) { } // 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(identifier, reason); + Optional errorReasonOptional = serializer.readOptional(PacketSerializer::readVarInt).map(ErrorReason::getById); + if (errorReasonOptional.isPresent()) { + throw new ModAPIException(identifier, errorReasonOptional.get()); } ClientboundHypixelPacket packet = registry.createClientboundPacket(identifier, serializer); 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 8817ab2..3620ded 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 @@ -41,10 +41,10 @@ public ClientboundLocationPacket(PacketSerializer serializer) { this.environment = Environment.getById(serializer.readVarInt()).orElseThrow(() -> new IllegalArgumentException("Invalid environment ID")); this.proxyName = serializer.readString(); this.serverName = serializer.readString(); - this.serverType = serializer.readBoolean() ? ServerType.valueOf(serializer.readString()).orElse(null) : null; - this.lobbyName = serializer.readBoolean() ? serializer.readString() : null; - this.mode = serializer.readBoolean() ? serializer.readString() : null; - this.map = serializer.readBoolean() ? serializer.readString() : null; + this.serverType = serializer.readOptional(PacketSerializer::readString).flatMap(ServerType::valueOf).orElse(null); + this.lobbyName = serializer.readOptionally(PacketSerializer::readString); + this.mode = serializer.readOptionally(PacketSerializer::readString); + this.map = serializer.readOptionally(PacketSerializer::readString); } @Override @@ -53,26 +53,10 @@ public void write(PacketSerializer serializer) { serializer.writeVarInt(environment.ordinal()); serializer.writeString(proxyName); serializer.writeString(serverName); - - serializer.writeBoolean(serverType != null); - if (serverType != null) { - serializer.writeString(serverType.name()); - } - - serializer.writeBoolean(lobbyName != null); - if (lobbyName != null) { - serializer.writeString(lobbyName); - } - - serializer.writeBoolean(mode != null); - if (mode != null) { - serializer.writeString(mode); - } - - serializer.writeBoolean(map != null); - if (map != null) { - serializer.writeString(map); - } + serializer.writeOptionally(serverType, (s, t) -> s.writeString(t.name())); + serializer.writeOptionally(lobbyName, PacketSerializer::writeString); + serializer.writeOptionally(mode, PacketSerializer::writeString); + serializer.writeOptionally(map, PacketSerializer::writeString); } @Override 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 ec1f4c8..17f8acb 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 @@ -33,7 +33,7 @@ public ClientboundPlayerInfoPacket(PacketSerializer serializer) { this.playerRank = PlayerRank.getById(serializer.readVarInt()).orElseThrow(() -> new IllegalArgumentException("Invalid player rank ID")); this.packageRank = PackageRank.getById(serializer.readVarInt()).orElseThrow(() -> new IllegalArgumentException("Invalid package rank ID")); this.monthlyPackageRank = MonthlyPackageRank.getById(serializer.readVarInt()).orElseThrow(() -> new IllegalArgumentException("Invalid monthly package rank ID")); - this.prefix = serializer.readBoolean() ? serializer.readString() : null; + this.prefix = serializer.readOptionally(PacketSerializer::readString); } @Override @@ -42,10 +42,7 @@ public void write(PacketSerializer serializer) { serializer.writeVarInt(playerRank.getId()); serializer.writeVarInt(packageRank.getId()); serializer.writeVarInt(monthlyPackageRank.getId()); - serializer.writeBoolean(prefix != null); - if (prefix != null) { - serializer.writeString(prefix); - } + serializer.writeOptionally(prefix, PacketSerializer::writeString); } @Override diff --git a/src/main/java/net/hypixel/modapi/serializer/PacketSerializer.java b/src/main/java/net/hypixel/modapi/serializer/PacketSerializer.java index 9491d2a..a8881c7 100644 --- a/src/main/java/net/hypixel/modapi/serializer/PacketSerializer.java +++ b/src/main/java/net/hypixel/modapi/serializer/PacketSerializer.java @@ -4,8 +4,12 @@ import io.netty.handler.codec.DecoderException; import io.netty.handler.codec.EncoderException; import io.netty.util.CharsetUtil; +import org.jetbrains.annotations.Nullable; +import java.util.Optional; import java.util.UUID; +import java.util.function.BiConsumer; +import java.util.function.Function; public class PacketSerializer { private static final int MAX_BYTES_PER_CHAR_UTF8 = (int) CharsetUtil.getEncoder(CharsetUtil.UTF_8).maxBytesPerChar(); @@ -135,4 +139,25 @@ public PacketSerializer writeUuid(UUID uuid) { return this; } + public Optional readOptional(Function function) { + return this.readBoolean() ? Optional.of(function.apply(this)) : Optional.empty(); + } + + @Nullable + public T readOptionally(Function function) { + return this.readBoolean() ? function.apply(this) : null; + } + + public PacketSerializer writeOptional(Optional optional, BiConsumer consumer) { + return writeOptionally(optional.orElse(null), consumer); + } + + public PacketSerializer writeOptionally(@Nullable T value, BiConsumer consumer) { + this.writeBoolean(value != null); + if (value != null) { + consumer.accept(this, value); + } + return this; + } + }