From c1786e28b8a7b220ccbda45811ff0285870aaebb Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Sat, 4 May 2024 00:47:58 -0400 Subject: [PATCH 01/20] Fix ClientboundExplodePacket --- .../clientbound/level/ClientboundExplodePacket.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/level/ClientboundExplodePacket.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/level/ClientboundExplodePacket.java index 86b151d4..f6f50672 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/level/ClientboundExplodePacket.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/level/ClientboundExplodePacket.java @@ -10,6 +10,8 @@ import org.geysermc.mcprotocollib.protocol.codec.MinecraftCodecHelper; import org.geysermc.mcprotocollib.protocol.codec.MinecraftPacket; import org.geysermc.mcprotocollib.protocol.data.game.level.block.ExplosionInteraction; import org.geysermc.mcprotocollib.protocol.data.game.level.particle.Particle; +import org.geysermc.mcprotocollib.protocol.data.game.level.sound.BuiltinSound; +import org.geysermc.mcprotocollib.protocol.data.game.level.sound.CustomSound; import org.geysermc.mcprotocollib.protocol.data.game.level.sound.Sound; import java.util.ArrayList; @@ -49,7 +51,7 @@ public class ClientboundExplodePacket implements MinecraftPacket { this.blockInteraction = ExplosionInteraction.from(helper.readVarInt(in)); // different order than mojang fields this.smallExplosionParticles = helper.readParticle(in); this.largeExplosionParticles = helper.readParticle(in); - this.explosionSound = helper.readSoundEvent(in); + this.explosionSound = helper.readById(in, BuiltinSound::from, helper::readSoundEvent); } @Override @@ -71,6 +73,11 @@ public class ClientboundExplodePacket implements MinecraftPacket { helper.writeVarInt(out, this.blockInteraction.ordinal()); // different order than mojang fields helper.writeParticle(out, this.smallExplosionParticles); helper.writeParticle(out, this.largeExplosionParticles); - helper.writeSoundEvent(out, this.explosionSound); + if (this.explosionSound instanceof CustomSound) { + helper.writeVarInt(out, 0); + helper.writeSoundEvent(out, this.explosionSound); + } else { + helper.writeVarInt(out, ((BuiltinSound) this.explosionSound).ordinal() + 1); + } } } From 1ec8641c1f002f448b527e31cc679c480f3942b8 Mon Sep 17 00:00:00 2001 From: Alex <40795980+AlexProgrammerDE@users.noreply.github.com> Date: Sat, 4 May 2024 07:05:51 +0200 Subject: [PATCH 02/20] Update README.md (#805) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 59de2f31..271e43fa 100644 --- a/README.md +++ b/README.md @@ -85,7 +85,7 @@ You can find the Javadocs for MCProtocolLib [on opencollab](https://ci.opencolla ## Building the Source -MCProtocolLib uses Maven to manage dependencies. To build the source code, run `mvn clean install` in the project root directory. +MCProtocolLib uses Gradle to manage dependencies. To build the source code, run `./gradlew clean build` in the project root directory. ## Support and Development @@ -93,4 +93,4 @@ Please join [the GeyserMC Discord server](https://discord.gg/geysermc) and visit ## License -MCProtocolLib is licensed under the **[MIT license](https://opensource.org/license/mit/)**. +MCProtocolLib is licensed under the **[MIT license](https://opensource.org/license/mit)**. From 1234962b2674fcb0494f1eec0b3a7809111b6885 Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Sun, 5 May 2024 01:36:18 -0400 Subject: [PATCH 03/20] Increase nbt max depth --- .../mcprotocollib/protocol/codec/MinecraftCodecHelper.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/codec/MinecraftCodecHelper.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/codec/MinecraftCodecHelper.java index c0f979b7..b81a095c 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/codec/MinecraftCodecHelper.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/codec/MinecraftCodecHelper.java @@ -252,7 +252,7 @@ public class MinecraftCodecHelper extends BasePacketCodecHelper { NbtType type = NbtType.byId(typeId); - return new NBTInputStream(input).readValue(type); + return new NBTInputStream(input).readValue(type, 512); } catch (IOException e) { throw new IllegalArgumentException(e); } @@ -270,7 +270,7 @@ public class MinecraftCodecHelper extends BasePacketCodecHelper { NbtType type = NbtType.byClass(tag.getClass()); output.writeByte(type.getId()); - new NBTOutputStream(output).writeValue(tag); + new NBTOutputStream(output).writeValue(tag, 512); } catch (IOException e) { throw new IllegalArgumentException(e); } From 31ac6dffcc4780b2dcd56596e33b884242b78d57 Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Mon, 6 May 2024 18:33:25 -0400 Subject: [PATCH 04/20] Fix MobEffectDetails --- .../data/game/item/component/ItemCodecHelper.java | 13 +++++++------ .../data/game/item/component/MobEffectDetails.java | 1 + .../data/game/item/component/PotionContents.java | 5 +++-- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/ItemCodecHelper.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/ItemCodecHelper.java index 1b61fccc..fa7d217f 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/ItemCodecHelper.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/ItemCodecHelper.java @@ -255,10 +255,10 @@ public class ItemCodecHelper extends MinecraftCodecHelper { int potionId = buf.readBoolean() ? this.readVarInt(buf) : -1; int customColor = buf.readBoolean() ? buf.readInt() : -1; - Int2ObjectMap customEffects = new Int2ObjectOpenHashMap<>(); + List customEffects = new ArrayList<>(); int effectCount = this.readVarInt(buf); for (int i = 0; i < effectCount; i++) { - customEffects.put(this.readVarInt(buf), this.readEffectDetails(buf)); + customEffects.add(this.readEffectDetails(buf)); } return new PotionContents(potionId, customColor, customEffects); } @@ -279,9 +279,8 @@ public class ItemCodecHelper extends MinecraftCodecHelper { } this.writeVarInt(buf, contents.getCustomEffects().size()); - for (Int2ObjectMap.Entry entry : contents.getCustomEffects().int2ObjectEntrySet()) { - this.writeVarInt(buf, entry.getIntKey()); - this.writeEffectDetails(buf, entry.getValue()); + for (MobEffectDetails customEffect : contents.getCustomEffects()) { + this.writeEffectDetails(buf, customEffect); } } @@ -314,16 +313,18 @@ public class ItemCodecHelper extends MinecraftCodecHelper { } public MobEffectDetails readEffectDetails(ByteBuf buf) { + int mobEffectId = this.readVarInt(buf); int amplifier = this.readVarInt(buf); int duration = this.readVarInt(buf); boolean ambient = buf.readBoolean(); boolean showParticles = buf.readBoolean(); boolean showIcon = buf.readBoolean(); MobEffectDetails hiddenEffect = this.readNullable(buf, this::readEffectDetails); - return new MobEffectDetails(amplifier, duration, ambient, showParticles, showIcon, hiddenEffect); + return new MobEffectDetails(mobEffectId, amplifier, duration, ambient, showParticles, showIcon, hiddenEffect); } public void writeEffectDetails(ByteBuf buf, MobEffectDetails details) { + this.writeVarInt(buf, details.getMobEffectId()); this.writeVarInt(buf, details.getAmplifier()); this.writeVarInt(buf, details.getDuration()); buf.writeBoolean(details.isAmbient()); diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/MobEffectDetails.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/MobEffectDetails.java index 4669f6cf..ed9c542a 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/MobEffectDetails.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/MobEffectDetails.java @@ -7,6 +7,7 @@ import org.jetbrains.annotations.Nullable; @Data @AllArgsConstructor public class MobEffectDetails { + private final int mobEffectId; private final int amplifier; private final int duration; private final boolean ambient; diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/PotionContents.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/PotionContents.java index b1eab367..e2cb2a73 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/PotionContents.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/PotionContents.java @@ -1,13 +1,14 @@ package org.geysermc.mcprotocollib.protocol.data.game.item.component; -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import lombok.AllArgsConstructor; import lombok.Data; +import java.util.List; + @Data @AllArgsConstructor public class PotionContents { private final int potionId; private final int customColor; - private final Int2ObjectMap customEffects; + private final List customEffects; } From 906da4aa38a999fb3fa27c43b311d1a928506592 Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Mon, 6 May 2024 19:32:46 -0400 Subject: [PATCH 05/20] Bump MCAuthLib --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1e1883ee..24cacf85 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -4,7 +4,7 @@ metadata.format.version = "1.1" adventure = "4.15.0" cloudburstnbt = "3.0.0.Final" -mcauthlib = "6621fd0" +mcauthlib = "e5b0bcc" math = "2.0" fastutil-maps = "8.5.3" netty = "4.1.103.Final" From b48c374428dfb86b63cd33bc4e430abab5ecefba Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Mon, 6 May 2024 21:06:24 -0400 Subject: [PATCH 06/20] Use Effect enum --- .../protocol/data/game/item/component/ItemCodecHelper.java | 7 ++++--- .../data/game/item/component/MobEffectDetails.java | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/ItemCodecHelper.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/ItemCodecHelper.java index fa7d217f..80b76383 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/ItemCodecHelper.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/ItemCodecHelper.java @@ -10,6 +10,7 @@ import org.cloudburstmc.nbt.NbtList; import org.cloudburstmc.nbt.NbtType; import org.geysermc.mcprotocollib.protocol.codec.MinecraftCodecHelper; import org.geysermc.mcprotocollib.protocol.data.game.Holder; +import org.geysermc.mcprotocollib.protocol.data.game.entity.Effect; import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.ModifierOperation; import org.geysermc.mcprotocollib.protocol.data.game.level.sound.BuiltinSound; import org.geysermc.mcprotocollib.protocol.data.game.level.sound.CustomSound; @@ -313,18 +314,18 @@ public class ItemCodecHelper extends MinecraftCodecHelper { } public MobEffectDetails readEffectDetails(ByteBuf buf) { - int mobEffectId = this.readVarInt(buf); + Effect effect = this.readEffect(buf); int amplifier = this.readVarInt(buf); int duration = this.readVarInt(buf); boolean ambient = buf.readBoolean(); boolean showParticles = buf.readBoolean(); boolean showIcon = buf.readBoolean(); MobEffectDetails hiddenEffect = this.readNullable(buf, this::readEffectDetails); - return new MobEffectDetails(mobEffectId, amplifier, duration, ambient, showParticles, showIcon, hiddenEffect); + return new MobEffectDetails(effect, amplifier, duration, ambient, showParticles, showIcon, hiddenEffect); } public void writeEffectDetails(ByteBuf buf, MobEffectDetails details) { - this.writeVarInt(buf, details.getMobEffectId()); + this.writeEffect(buf, details.getEffect()); this.writeVarInt(buf, details.getAmplifier()); this.writeVarInt(buf, details.getDuration()); buf.writeBoolean(details.isAmbient()); diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/MobEffectDetails.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/MobEffectDetails.java index ed9c542a..af918f23 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/MobEffectDetails.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/MobEffectDetails.java @@ -2,12 +2,13 @@ package org.geysermc.mcprotocollib.protocol.data.game.item.component; import lombok.AllArgsConstructor; import lombok.Data; +import org.geysermc.mcprotocollib.protocol.data.game.entity.Effect; import org.jetbrains.annotations.Nullable; @Data @AllArgsConstructor public class MobEffectDetails { - private final int mobEffectId; + private final Effect effect; private final int amplifier; private final int duration; private final boolean ambient; From 42ea4a401d3c68cd86eb8b92f97db9c0aaa36cd2 Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Mon, 6 May 2024 21:25:01 -0400 Subject: [PATCH 07/20] Effect is NonNull --- .../protocol/data/game/item/component/MobEffectDetails.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/MobEffectDetails.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/MobEffectDetails.java index af918f23..2f6e32ef 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/MobEffectDetails.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/MobEffectDetails.java @@ -2,13 +2,14 @@ package org.geysermc.mcprotocollib.protocol.data.game.item.component; import lombok.AllArgsConstructor; import lombok.Data; +import lombok.NonNull; import org.geysermc.mcprotocollib.protocol.data.game.entity.Effect; import org.jetbrains.annotations.Nullable; @Data @AllArgsConstructor public class MobEffectDetails { - private final Effect effect; + private final @NonNull Effect effect; private final int amplifier; private final int duration; private final boolean ambient; From 199de81cb40ac7cdcd2fff7b82d6519030aa6e5b Mon Sep 17 00:00:00 2001 From: Alex <40795980+AlexProgrammerDE@users.noreply.github.com> Date: Wed, 8 May 2024 15:44:49 +0200 Subject: [PATCH 08/20] Add .editorconfig (#801) * Add .editorconfig * Update .editorconfig --- .editorconfig | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..c32bad0c --- /dev/null +++ b/.editorconfig @@ -0,0 +1,14 @@ +root = true + +[*] +charset = utf-8 +indent_size = 4 +indent_style = space +insert_final_newline = true +tab_width = 4 +max_line_length = off + +[*.java] +ij_java_class_count_to_use_import_on_demand = 9999 +ij_java_doc_align_exception_comments = false +ij_java_doc_align_param_comments = false From 96a566f27837dd3fee03f0e8ea17d552d838a11c Mon Sep 17 00:00:00 2001 From: basaigh <53559772+basaigh@users.noreply.github.com> Date: Thu, 9 May 2024 22:22:24 +0100 Subject: [PATCH 09/20] Add missing MapIconType --- .../protocol/data/game/level/map/MapIconType.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/level/map/MapIconType.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/level/map/MapIconType.java index 2b7a8cc9..c06c4f91 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/level/map/MapIconType.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/level/map/MapIconType.java @@ -34,7 +34,8 @@ public enum MapIconType { SNOWY_VILLAGE, TAIGA_VILLAGE, JUNGLE_TEMPLE, - SWAMP_HUT; + SWAMP_HUT, + TRIAL_CHAMBERS; private static final MapIconType[] VALUES = values(); From 98f0582029f03720e1e8a73c3175edc34ff0a963 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Mon, 13 May 2024 22:24:56 -0400 Subject: [PATCH 10/20] Release 1.20.6-1 --- protocol/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol/build.gradle.kts b/protocol/build.gradle.kts index 7ace4fbf..b82f011b 100644 --- a/protocol/build.gradle.kts +++ b/protocol/build.gradle.kts @@ -2,7 +2,7 @@ plugins { id("mcprotocollib.publish-conventions") } -version = "1.20.6-SNAPSHOT" +version = "1.20.6-1" description = "MCProtocolLib is a simple library for communicating with Minecraft clients and servers." dependencies { From 8dbdffc0004746122efd1fbe63d1c1620a8336db Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Mon, 13 May 2024 22:29:24 -0400 Subject: [PATCH 11/20] Fix Javadocs --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 78f18818..1d7a3c6c 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -20,7 +20,7 @@ pipeline { steps { sh './gradlew javadoc' - step([$class: 'JavadocArchiver', javadocDir: 'build/docs/javadoc', keepAll: false]) + step([$class: 'JavadocArchiver', javadocDir: 'protocol/build/docs/javadoc', keepAll: false]) } } } From d5298b3974621563a65f645339c1d4f1d5392304 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Mon, 13 May 2024 22:33:11 -0400 Subject: [PATCH 12/20] Bump to snapshot --- protocol/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol/build.gradle.kts b/protocol/build.gradle.kts index b82f011b..a62786d2 100644 --- a/protocol/build.gradle.kts +++ b/protocol/build.gradle.kts @@ -2,7 +2,7 @@ plugins { id("mcprotocollib.publish-conventions") } -version = "1.20.6-1" +version = "1.20.6-2-SNAPSHOT" description = "MCProtocolLib is a simple library for communicating with Minecraft clients and servers." dependencies { From 115d3d4db2341a4d9c93a0b069ea3d0d9a3747ec Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Wed, 15 May 2024 00:52:26 -0400 Subject: [PATCH 13/20] Add flag to control sending KnownPacksPacket --- .../org/geysermc/mcprotocollib/protocol/ClientListener.java | 6 ++++-- .../geysermc/mcprotocollib/protocol/MinecraftConstants.java | 5 +++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ClientListener.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ClientListener.java index d5929792..198b992f 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ClientListener.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ClientListener.java @@ -45,7 +45,7 @@ import org.geysermc.mcprotocollib.protocol.packet.status.serverbound.Serverbound import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import java.security.NoSuchAlgorithmException; -import java.util.ArrayList; +import java.util.Collections; /** * Handles making initial login and status requests for clients. @@ -136,7 +136,9 @@ public class ClientListener extends SessionAdapter { if (packet instanceof ClientboundFinishConfigurationPacket) { session.send(new ServerboundFinishConfigurationPacket()); } else if (packet instanceof ClientboundSelectKnownPacks) { - session.send(new ServerboundSelectKnownPacks(new ArrayList<>())); + if (session.getFlag(MinecraftConstants.SEND_BLANK_KNOWN_PACKS_RESPONSE, true)) { + session.send(new ServerboundSelectKnownPacks(Collections.emptyList())); + } } else if (packet instanceof ClientboundTransferPacket transferPacket) { TcpClientSession newSession = new TcpClientSession(transferPacket.getHost(), transferPacket.getPort(), session.getPacketProtocol()); newSession.setFlags(session.getFlags()); diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/MinecraftConstants.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/MinecraftConstants.java index 530be182..4bc35db9 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/MinecraftConstants.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/MinecraftConstants.java @@ -50,6 +50,11 @@ public final class MinecraftConstants { */ public static final Flag SERVER_PING_TIME_HANDLER_KEY = new Flag<>("server-ping-time-handler", ServerPingTimeHandler.class); + /** + * Session flag for determining if an automatic response should be sent to the ClientboundSelectKnownPacks. + */ + public static final Flag SEND_BLANK_KNOWN_PACKS_RESPONSE = new Flag<>("send-blank-known-packs-response", Boolean.class); + // Server Key Constants /** From ea95c5d3b23b3bd515bbf60e9668ea6808729654 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Wed, 15 May 2024 01:18:28 -0400 Subject: [PATCH 14/20] Include networkCodec with all feature flags --- protocol/src/main/resources/networkCodec.nbt | Bin 5780 -> 5866 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/protocol/src/main/resources/networkCodec.nbt b/protocol/src/main/resources/networkCodec.nbt index 9b5814f73efd2cd81224104ea425a64e366a2cc3..978d52155a2455404c995d5502f08eb8d82d43bc 100644 GIT binary patch literal 5866 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 S2NVM}5&D03Q(6 Date: Thu, 16 May 2024 20:39:29 +0100 Subject: [PATCH 15/20] Add missing new effects (#815) --- .../mcprotocollib/protocol/data/game/entity/Effect.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/Effect.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/Effect.java index 3b19e54f..1738457b 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/Effect.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/Effect.java @@ -33,7 +33,13 @@ public enum Effect { DOLPHINS_GRACE, BAD_OMEN, HERO_OF_THE_VILLAGE, - DARKNESS; + DARKNESS, + TRIAL_OMEN, + RAID_OMEN, + WIND_CHARGED, + WEAVING, + OOZING, + INFESTED; public static final Effect[] VALUES = values(); From 1b80c1b6ebfb1bd5d7705814ac2c7606283b176b Mon Sep 17 00:00:00 2001 From: Alex <40795980+AlexProgrammerDE@users.noreply.github.com> Date: Thu, 16 May 2024 22:28:23 +0200 Subject: [PATCH 16/20] Fix writing mobeffectinstances (#814) --- .../game/item/component/FoodProperties.java | 2 +- .../game/item/component/ItemCodecHelper.java | 26 ++++++++++++------- .../game/item/component/MobEffectDetails.java | 5 +--- .../item/component/MobEffectInstance.java | 13 ++++++++++ .../game/item/component/PotionContents.java | 2 +- 5 files changed, 33 insertions(+), 15 deletions(-) create mode 100644 protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/MobEffectInstance.java diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/FoodProperties.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/FoodProperties.java index 8a3614ee..ab9f973a 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/FoodProperties.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/FoodProperties.java @@ -17,7 +17,7 @@ public class FoodProperties { @Data @AllArgsConstructor public static class PossibleEffect { - private final MobEffectDetails effect; + private final MobEffectInstance effect; private final float probability; } } diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/ItemCodecHelper.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/ItemCodecHelper.java index 80b76383..e426343c 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/ItemCodecHelper.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/ItemCodecHelper.java @@ -256,10 +256,10 @@ public class ItemCodecHelper extends MinecraftCodecHelper { int potionId = buf.readBoolean() ? this.readVarInt(buf) : -1; int customColor = buf.readBoolean() ? buf.readInt() : -1; - List customEffects = new ArrayList<>(); + List customEffects = new ArrayList<>(); int effectCount = this.readVarInt(buf); for (int i = 0; i < effectCount; i++) { - customEffects.add(this.readEffectDetails(buf)); + customEffects.add(this.readEffectInstance(buf)); } return new PotionContents(potionId, customColor, customEffects); } @@ -280,8 +280,8 @@ public class ItemCodecHelper extends MinecraftCodecHelper { } this.writeVarInt(buf, contents.getCustomEffects().size()); - for (MobEffectDetails customEffect : contents.getCustomEffects()) { - this.writeEffectDetails(buf, customEffect); + for (MobEffectInstance customEffect : contents.getCustomEffects()) { + this.writeEffectInstance(buf, customEffect); } } @@ -294,7 +294,7 @@ public class ItemCodecHelper extends MinecraftCodecHelper { List effects = new ArrayList<>(); int effectCount = this.readVarInt(buf); for (int i = 0; i < effectCount; i++) { - effects.add(new FoodProperties.PossibleEffect(this.readEffectDetails(buf), buf.readFloat())); + effects.add(new FoodProperties.PossibleEffect(this.readEffectInstance(buf), buf.readFloat())); } return new FoodProperties(nutrition, saturationModifier, canAlwaysEat, eatSeconds, effects); @@ -308,24 +308,32 @@ public class ItemCodecHelper extends MinecraftCodecHelper { this.writeVarInt(buf, properties.getEffects().size()); for (FoodProperties.PossibleEffect effect : properties.getEffects()) { - this.writeEffectDetails(buf, effect.getEffect()); + this.writeEffectInstance(buf, effect.getEffect()); buf.writeFloat(effect.getProbability()); } } - public MobEffectDetails readEffectDetails(ByteBuf buf) { + public MobEffectInstance readEffectInstance(ByteBuf buf) { Effect effect = this.readEffect(buf); + return new MobEffectInstance(effect, this.readEffectDetails(buf)); + } + + public MobEffectDetails readEffectDetails(ByteBuf buf) { int amplifier = this.readVarInt(buf); int duration = this.readVarInt(buf); boolean ambient = buf.readBoolean(); boolean showParticles = buf.readBoolean(); boolean showIcon = buf.readBoolean(); MobEffectDetails hiddenEffect = this.readNullable(buf, this::readEffectDetails); - return new MobEffectDetails(effect, amplifier, duration, ambient, showParticles, showIcon, hiddenEffect); + return new MobEffectDetails(amplifier, duration, ambient, showParticles, showIcon, hiddenEffect); + } + + public void writeEffectInstance(ByteBuf buf, MobEffectInstance instance) { + this.writeEffect(buf, instance.getEffect()); + this.writeEffectDetails(buf, instance.getDetails()); } public void writeEffectDetails(ByteBuf buf, MobEffectDetails details) { - this.writeEffect(buf, details.getEffect()); this.writeVarInt(buf, details.getAmplifier()); this.writeVarInt(buf, details.getDuration()); buf.writeBoolean(details.isAmbient()); diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/MobEffectDetails.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/MobEffectDetails.java index 2f6e32ef..29406e78 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/MobEffectDetails.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/MobEffectDetails.java @@ -2,18 +2,15 @@ package org.geysermc.mcprotocollib.protocol.data.game.item.component; import lombok.AllArgsConstructor; import lombok.Data; -import lombok.NonNull; -import org.geysermc.mcprotocollib.protocol.data.game.entity.Effect; import org.jetbrains.annotations.Nullable; @Data @AllArgsConstructor public class MobEffectDetails { - private final @NonNull Effect effect; private final int amplifier; private final int duration; private final boolean ambient; private final boolean showParticles; private final boolean showIcon; private final @Nullable MobEffectDetails hiddenEffect; -} \ No newline at end of file +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/MobEffectInstance.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/MobEffectInstance.java new file mode 100644 index 00000000..9084f146 --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/MobEffectInstance.java @@ -0,0 +1,13 @@ +package org.geysermc.mcprotocollib.protocol.data.game.item.component; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NonNull; +import org.geysermc.mcprotocollib.protocol.data.game.entity.Effect; + +@Data +@AllArgsConstructor +public class MobEffectInstance { + private final @NonNull Effect effect; + private final @NonNull MobEffectDetails details; +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/PotionContents.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/PotionContents.java index e2cb2a73..dd7fbe4e 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/PotionContents.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/PotionContents.java @@ -10,5 +10,5 @@ import java.util.List; public class PotionContents { private final int potionId; private final int customColor; - private final List customEffects; + private final List customEffects; } From 92acb011553a166a63162dd857f89fe25ae73d10 Mon Sep 17 00:00:00 2001 From: Alex <40795980+AlexProgrammerDE@users.noreply.github.com> Date: Fri, 17 May 2024 22:13:05 +0200 Subject: [PATCH 17/20] Implement some serialization better (#812) * Implement some serialization better * Fix buf naming --- .../protocol/codec/MinecraftCodecHelper.java | 17 ++++ .../ClientboundRegistryDataPacket.java | 18 ++--- .../ClientboundSelectKnownPacks.java | 18 ++--- .../ClientboundPlayerChatPacket.java | 16 ++-- .../ClientboundPlayerInfoRemovePacket.java | 12 +-- .../ClientboundPlayerInfoUpdatePacket.java | 15 +--- ...lientboundSelectAdvancementsTabPacket.java | 16 +--- .../ClientboundUpdateAdvancementsPacket.java | 77 +++++++------------ .../level/ClientboundChunksBiomesPacket.java | 21 ++--- .../level/ClientboundExplodePacket.java | 18 ++--- .../level/ClientboundMapItemDataPacket.java | 12 +-- .../serverbound/ServerboundChatPacket.java | 16 ++-- .../inventory/ServerboundEditBookPacket.java | 23 +----- .../ClientboundGameProfilePacket.java | 28 +------ 14 files changed, 97 insertions(+), 210 deletions(-) diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/codec/MinecraftCodecHelper.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/codec/MinecraftCodecHelper.java index b81a095c..90e13554 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/codec/MinecraftCodecHelper.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/codec/MinecraftCodecHelper.java @@ -130,6 +130,23 @@ public class MinecraftCodecHelper extends BasePacketCodecHelper { } } + public List readList(ByteBuf buf, Function reader) { + int size = this.readVarInt(buf); + List list = new ArrayList<>(size); + for (int i = 0; i < size; i++) { + list.add(reader.apply(buf)); + } + + return list; + } + + public void writeList(ByteBuf buf, List value, BiConsumer writer) { + this.writeVarInt(buf, value.size()); + for (T t : value) { + writer.accept(buf, t); + } + } + public Holder readHolder(ByteBuf buf, Function readCustom) { int registryId = this.readVarInt(buf); return registryId == 0 ? Holder.ofCustom(readCustom.apply(buf)) : Holder.ofId(registryId - 1); diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/configuration/clientbound/ClientboundRegistryDataPacket.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/configuration/clientbound/ClientboundRegistryDataPacket.java index d93c14f9..35ff3341 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/configuration/clientbound/ClientboundRegistryDataPacket.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/configuration/clientbound/ClientboundRegistryDataPacket.java @@ -8,7 +8,6 @@ import org.geysermc.mcprotocollib.protocol.codec.MinecraftCodecHelper; import org.geysermc.mcprotocollib.protocol.codec.MinecraftPacket; import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry; -import java.util.ArrayList; import java.util.List; @Data @@ -20,22 +19,15 @@ public class ClientboundRegistryDataPacket implements MinecraftPacket { public ClientboundRegistryDataPacket(ByteBuf in, MinecraftCodecHelper helper) { this.registry = helper.readResourceLocation(in); - this.entries = new ArrayList<>(); - - int entryCount = helper.readVarInt(in); - for (int i = 0; i < entryCount; i++) { - this.entries.add(new RegistryEntry(helper.readResourceLocation(in), helper.readNullable(in, helper::readCompoundTag))); - } + this.entries = helper.readList(in, buf -> new RegistryEntry(helper.readResourceLocation(buf), helper.readNullable(buf, helper::readCompoundTag))); } @Override public void serialize(ByteBuf out, MinecraftCodecHelper helper) { helper.writeResourceLocation(out, this.registry); - - helper.writeVarInt(out, this.entries.size()); - for (RegistryEntry entry : this.entries) { - helper.writeResourceLocation(out, entry.getId()); - helper.writeNullable(out, entry.getData(), helper::writeAnyTag); - } + helper.writeList(out, this.entries, (buf, entry) -> { + helper.writeResourceLocation(buf, entry.getId()); + helper.writeNullable(buf, entry.getData(), helper::writeAnyTag); + }); } } diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/configuration/clientbound/ClientboundSelectKnownPacks.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/configuration/clientbound/ClientboundSelectKnownPacks.java index 17454b05..e5dfa96f 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/configuration/clientbound/ClientboundSelectKnownPacks.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/configuration/clientbound/ClientboundSelectKnownPacks.java @@ -8,7 +8,6 @@ import org.geysermc.mcprotocollib.protocol.codec.MinecraftCodecHelper; import org.geysermc.mcprotocollib.protocol.codec.MinecraftPacket; import org.geysermc.mcprotocollib.protocol.data.game.KnownPack; -import java.util.ArrayList; import java.util.List; @Data @@ -18,20 +17,15 @@ public class ClientboundSelectKnownPacks implements MinecraftPacket { private final List knownPacks; public ClientboundSelectKnownPacks(ByteBuf in, MinecraftCodecHelper helper) { - this.knownPacks = new ArrayList<>(); - int entryCount = helper.readVarInt(in); - for (int i = 0; i < entryCount; i++) { - this.knownPacks.add(new KnownPack(helper.readString(in), helper.readString(in), helper.readString(in))); - } + this.knownPacks = helper.readList(in, buf -> new KnownPack(helper.readString(buf), helper.readString(buf), helper.readString(buf))); } @Override public void serialize(ByteBuf out, MinecraftCodecHelper helper) { - helper.writeVarInt(out, this.knownPacks.size()); - for (KnownPack entry : this.knownPacks) { - helper.writeString(out, entry.getNamespace()); - helper.writeString(out, entry.getId()); - helper.writeString(out, entry.getVersion()); - } + helper.writeList(out, this.knownPacks, (buf, entry) -> { + helper.writeString(buf, entry.getNamespace()); + helper.writeString(buf, entry.getId()); + helper.writeString(buf, entry.getVersion()); + }); } } diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/ClientboundPlayerChatPacket.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/ClientboundPlayerChatPacket.java index bbb5ac29..86be6cc0 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/ClientboundPlayerChatPacket.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/ClientboundPlayerChatPacket.java @@ -39,12 +39,11 @@ public class ClientboundPlayerChatPacket implements MinecraftPacket { public ClientboundPlayerChatPacket(ByteBuf in, MinecraftCodecHelper helper) { this.sender = helper.readUUID(in); this.index = helper.readVarInt(in); - if (in.readBoolean()) { - this.messageSignature = new byte[256]; - in.readBytes(this.messageSignature); - } else { - this.messageSignature = null; - } + this.messageSignature = helper.readNullable(in, buf -> { + byte[] signature = new byte[256]; + buf.readBytes(signature); + return signature; + }); this.content = helper.readString(in, 256); this.timeStamp = in.readLong(); @@ -67,10 +66,7 @@ public class ClientboundPlayerChatPacket implements MinecraftPacket { public void serialize(ByteBuf out, MinecraftCodecHelper helper) { helper.writeUUID(out, this.sender); helper.writeVarInt(out, this.index); - out.writeBoolean(this.messageSignature != null); - if (this.messageSignature != null) { - out.writeBytes(this.messageSignature); - } + helper.writeNullable(out, this.messageSignature, ByteBuf::writeBytes); helper.writeString(out, this.content); out.writeLong(this.timeStamp); diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/ClientboundPlayerInfoRemovePacket.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/ClientboundPlayerInfoRemovePacket.java index a11da043..041534e7 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/ClientboundPlayerInfoRemovePacket.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/ClientboundPlayerInfoRemovePacket.java @@ -7,7 +7,6 @@ import lombok.With; import org.geysermc.mcprotocollib.protocol.codec.MinecraftCodecHelper; import org.geysermc.mcprotocollib.protocol.codec.MinecraftPacket; -import java.util.ArrayList; import java.util.List; import java.util.UUID; @@ -18,17 +17,10 @@ public class ClientboundPlayerInfoRemovePacket implements MinecraftPacket { private final List profileIds; public ClientboundPlayerInfoRemovePacket(ByteBuf in, MinecraftCodecHelper helper) { - this.profileIds = new ArrayList<>(); - int numIds = helper.readVarInt(in); - for (int i = 0; i < numIds; i++) { - this.profileIds.add(helper.readUUID(in)); - } + this.profileIds = helper.readList(in, helper::readUUID); } public void serialize(ByteBuf out, MinecraftCodecHelper helper) { - helper.writeVarInt(out, this.profileIds.size()); - for (UUID id : this.profileIds) { - helper.writeUUID(out, id); - } + helper.writeList(out, this.profileIds, helper::writeUUID); } } diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/ClientboundPlayerInfoUpdatePacket.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/ClientboundPlayerInfoUpdatePacket.java index b3e00716..117b6ada 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/ClientboundPlayerInfoUpdatePacket.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/ClientboundPlayerInfoUpdatePacket.java @@ -16,9 +16,7 @@ import java.security.GeneralSecurityException; import java.security.KeyFactory; import java.security.PublicKey; import java.security.spec.X509EncodedKeySpec; -import java.util.ArrayList; import java.util.EnumSet; -import java.util.List; @Data @With @@ -36,13 +34,7 @@ public class ClientboundPlayerInfoUpdatePacket implements MinecraftPacket { switch (action) { case ADD_PLAYER -> { GameProfile profile = new GameProfile(entry.getProfileId(), helper.readString(in, 16)); - int propertyCount = helper.readVarInt(in); - List propertyList = new ArrayList<>(); - for (int index = 0; index < propertyCount; index++) { - propertyList.add(helper.readProperty(in)); - } - - profile.setProperties(propertyList); + profile.setProperties(helper.readList(in, helper::readProperty)); entry.setProfile(profile); } @@ -104,10 +96,7 @@ public class ClientboundPlayerInfoUpdatePacket implements MinecraftPacket { } helper.writeString(out, profile.getName()); - helper.writeVarInt(out, profile.getProperties().size()); - for (GameProfile.Property property : profile.getProperties()) { - helper.writeProperty(out, property); - } + helper.writeList(out, profile.getProperties(), helper::writeProperty); } case INITIALIZE_CHAT -> { out.writeBoolean(entry.getPublicKey() != null); diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/ClientboundSelectAdvancementsTabPacket.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/ClientboundSelectAdvancementsTabPacket.java index c3e3c94d..a38e24bd 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/ClientboundSelectAdvancementsTabPacket.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/ClientboundSelectAdvancementsTabPacket.java @@ -4,6 +4,7 @@ import io.netty.buffer.ByteBuf; import lombok.AllArgsConstructor; import lombok.Data; import lombok.With; +import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.mcprotocollib.protocol.codec.MinecraftCodecHelper; import org.geysermc.mcprotocollib.protocol.codec.MinecraftPacket; @@ -11,23 +12,14 @@ import org.geysermc.mcprotocollib.protocol.codec.MinecraftPacket; @With @AllArgsConstructor public class ClientboundSelectAdvancementsTabPacket implements MinecraftPacket { - private final String tabId; + private final @Nullable String tabId; public ClientboundSelectAdvancementsTabPacket(ByteBuf in, MinecraftCodecHelper helper) { - if (in.readBoolean()) { - this.tabId = helper.readString(in); - } else { - this.tabId = null; - } + this.tabId = helper.readNullable(in, helper::readString); } @Override public void serialize(ByteBuf out, MinecraftCodecHelper helper) { - if (this.tabId != null) { - out.writeBoolean(true); - helper.writeString(out, this.tabId); - } else { - out.writeBoolean(false); - } + helper.writeNullable(out, this.tabId, helper::writeString); } } diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/ClientboundUpdateAdvancementsPacket.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/ClientboundUpdateAdvancementsPacket.java index 7900bdd9..8293a17c 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/ClientboundUpdateAdvancementsPacket.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/ClientboundUpdateAdvancementsPacket.java @@ -13,7 +13,6 @@ import org.geysermc.mcprotocollib.protocol.data.game.advancement.Advancement.Dis import org.geysermc.mcprotocollib.protocol.data.game.advancement.Advancement.DisplayData.AdvancementType; import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -51,36 +50,25 @@ public class ClientboundUpdateAdvancementsPacket implements MinecraftPacket { for (int i = 0; i < this.advancements.length; i++) { String id = helper.readString(in); String parentId = helper.readNullable(in, helper::readString); - DisplayData displayData = null; - if (in.readBoolean()) { - Component title = helper.readComponent(in); - Component description = helper.readComponent(in); - ItemStack icon = helper.readOptionalItemStack(in); - AdvancementType advancementType = AdvancementType.from(helper.readVarInt(in)); + DisplayData displayData = helper.readNullable(in, buf -> { + Component title = helper.readComponent(buf); + Component description = helper.readComponent(buf); + ItemStack icon = helper.readOptionalItemStack(buf); + AdvancementType advancementType = AdvancementType.from(helper.readVarInt(buf)); - int flags = in.readInt(); + int flags = buf.readInt(); boolean hasBackgroundTexture = (flags & FLAG_HAS_BACKGROUND_TEXTURE) != 0; boolean showToast = (flags & FLAG_SHOW_TOAST) != 0; boolean hidden = (flags & FLAG_HIDDEN) != 0; - String backgroundTexture = hasBackgroundTexture ? helper.readString(in) : null; - float posX = in.readFloat(); - float posY = in.readFloat(); + String backgroundTexture = hasBackgroundTexture ? helper.readString(buf) : null; + float posX = buf.readFloat(); + float posY = buf.readFloat(); - displayData = new DisplayData(title, description, icon, advancementType, showToast, hidden, posX, posY, backgroundTexture); - } + return new DisplayData(title, description, icon, advancementType, showToast, hidden, posX, posY, backgroundTexture); + }); - List> requirements = new ArrayList<>(); - int requirementCount = helper.readVarInt(in); - for (int j = 0; j < requirementCount; j++) { - List requirement = new ArrayList<>(); - int componentCount = helper.readVarInt(in); - for (int k = 0; k < componentCount; k++) { - requirement.add(helper.readString(in)); - } - - requirements.add(requirement); - } + List> requirements = helper.readList(in, buf -> helper.readList(buf, helper::readString)); boolean sendTelemetryEvent = in.readBoolean(); @@ -123,47 +111,36 @@ public class ClientboundUpdateAdvancementsPacket implements MinecraftPacket { out.writeBoolean(false); } - DisplayData displayData = advancement.getDisplayData(); - if (displayData != null) { - out.writeBoolean(true); - helper.writeComponent(out, displayData.getTitle()); - helper.writeComponent(out, displayData.getDescription()); - helper.writeOptionalItemStack(out, displayData.getIcon()); - helper.writeVarInt(out, displayData.getAdvancementType().ordinal()); - String backgroundTexture = displayData.getBackgroundTexture(); + helper.writeNullable(out, advancement.getDisplayData(), (buf, data) -> { + helper.writeComponent(buf, data.getTitle()); + helper.writeComponent(buf, data.getDescription()); + helper.writeOptionalItemStack(buf, data.getIcon()); + helper.writeVarInt(buf, data.getAdvancementType().ordinal()); int flags = 0; - if (backgroundTexture != null) { + if (data.getBackgroundTexture() != null) { flags |= FLAG_HAS_BACKGROUND_TEXTURE; } - if (displayData.isShowToast()) { + if (data.isShowToast()) { flags |= FLAG_SHOW_TOAST; } - if (displayData.isHidden()) { + if (data.isHidden()) { flags |= FLAG_HIDDEN; } - out.writeInt(flags); + buf.writeInt(flags); - if (backgroundTexture != null) { - helper.writeString(out, backgroundTexture); + if (data.getBackgroundTexture() != null) { + helper.writeString(buf, data.getBackgroundTexture()); } - out.writeFloat(displayData.getPosX()); - out.writeFloat(displayData.getPosY()); - } else { - out.writeBoolean(false); - } + buf.writeFloat(data.getPosX()); + buf.writeFloat(data.getPosY()); + }); - helper.writeVarInt(out, advancement.getRequirements().size()); - for (List requirement : advancement.getRequirements()) { - helper.writeVarInt(out, requirement.size()); - for (String criterion : requirement) { - helper.writeString(out, criterion); - } - } + helper.writeList(out, advancement.getRequirements(), (buf, requirement) -> helper.writeList(buf, requirement, helper::writeString)); out.writeBoolean(advancement.isSendsTelemetryEvent()); } diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/level/ClientboundChunksBiomesPacket.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/level/ClientboundChunksBiomesPacket.java index 222d2e7e..6d5a8757 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/level/ClientboundChunksBiomesPacket.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/level/ClientboundChunksBiomesPacket.java @@ -7,7 +7,6 @@ import org.geysermc.mcprotocollib.protocol.codec.MinecraftCodecHelper; import org.geysermc.mcprotocollib.protocol.codec.MinecraftPacket; import org.geysermc.mcprotocollib.protocol.data.game.chunk.ChunkBiomeData; -import java.util.ArrayList; import java.util.List; @Data @@ -16,22 +15,18 @@ public class ClientboundChunksBiomesPacket implements MinecraftPacket { private final List chunkBiomeData; public ClientboundChunksBiomesPacket(ByteBuf in, MinecraftCodecHelper helper) { - this.chunkBiomeData = new ArrayList<>(); - - int length = helper.readVarInt(in); - for (int i = 0; i < length; i++) { - long raw = in.readLong(); - this.chunkBiomeData.add(new ChunkBiomeData((int) raw, (int) (raw >> 32), helper.readByteArray(in))); - } + this.chunkBiomeData = helper.readList(in, buf -> { + long raw = buf.readLong(); + return new ChunkBiomeData((int) raw, (int) (raw >> 32), helper.readByteArray(buf)); + }); } @Override public void serialize(ByteBuf out, MinecraftCodecHelper helper) { - helper.writeVarInt(out, this.chunkBiomeData.size()); - for (ChunkBiomeData entry : this.chunkBiomeData) { + helper.writeList(out, this.chunkBiomeData, (buf, entry) -> { long raw = (long) entry.getX() & 0xFFFFFFFFL | ((long) entry.getZ() & 0xFFFFFFFFL) << 32; - out.writeLong(raw); - helper.writeByteArray(out, entry.getBuffer()); - } + buf.writeLong(raw); + helper.writeByteArray(buf, entry.getBuffer()); + }); } } diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/level/ClientboundExplodePacket.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/level/ClientboundExplodePacket.java index f6f50672..575359ed 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/level/ClientboundExplodePacket.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/level/ClientboundExplodePacket.java @@ -14,7 +14,6 @@ import org.geysermc.mcprotocollib.protocol.data.game.level.sound.BuiltinSound; import org.geysermc.mcprotocollib.protocol.data.game.level.sound.CustomSound; import org.geysermc.mcprotocollib.protocol.data.game.level.sound.Sound; -import java.util.ArrayList; import java.util.List; @Data @@ -39,11 +38,7 @@ public class ClientboundExplodePacket implements MinecraftPacket { this.y = in.readDouble(); this.z = in.readDouble(); this.radius = in.readFloat(); - this.exploded = new ArrayList<>(); - int length = helper.readVarInt(in); - for (int count = 0; count < length; count++) { - this.exploded.add(Vector3i.from(in.readByte(), in.readByte(), in.readByte())); - } + this.exploded = helper.readList(in, buf -> Vector3i.from(buf.readByte(), buf.readByte(), buf.readByte())); this.pushX = in.readFloat(); this.pushY = in.readFloat(); @@ -60,12 +55,11 @@ public class ClientboundExplodePacket implements MinecraftPacket { out.writeDouble(this.y); out.writeDouble(this.z); out.writeFloat(this.radius); - helper.writeVarInt(out, this.exploded.size()); - for (Vector3i record : this.exploded) { - out.writeByte(record.getX()); - out.writeByte(record.getY()); - out.writeByte(record.getZ()); - } + helper.writeList(out, this.exploded, (buf, record) -> { + buf.writeByte(record.getX()); + buf.writeByte(record.getY()); + buf.writeByte(record.getZ()); + }); out.writeFloat(this.pushX); out.writeFloat(this.pushY); diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/level/ClientboundMapItemDataPacket.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/level/ClientboundMapItemDataPacket.java index f6f69595..4837cfdb 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/level/ClientboundMapItemDataPacket.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/level/ClientboundMapItemDataPacket.java @@ -39,10 +39,7 @@ public class ClientboundMapItemDataPacket implements MinecraftPacket { int x = in.readByte(); int z = in.readByte(); int rotation = in.readByte(); - Component displayName = null; - if (in.readBoolean()) { - displayName = helper.readComponent(in); - } + Component displayName = helper.readNullable(in, helper::readComponent); this.icons[index] = new MapIcon(x, z, MapIconType.from(type), rotation, displayName); } @@ -75,12 +72,7 @@ public class ClientboundMapItemDataPacket implements MinecraftPacket { out.writeByte(icon.getCenterX()); out.writeByte(icon.getCenterZ()); out.writeByte(icon.getIconRotation()); - if (icon.getDisplayName() != null) { - out.writeBoolean(true); - helper.writeComponent(out, icon.getDisplayName()); - } else { - out.writeBoolean(false); - } + helper.writeNullable(out, icon.getDisplayName(), helper::writeComponent); } } else { out.writeBoolean(false); diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/serverbound/ServerboundChatPacket.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/serverbound/ServerboundChatPacket.java index e317f0f4..ec0ddaa1 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/serverbound/ServerboundChatPacket.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/serverbound/ServerboundChatPacket.java @@ -26,12 +26,11 @@ public class ServerboundChatPacket implements MinecraftPacket { this.message = helper.readString(in); this.timeStamp = in.readLong(); this.salt = in.readLong(); - if (in.readBoolean()) { - this.signature = new byte[256]; - in.readBytes(this.signature); - } else { - this.signature = null; - } + this.signature = helper.readNullable(in, buf -> { + byte[] signature = new byte[256]; + buf.readBytes(signature); + return signature; + }); this.offset = helper.readVarInt(in); this.acknowledgedMessages = helper.readFixedBitSet(in, 20); @@ -42,10 +41,7 @@ public class ServerboundChatPacket implements MinecraftPacket { helper.writeString(out, this.message); out.writeLong(this.timeStamp); out.writeLong(this.salt); - out.writeBoolean(this.signature != null); - if (this.signature != null) { - out.writeBytes(this.signature); - } + helper.writeNullable(out, this.signature, ByteBuf::writeBytes); helper.writeVarInt(out, this.offset); helper.writeFixedBitSet(out, this.acknowledgedMessages, 20); diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/serverbound/inventory/ServerboundEditBookPacket.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/serverbound/inventory/ServerboundEditBookPacket.java index 154040b4..c80b1200 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/serverbound/inventory/ServerboundEditBookPacket.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/serverbound/inventory/ServerboundEditBookPacket.java @@ -8,7 +8,6 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.mcprotocollib.protocol.codec.MinecraftCodecHelper; import org.geysermc.mcprotocollib.protocol.codec.MinecraftPacket; -import java.util.ArrayList; import java.util.List; @Data @@ -21,28 +20,14 @@ public class ServerboundEditBookPacket implements MinecraftPacket { public ServerboundEditBookPacket(ByteBuf in, MinecraftCodecHelper helper) { this.slot = helper.readVarInt(in); - this.pages = new ArrayList<>(); - int pagesSize = helper.readVarInt(in); - for (int i = 0; i < pagesSize; i++) { - this.pages.add(helper.readString(in)); - } - if (in.readBoolean()) { - this.title = helper.readString(in); - } else { - this.title = null; - } + this.pages = helper.readList(in, helper::readString); + this.title = helper.readNullable(in, helper::readString); } @Override public void serialize(ByteBuf out, MinecraftCodecHelper helper) { helper.writeVarInt(out, slot); - helper.writeVarInt(out, this.pages.size()); - for (String page : this.pages) { - helper.writeString(out, page); - } - out.writeBoolean(this.title != null); - if (this.title != null) { - helper.writeString(out, title); - } + helper.writeList(out, pages, helper::writeString); + helper.writeNullable(out, title, helper::writeString); } } diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/login/clientbound/ClientboundGameProfilePacket.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/login/clientbound/ClientboundGameProfilePacket.java index 2a3cce2f..3d3e528e 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/login/clientbound/ClientboundGameProfilePacket.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/login/clientbound/ClientboundGameProfilePacket.java @@ -9,9 +9,6 @@ import lombok.With; import org.geysermc.mcprotocollib.protocol.codec.MinecraftCodecHelper; import org.geysermc.mcprotocollib.protocol.codec.MinecraftPacket; -import java.util.ArrayList; -import java.util.List; - @Data @With @AllArgsConstructor @@ -21,20 +18,7 @@ public class ClientboundGameProfilePacket implements MinecraftPacket { public ClientboundGameProfilePacket(ByteBuf in, MinecraftCodecHelper helper) { GameProfile profile = new GameProfile(helper.readUUID(in), helper.readString(in)); - int properties = helper.readVarInt(in); - List propertyList = new ArrayList<>(); - for (int index = 0; index < properties; index++) { - String propertyName = helper.readString(in); - String value = helper.readString(in); - String signature = null; - if (in.readBoolean()) { - signature = helper.readString(in); - } - - propertyList.add(new GameProfile.Property(propertyName, value, signature)); - } - - profile.setProperties(propertyList); + profile.setProperties(helper.readList(in, helper::readProperty)); this.profile = profile; this.strictErrorHandling = in.readBoolean(); } @@ -43,15 +27,7 @@ public class ClientboundGameProfilePacket implements MinecraftPacket { public void serialize(ByteBuf out, MinecraftCodecHelper helper) { helper.writeUUID(out, this.profile.getId()); helper.writeString(out, this.profile.getName()); - helper.writeVarInt(out, this.profile.getProperties().size()); - for (GameProfile.Property property : this.profile.getProperties()) { - helper.writeString(out, property.getName()); - helper.writeString(out, property.getValue()); - out.writeBoolean(property.hasSignature()); - if (property.hasSignature()) { - helper.writeString(out, property.getSignature()); - } - } + helper.writeList(out, this.profile.getProperties(), helper::writeProperty); out.writeBoolean(this.strictErrorHandling); } From bfaef4322b1d753c3e0005f0229c3108e7b605c0 Mon Sep 17 00:00:00 2001 From: chris Date: Sat, 18 May 2024 18:23:24 +0200 Subject: [PATCH 18/20] Allow users of the default client listener to decide whether to automatically follow transfer packets (#817) --- .../protocol/ClientListener.java | 20 +++++++++++-------- .../protocol/MinecraftConstants.java | 5 +++++ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ClientListener.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ClientListener.java index 198b992f..5981931e 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ClientListener.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ClientListener.java @@ -127,10 +127,12 @@ public class ClientListener extends SessionAdapter { } else if (packet instanceof ClientboundStartConfigurationPacket) { session.send(new ServerboundConfigurationAcknowledgedPacket()); } else if (packet instanceof ClientboundTransferPacket transferPacket) { - TcpClientSession newSession = new TcpClientSession(transferPacket.getHost(), transferPacket.getPort(), session.getPacketProtocol()); - newSession.setFlags(session.getFlags()); - session.disconnect("Transferring"); - newSession.connect(true, true); + if (session.getFlag(MinecraftConstants.FOLLOW_TRANFERS, true)) { + TcpClientSession newSession = new TcpClientSession(transferPacket.getHost(), transferPacket.getPort(), session.getPacketProtocol()); + newSession.setFlags(session.getFlags()); + session.disconnect("Transferring"); + newSession.connect(true, true); + } } } else if (protocol.getState() == ProtocolState.CONFIGURATION) { if (packet instanceof ClientboundFinishConfigurationPacket) { @@ -140,10 +142,12 @@ public class ClientListener extends SessionAdapter { session.send(new ServerboundSelectKnownPacks(Collections.emptyList())); } } else if (packet instanceof ClientboundTransferPacket transferPacket) { - TcpClientSession newSession = new TcpClientSession(transferPacket.getHost(), transferPacket.getPort(), session.getPacketProtocol()); - newSession.setFlags(session.getFlags()); - session.disconnect("Transferring"); - newSession.connect(true, true); + if (session.getFlag(MinecraftConstants.FOLLOW_TRANFERS, true)) { + TcpClientSession newSession = new TcpClientSession(transferPacket.getHost(), transferPacket.getPort(), session.getPacketProtocol()); + newSession.setFlags(session.getFlags()); + session.disconnect("Transferring"); + newSession.connect(true, true); + } } } } diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/MinecraftConstants.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/MinecraftConstants.java index 4bc35db9..fae29828 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/MinecraftConstants.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/MinecraftConstants.java @@ -55,6 +55,11 @@ public final class MinecraftConstants { */ public static final Flag SEND_BLANK_KNOWN_PACKS_RESPONSE = new Flag<>("send-blank-known-packs-response", Boolean.class); + /** + * Session flag for determining whether to create a new TcpClientSession when the Java server sends a ClientboundTransferPacket. + */ + public static final Flag FOLLOW_TRANFERS = new Flag<>("follow-transfers", Boolean.class); + // Server Key Constants /** From a1b559d20f0b3a3645dcd71ebe827155d0743688 Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Sat, 18 May 2024 20:42:11 +0200 Subject: [PATCH 19/20] fix typo in "FOLLOW_TRANFERS" --- .../org/geysermc/mcprotocollib/protocol/ClientListener.java | 4 ++-- .../geysermc/mcprotocollib/protocol/MinecraftConstants.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ClientListener.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ClientListener.java index 5981931e..5b92d7d5 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ClientListener.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ClientListener.java @@ -127,7 +127,7 @@ public class ClientListener extends SessionAdapter { } else if (packet instanceof ClientboundStartConfigurationPacket) { session.send(new ServerboundConfigurationAcknowledgedPacket()); } else if (packet instanceof ClientboundTransferPacket transferPacket) { - if (session.getFlag(MinecraftConstants.FOLLOW_TRANFERS, true)) { + if (session.getFlag(MinecraftConstants.FOLLOW_TRANSFERS, true)) { TcpClientSession newSession = new TcpClientSession(transferPacket.getHost(), transferPacket.getPort(), session.getPacketProtocol()); newSession.setFlags(session.getFlags()); session.disconnect("Transferring"); @@ -142,7 +142,7 @@ public class ClientListener extends SessionAdapter { session.send(new ServerboundSelectKnownPacks(Collections.emptyList())); } } else if (packet instanceof ClientboundTransferPacket transferPacket) { - if (session.getFlag(MinecraftConstants.FOLLOW_TRANFERS, true)) { + if (session.getFlag(MinecraftConstants.FOLLOW_TRANSFERS, true)) { TcpClientSession newSession = new TcpClientSession(transferPacket.getHost(), transferPacket.getPort(), session.getPacketProtocol()); newSession.setFlags(session.getFlags()); session.disconnect("Transferring"); diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/MinecraftConstants.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/MinecraftConstants.java index fae29828..93505478 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/MinecraftConstants.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/MinecraftConstants.java @@ -58,7 +58,7 @@ public final class MinecraftConstants { /** * Session flag for determining whether to create a new TcpClientSession when the Java server sends a ClientboundTransferPacket. */ - public static final Flag FOLLOW_TRANFERS = new Flag<>("follow-transfers", Boolean.class); + public static final Flag FOLLOW_TRANSFERS = new Flag<>("follow-transfers", Boolean.class); // Server Key Constants From a724a8fdb4853291dfe357b36b5aee3926ab9abd Mon Sep 17 00:00:00 2001 From: Alex <40795980+AlexProgrammerDE@users.noreply.github.com> Date: Mon, 20 May 2024 05:00:22 +0200 Subject: [PATCH 20/20] Implement HolderSet class and cleanup item codec (#818) * Implement HolderSet class and cleanup item codec * Also validate both being set case * Fix equals and hashcode by migrating from a record to a class * Change field names to match vanilla --- .../component/AdventureModePredicate.java | 3 +- .../data/game/item/component/HolderSet.java | 41 +++ .../game/item/component/ItemCodecHelper.java | 253 ++++++------------ .../data/game/item/component/ToolData.java | 4 +- 4 files changed, 133 insertions(+), 168 deletions(-) create mode 100644 protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/HolderSet.java diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/AdventureModePredicate.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/AdventureModePredicate.java index 4b066693..df5a9068 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/AdventureModePredicate.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/AdventureModePredicate.java @@ -16,8 +16,7 @@ public class AdventureModePredicate { @Data @AllArgsConstructor public static class BlockPredicate { - private final @Nullable String location; - private final int @Nullable [] holders; + private final @Nullable HolderSet blocks; private final @Nullable List properties; private final @Nullable NbtMap nbt; } diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/HolderSet.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/HolderSet.java new file mode 100644 index 00000000..d9c45465 --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/HolderSet.java @@ -0,0 +1,41 @@ +package org.geysermc.mcprotocollib.protocol.data.game.item.component; + +import lombok.Data; +import lombok.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.util.function.Function; + +/** + * Represents a set of holders that could either be explicit, or resolved from a tag location. + * The client has to know how to resolve the tag location to get the holders. + */ +@Data +public final class HolderSet { + private final @Nullable String location; + private final int @Nullable [] holders; + + public HolderSet(int @NonNull [] holders) { + this.location = null; + this.holders = holders; + } + + public HolderSet(@NonNull String location) { + this.location = location; + this.holders = null; + } + + /** + * Return either the explicit holders, or resolve the tag location to get the holders. + * + * @param tagResolver The function to resolve the tag location to get the holders. + * @return The holders. + */ + public int[] resolve(Function tagResolver) { + if (holders != null) { + return holders; + } + + return tagResolver.apply(location); + } +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/ItemCodecHelper.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/ItemCodecHelper.java index e426343c..dab86c2b 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/ItemCodecHelper.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/ItemCodecHelper.java @@ -35,21 +35,13 @@ public class ItemCodecHelper extends MinecraftCodecHelper { public Filterable readFilterable(ByteBuf buf, Function reader) { T raw = reader.apply(buf); - T filtered = null; - if (buf.readBoolean()) { - filtered = reader.apply(buf); - } + T filtered = this.readNullable(buf, reader); return new Filterable<>(raw, filtered); } public void writeFilterable(ByteBuf buf, Filterable filterable, BiConsumer writer) { writer.accept(buf, filterable.getRaw()); - if (filterable.getOptional() != null) { - buf.writeBoolean(true); - writer.accept(buf, filterable.getOptional()); - } else { - buf.writeBoolean(false); - } + this.writeNullable(buf, filterable.getOptional(), writer); } public ItemEnchantments readItemEnchantments(ByteBuf buf) { @@ -73,12 +65,7 @@ public class ItemCodecHelper extends MinecraftCodecHelper { } public AdventureModePredicate readAdventureModePredicate(ByteBuf buf) { - List predicates = new ArrayList<>(); - int predicateCount = this.readVarInt(buf); - for (int i = 0; i < predicateCount; i++) { - predicates.add(this.readBlockPredicate(buf)); - } - + List predicates = this.readList(buf, this::readBlockPredicate); return new AdventureModePredicate(predicates, buf.readBoolean()); } @@ -92,59 +79,29 @@ public class ItemCodecHelper extends MinecraftCodecHelper { } public AdventureModePredicate.BlockPredicate readBlockPredicate(ByteBuf buf) { - String location = null; - int[] holders = null; - List propertyMatchers = null; - - if (buf.readBoolean()) { - int length = this.readVarInt(buf) - 1; - if (length == -1) { - location = this.readResourceLocation(buf); - } else { - holders = new int[length]; - for (int i = 0; i < length; i++) { - holders[i] = this.readVarInt(buf); - } - } - } - - if (buf.readBoolean()) { - propertyMatchers = new ArrayList<>(); - int matcherCount = this.readVarInt(buf); + HolderSet holderSet = this.readNullable(buf, this::readHolderSet); + List propertyMatchers = this.readNullable(buf, (input) -> { + List matchers = new ArrayList<>(); + int matcherCount = this.readVarInt(input); for (int i = 0; i < matcherCount; i++) { - String name = this.readString(buf); - if (buf.readBoolean()) { - propertyMatchers.add(new AdventureModePredicate.PropertyMatcher(name, this.readString(buf), null, null)); + String name = this.readString(input); + if (input.readBoolean()) { + matchers.add(new AdventureModePredicate.PropertyMatcher(name, this.readString(input), null, null)); } else { - propertyMatchers.add(new AdventureModePredicate.PropertyMatcher(name, null, this.readString(buf), this.readString(buf))); + matchers.add(new AdventureModePredicate.PropertyMatcher(name, null, this.readString(input), this.readString(input))); } } - } + return matchers; + }); - return new AdventureModePredicate.BlockPredicate(location, holders, propertyMatchers, this.readNullable(buf, this::readCompoundTag)); + return new AdventureModePredicate.BlockPredicate(holderSet, propertyMatchers, this.readNullable(buf, this::readCompoundTag)); } public void writeBlockPredicate(ByteBuf buf, AdventureModePredicate.BlockPredicate blockPredicate) { - if (blockPredicate.getLocation() == null && blockPredicate.getHolders() == null) { - buf.writeBoolean(false); - } else { + this.writeNullable(buf, blockPredicate.getBlocks(), this::writeHolderSet); + this.writeNullable(buf, blockPredicate.getProperties(), (output, properties) -> { buf.writeBoolean(true); - if (blockPredicate.getLocation() != null) { - this.writeVarInt(buf, 0); - this.writeResourceLocation(buf, blockPredicate.getLocation()); - } else { - this.writeVarInt(buf, blockPredicate.getHolders().length + 1); - for (int holder : blockPredicate.getHolders()) { - this.writeVarInt(buf, holder); - } - } - } - - if (blockPredicate.getProperties() == null) { - buf.writeBoolean(false); - } else { - buf.writeBoolean(true); - for (AdventureModePredicate.PropertyMatcher matcher : blockPredicate.getProperties()) { + for (AdventureModePredicate.PropertyMatcher matcher : properties) { this.writeString(buf, matcher.getName()); if (matcher.getValue() != null) { buf.writeBoolean(true); @@ -155,32 +112,46 @@ public class ItemCodecHelper extends MinecraftCodecHelper { this.writeString(buf, matcher.getMaxValue()); } } - } + }); this.writeNullable(buf, blockPredicate.getNbt(), this::writeAnyTag); } - public ToolData readToolData(ByteBuf buf) { - List rules = new ArrayList<>(); - int ruleCount = this.readVarInt(buf); - for (int i = 0; i < ruleCount; i++) { - String location = null; - int[] holders = null; - - int length = this.readVarInt(buf) - 1; - if (length == -1) { - location = this.readResourceLocation(buf); - } else { - holders = new int[length]; - for (int j = 0; j < length; j++) { - holders[j] = this.readVarInt(buf); - } + public HolderSet readHolderSet(ByteBuf buf) { + int length = this.readVarInt(buf) - 1; + if (length == -1) { + return new HolderSet(this.readResourceLocation(buf)); + } else { + int[] holders = new int[length]; + for (int i = 0; i < length; i++) { + holders[i] = this.readVarInt(buf); } - Float speed = this.readNullable(buf, ByteBuf::readFloat); - Boolean correctForDrops = this.readNullable(buf, ByteBuf::readBoolean); - rules.add(new ToolData.Rule(location, holders, speed, correctForDrops)); + return new HolderSet(holders); } + } + + public void writeHolderSet(ByteBuf buf, HolderSet holderSet) { + if (holderSet.getLocation() != null) { + this.writeVarInt(buf, 0); + this.writeResourceLocation(buf, holderSet.getLocation()); + } else { + assert holderSet.getHolders() != null; + this.writeVarInt(buf, holderSet.getHolders().length + 1); + for (int holder : holderSet.getHolders()) { + this.writeVarInt(buf, holder); + } + } + } + + public ToolData readToolData(ByteBuf buf) { + List rules = this.readList(buf, (input) -> { + HolderSet holderSet = this.readHolderSet(input); + + Float speed = this.readNullable(input, ByteBuf::readFloat); + Boolean correctForDrops = this.readNullable(input, ByteBuf::readBoolean); + return new ToolData.Rule(holderSet, speed, correctForDrops); + }); float defaultMiningSpeed = buf.readFloat(); int damagePerBlock = this.readVarInt(buf); @@ -188,57 +159,42 @@ public class ItemCodecHelper extends MinecraftCodecHelper { } public void writeToolData(ByteBuf buf, ToolData data) { - this.writeVarInt(buf, data.getRules().size()); - for (ToolData.Rule rule : data.getRules()) { - if (rule.getLocation() != null) { - this.writeVarInt(buf, 0); - this.writeResourceLocation(buf, rule.getLocation()); - } else { - this.writeVarInt(buf, rule.getHolders().length + 1); - for (int holder : rule.getHolders()) { - this.writeVarInt(buf, holder); - } - } - - this.writeNullable(buf, rule.getSpeed(), ByteBuf::writeFloat); - this.writeNullable(buf, rule.getCorrectForDrops(), ByteBuf::writeBoolean); - } + this.writeList(buf, data.getRules(), (output, rule) -> { + this.writeHolderSet(output, rule.getBlocks()); + this.writeNullable(output, rule.getSpeed(), ByteBuf::writeFloat); + this.writeNullable(output, rule.getCorrectForDrops(), ByteBuf::writeBoolean); + }); buf.writeFloat(data.getDefaultMiningSpeed()); this.writeVarInt(buf, data.getDamagePerBlock()); } public ItemAttributeModifiers readItemAttributeModifiers(ByteBuf buf) { - List modifiers = new ArrayList<>(); - int modifierCount = this.readVarInt(buf); - for (int i = 0; i < modifierCount; i++) { - int attribute = this.readVarInt(buf); + List modifiers = this.readList(buf, (input) -> { + int attribute = this.readVarInt(input); - UUID id = this.readUUID(buf); - String name = this.readString(buf); - double amount = buf.readDouble(); - ModifierOperation operation = ModifierOperation.from(this.readVarInt(buf)); + UUID id = this.readUUID(input); + String name = this.readString(input); + double amount = input.readDouble(); + ModifierOperation operation = ModifierOperation.from(this.readVarInt(input)); ItemAttributeModifiers.AttributeModifier modifier = new ItemAttributeModifiers.AttributeModifier(id, name, amount, operation); - ItemAttributeModifiers.EquipmentSlotGroup slot = ItemAttributeModifiers.EquipmentSlotGroup.from(this.readVarInt(buf)); - modifiers.add(new ItemAttributeModifiers.Entry(attribute, modifier, slot)); - } + ItemAttributeModifiers.EquipmentSlotGroup slot = ItemAttributeModifiers.EquipmentSlotGroup.from(this.readVarInt(input)); + return new ItemAttributeModifiers.Entry(attribute, modifier, slot); + }); return new ItemAttributeModifiers(modifiers, buf.readBoolean()); } public void writeItemAttributeModifiers(ByteBuf buf, ItemAttributeModifiers modifiers) { - this.writeVarInt(buf, modifiers.getModifiers().size()); - for (ItemAttributeModifiers.Entry modifier : modifiers.getModifiers()) { - this.writeVarInt(buf, modifier.getAttribute()); - - this.writeUUID(buf, modifier.getModifier().getId()); - this.writeString(buf, modifier.getModifier().getName()); - buf.writeDouble(modifier.getModifier().getAmount()); - this.writeVarInt(buf, modifier.getModifier().getOperation().ordinal()); - - this.writeVarInt(buf, modifier.getSlot().ordinal()); - } + this.writeList(buf, modifiers.getModifiers(), (output, entry) -> { + this.writeVarInt(output, entry.getAttribute()); + this.writeUUID(output, entry.getModifier().getId()); + this.writeString(output, entry.getModifier().getName()); + output.writeDouble(entry.getModifier().getAmount()); + this.writeVarInt(output, entry.getModifier().getOperation().ordinal()); + this.writeVarInt(output, entry.getSlot().ordinal()); + }); buf.writeBoolean(modifiers.isShowInTooltip()); } @@ -256,11 +212,7 @@ public class ItemCodecHelper extends MinecraftCodecHelper { int potionId = buf.readBoolean() ? this.readVarInt(buf) : -1; int customColor = buf.readBoolean() ? buf.readInt() : -1; - List customEffects = new ArrayList<>(); - int effectCount = this.readVarInt(buf); - for (int i = 0; i < effectCount; i++) { - customEffects.add(this.readEffectInstance(buf)); - } + List customEffects = this.readList(buf, this::readEffectInstance); return new PotionContents(potionId, customColor, customEffects); } @@ -279,10 +231,7 @@ public class ItemCodecHelper extends MinecraftCodecHelper { buf.writeInt(contents.getCustomColor()); } - this.writeVarInt(buf, contents.getCustomEffects().size()); - for (MobEffectInstance customEffect : contents.getCustomEffects()) { - this.writeEffectInstance(buf, customEffect); - } + this.writeList(buf, contents.getCustomEffects(), this::writeEffectInstance); } public FoodProperties readFoodProperties(ByteBuf buf) { @@ -291,11 +240,11 @@ public class ItemCodecHelper extends MinecraftCodecHelper { boolean canAlwaysEat = buf.readBoolean(); float eatSeconds = buf.readFloat(); - List effects = new ArrayList<>(); - int effectCount = this.readVarInt(buf); - for (int i = 0; i < effectCount; i++) { - effects.add(new FoodProperties.PossibleEffect(this.readEffectInstance(buf), buf.readFloat())); - } + List effects = this.readList(buf, (input) -> { + MobEffectInstance effect = this.readEffectInstance(input); + float probability = input.readFloat(); + return new FoodProperties.PossibleEffect(effect, probability); + }); return new FoodProperties(nutrition, saturationModifier, canAlwaysEat, eatSeconds, effects); } @@ -306,11 +255,10 @@ public class ItemCodecHelper extends MinecraftCodecHelper { buf.writeBoolean(properties.isCanAlwaysEat()); buf.writeFloat(properties.getEatSeconds()); - this.writeVarInt(buf, properties.getEffects().size()); - for (FoodProperties.PossibleEffect effect : properties.getEffects()) { - this.writeEffectInstance(buf, effect.getEffect()); - buf.writeFloat(effect.getProbability()); - } + this.writeList(buf, properties.getEffects(), (output, effect) -> { + this.writeEffectInstance(output, effect.getEffect()); + output.writeFloat(effect.getProbability()); + }); } public MobEffectInstance readEffectInstance(ByteBuf buf) { @@ -352,20 +300,12 @@ public class ItemCodecHelper extends MinecraftCodecHelper { } public WritableBookContent readWritableBookContent(ByteBuf buf) { - List> pages = new ArrayList<>(); - int pageCount = this.readVarInt(buf); - for (int i = 0; i < pageCount; i++) { - pages.add(this.readFilterable(buf, this::readString)); - } - + List> pages = this.readList(buf, (input) -> this.readFilterable(input, this::readString)); return new WritableBookContent(pages); } public void writeWritableBookContent(ByteBuf buf, WritableBookContent content) { - this.writeVarInt(buf, content.getPages().size()); - for (Filterable page : content.getPages()) { - this.writeFilterable(buf, page, this::writeString); - } + this.writeList(buf, content.getPages(), (output, page) -> this.writeFilterable(output, page, this::writeString)); } public WrittenBookContent readWrittenBookContent(ByteBuf buf) { @@ -373,12 +313,7 @@ public class ItemCodecHelper extends MinecraftCodecHelper { String author = this.readString(buf); int generation = this.readVarInt(buf); - List> pages = new ArrayList<>(); - int pageCount = this.readVarInt(buf); - for (int i = 0; i < pageCount; i++) { - pages.add(this.readFilterable(buf, this::readComponent)); - } - + List> pages = this.readList(buf, (input) -> this.readFilterable(input, this::readComponent)); boolean resolved = buf.readBoolean(); return new WrittenBookContent(title, author, generation, pages, resolved); } @@ -388,10 +323,7 @@ public class ItemCodecHelper extends MinecraftCodecHelper { this.writeString(buf, content.getAuthor()); this.writeVarInt(buf, content.getGeneration()); - this.writeVarInt(buf, content.getPages().size()); - for (Filterable page : content.getPages()) { - this.writeFilterable(buf, page, this::writeComponent); - } + this.writeList(buf, content.getPages(), (output, page) -> this.writeFilterable(output, page, this::writeComponent)); buf.writeBoolean(content.isResolved()); } @@ -554,11 +486,7 @@ public class ItemCodecHelper extends MinecraftCodecHelper { UUID id = this.readNullable(buf, this::readUUID); GameProfile profile = new GameProfile(id, name); - List properties = new ArrayList<>(); - int propertyCount = this.readVarInt(buf); - for (int i = 0; i < propertyCount; i++) { - properties.add(this.readProperty(buf)); - } + List properties = this.readList(buf, this::readProperty); profile.setProperties(properties); return profile; @@ -568,10 +496,7 @@ public class ItemCodecHelper extends MinecraftCodecHelper { this.writeNullable(buf, profile.getName(), this::writeString); this.writeNullable(buf, profile.getId(), this::writeUUID); - this.writeVarInt(buf, profile.getProperties().size()); - for (GameProfile.Property property : profile.getProperties()) { - this.writeProperty(buf, property); - } + this.writeList(buf, profile.getProperties(), this::writeProperty); } public BannerPatternLayer readBannerPatternLayer(ByteBuf buf) { diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/ToolData.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/ToolData.java index 93891af3..a6312082 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/ToolData.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/ToolData.java @@ -2,6 +2,7 @@ package org.geysermc.mcprotocollib.protocol.data.game.item.component; import lombok.AllArgsConstructor; import lombok.Data; +import lombok.NonNull; import org.jetbrains.annotations.Nullable; import java.util.List; @@ -16,8 +17,7 @@ public class ToolData { @Data @AllArgsConstructor public static class Rule { - private final @Nullable String location; - private final int @Nullable [] holders; + private final @NonNull HolderSet blocks; private final @Nullable Float speed; private final @Nullable Boolean correctForDrops; }