From dbf701feb19c273a96f84d5f30668a786b8595da Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Fri, 28 Mar 2025 21:16:03 +0100 Subject: [PATCH] Merchant changes, implement splash_potion entity type, some xp orb fixes --- .../geyser/entity/EntityDefinitions.java | 1 + .../geysermc/geyser/entity/type/Entity.java | 2 +- .../geyser/entity/type/ExpOrbEntity.java | 10 ++----- .../geyser/inventory/MerchantContainer.java | 8 +++--- .../geyser/item/hashing/RegistryHasher.java | 2 +- .../org/geysermc/geyser/item/type/Item.java | 9 +++--- .../JavaMerchantOffersTranslator.java | 7 +++-- .../network/ScoreboardIssueTests.java | 28 ------------------- gradle/libs.versions.toml | 2 +- 9 files changed, 19 insertions(+), 50 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java index 242bf2ffb..5703ea475 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java @@ -345,6 +345,7 @@ public final class EntityDefinitions { .build(); EXPERIENCE_ORB = EntityDefinition.inherited(ExpOrbEntity::new, entityBase) .type(EntityType.EXPERIENCE_ORB) + .addTranslator(null) // int determining xb orb texture .identifier("minecraft:xp_orb") .build(); EVOKER_FANGS = EntityDefinition.inherited(EvokerFangsEntity::new, entityBase) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java b/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java index eac070327..f8eafb5d7 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java @@ -435,7 +435,7 @@ public class Entity implements GeyserEntity { } public String teamIdentifier() { - // experience orbs are the only known entities that do not send an uuid (even though they do have one), + // experience orbs were the only known entities that do not send an uuid pre 1.21.5 (even though they do have one), // but to be safe in the future it's done in the entity class itself instead of the entity specific one. // All entities without an uuid cannot show up in the scoreboard! return uuid != null ? uuid.toString() : null; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ExpOrbEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ExpOrbEntity.java index 9f61bc961..8cca969b1 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ExpOrbEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ExpOrbEntity.java @@ -28,7 +28,6 @@ package org.geysermc.geyser.entity.type; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; -import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.session.GeyserSession; import java.util.UUID; @@ -36,12 +35,7 @@ import java.util.UUID; public class ExpOrbEntity extends Entity { public ExpOrbEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition entityDefinition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { - this(session, 1, entityId, geyserId, position); - } - - public ExpOrbEntity(GeyserSession session, int amount, int entityId, long geyserId, Vector3f position) { - super(session, entityId, geyserId, null, EntityDefinitions.EXPERIENCE_ORB, position, Vector3f.ZERO, 0, 0, 0); - - this.dirtyMetadata.put(EntityDataTypes.TRADE_EXPERIENCE, amount); + super(session, entityId, geyserId, uuid, entityDefinition, position, motion, yaw, pitch, headYaw); + this.dirtyMetadata.put(EntityDataTypes.TRADE_EXPERIENCE, 1); } } diff --git a/core/src/main/java/org/geysermc/geyser/inventory/MerchantContainer.java b/core/src/main/java/org/geysermc/geyser/inventory/MerchantContainer.java index 631b73936..156d5e691 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/MerchantContainer.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/MerchantContainer.java @@ -36,14 +36,14 @@ import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.inventory.C import java.util.List; +@Setter public class MerchantContainer extends Container { - @Getter @Setter + @Getter private Entity villager; - @Setter private List villagerTrades; - @Getter @Setter + @Getter private ClientboundMerchantOffersPacket pendingOffersPacket; - @Getter @Setter + @Getter private int tradeExperience; public MerchantContainer(String title, int id, int size, ContainerType containerType, PlayerInventory playerInventory) { diff --git a/core/src/main/java/org/geysermc/geyser/item/hashing/RegistryHasher.java b/core/src/main/java/org/geysermc/geyser/item/hashing/RegistryHasher.java index 4b38bfaad..a0ddf7504 100644 --- a/core/src/main/java/org/geysermc/geyser/item/hashing/RegistryHasher.java +++ b/core/src/main/java/org/geysermc/geyser/item/hashing/RegistryHasher.java @@ -160,7 +160,7 @@ public interface RegistryHasher extends MinecraftHasher { // Encode as a single element if the list only has one element MinecraftHasher ADVENTURE_MODE_PREDICATE = MinecraftHasher.either(BLOCK_PREDICATE, - predicate -> predicate.getPredicates().size() == 1 ? predicate.getPredicates().getFirst() : null, BLOCK_PREDICATE.list(), AdventureModePredicate::getPredicates); + predicate -> predicate.getPredicates().size() == 1 ? predicate.getPredicates().get(0) : null, BLOCK_PREDICATE.list(), AdventureModePredicate::getPredicates); MinecraftHasher ATTRIBUTE_MODIFIER_OPERATION = MinecraftHasher.fromEnum(operation -> switch (operation) { case ADD -> "add_value"; diff --git a/core/src/main/java/org/geysermc/geyser/item/type/Item.java b/core/src/main/java/org/geysermc/geyser/item/type/Item.java index a2fc567d1..bf8d4786e 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/Item.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/Item.java @@ -272,11 +272,10 @@ public class Item { } protected final void translateDyedColor(DataComponents components, BedrockItemBuilder builder) { - // TODO 1.21.5 -// DyedItemColor dyedItemColor = components.get(DataComponentTypes.DYED_COLOR); -// if (dyedItemColor != null) { -// builder.putInt("customColor", dyedItemColor.getRgb()); -// } + Integer dyedItemColor = components.get(DataComponentTypes.DYED_COLOR); + if (dyedItemColor != null) { + builder.putInt("customColor", dyedItemColor); + } } /** diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaMerchantOffersTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaMerchantOffersTranslator.java index 8a06698c0..59e74c06c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaMerchantOffersTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaMerchantOffersTranslator.java @@ -27,6 +27,7 @@ package org.geysermc.geyser.translator.protocol.java.inventory; import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import org.geysermc.mcprotocollib.protocol.data.game.inventory.VillagerTrade; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.inventory.ClientboundMerchantOffersPacket; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; @@ -159,8 +160,10 @@ public class JavaMerchantOffersTranslator extends PacketTranslator#5075 -// */ -// @Test -// void entityWithoutUuid() { -// // experience orbs are the only known entities without an uuid, see Entity#teamIdentifier for more info -// mockContextScoreboard(context -> { -// var addExperienceOrbTranslator = new JavaAddExperienceOrbTranslator(); -// var removeEntitiesTranslator = new JavaRemoveEntitiesTranslator(); -// -// // Entity#teamIdentifier used to throw because it returned uuid.toString where uuid could be null. -// // this would result in both EntityCache#spawnEntity and EntityCache#removeEntity throwing an exception, -// // because the entity would be registered and deregistered to the scoreboard. -// assertDoesNotThrow(() -> { -// context.translate(addExperienceOrbTranslator, new ClientboundAddExperienceOrbPacket(2, 0, 0, 0, 1)); -// -// String displayName = context.mockOrSpy(EntityCache.class).getEntityByJavaId(2).getDisplayName(); -// assertEquals("entity.minecraft.experience_orb", displayName); -// -// context.translate(removeEntitiesTranslator, new ClientboundRemoveEntitiesPacket(new int[] { 2 })); -// }); -// -// // we know that spawning and removing the entity should be fine -// assertNextPacketType(context, AddEntityPacket.class); -// assertNextPacketType(context, RemoveEntityPacket.class); -// }); -// } /** * Test for #5078 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index aece973bb..60499fcd5 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ protocol-common = "3.0.0.Beta6-20250324.162731-5" protocol-codec = "3.0.0.Beta6-20250324.162731-5" raknet = "1.0.0.CR3-20250218.160705-18" minecraftauth = "4.1.1" -mcprotocollib = "1.21.5-20250328.173210-19" +mcprotocollib = "1.21.5-20250328.175415-20" adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2"