From a41d705c42eeaa00789c5633448fc7de46c9f69a Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Sun, 8 Dec 2024 04:18:07 +0800 Subject: [PATCH] Some minor fixes, fix own block breaking progress not showing on the player's end --- .../geyser/entity/EntityDefinitions.java | 4 +- .../living/animal/tameable/WolfEntity.java | 9 ++-- .../type/living/monster/CreakingEntity.java | 21 +++++++--- .../updater/AnvilInventoryUpdater.java | 6 +-- .../geyser/session/cache/TagCache.java | 31 ++++++++++++++ .../session/cache/tags/GeyserHolderSet.java | 22 ---------- .../player/input/BedrockBlockActions.java | 4 +- .../java/JavaSelectKnownPacksTranslator.java | 2 +- .../entity/JavaEntityEventTranslator.java | 3 ++ .../level/JavaBlockDestructionTranslator.java | 7 +++- .../org/geysermc/geyser/util/BlockUtils.java | 41 +++++++------------ 11 files changed, 79 insertions(+), 71 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 d284cba3f..dab8cb6e7 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java @@ -685,13 +685,13 @@ public final class EntityDefinitions { .addTranslator(MetadataType.BOOLEAN, CreakingEntity::setIsTearingDown) .addTranslator(MetadataType.OPTIONAL_POSITION, CreakingEntity::setHomePos) .properties(new GeyserEntityProperties.Builder() - .addEnum("minecraft:creaking_state", + .addEnum(CreakingEntity.CREAKING_STATE, "neutral", "hostile_observed", "hostile_unobserved", "twitching", "crumbling") - .addInt("minecraft:creaking_swaying_ticks", 0, 6) + .addInt(CreakingEntity.CREAKING_SWAYING_TICKS, 0, 6) .build()) .build(); CREEPER = EntityDefinition.inherited(CreeperEntity::new, mobEntityBase) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java index 67e5788c6..1b06f3860 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java @@ -38,8 +38,6 @@ import org.geysermc.geyser.item.enchantment.EnchantmentComponent; import org.geysermc.geyser.item.type.DyeItem; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.session.cache.registry.JavaRegistries; -import org.geysermc.geyser.session.cache.tags.GeyserHolderSet; import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.session.cache.tags.Tag; import org.geysermc.geyser.util.InteractionResult; @@ -62,7 +60,7 @@ import java.util.UUID; public class WolfEntity extends TameableEntity { private byte collarColor = 14; // Red - default - private GeyserHolderSet repairableItems = null; + private HolderSet repairableItems = null; private boolean isCurseOfBinding = false; public WolfEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { @@ -130,8 +128,7 @@ public class WolfEntity extends TameableEntity { public void setBody(ItemStack stack) { super.setBody(stack); isCurseOfBinding = ItemUtils.hasEffect(session, stack, EnchantmentComponent.PREVENT_ARMOR_CHANGE); - HolderSet set = GeyserItemStack.from(stack).getComponent(DataComponentType.REPAIRABLE); - repairableItems = GeyserHolderSet.convertHolderSet(JavaRegistries.ITEM, set); + repairableItems = GeyserItemStack.from(stack).getComponent(DataComponentType.REPAIRABLE); } @Override @@ -166,7 +163,7 @@ public class WolfEntity extends TameableEntity { return InteractiveTag.REMOVE_WOLF_ARMOR; } if (getFlag(EntityFlag.SITTING) && - session.getTagCache().is(repairableItems, itemInHand.asItem()) && + session.getTagCache().isItem(repairableItems, itemInHand.asItem()) && this.body.isValid() && this.body.getTag() != null && this.body.getTag().getInt("Damage") > 0) { return InteractiveTag.REPAIR_WOLF_ARMOR; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/CreakingEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/CreakingEntity.java index a1861ca69..1f2ddc37c 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/CreakingEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/CreakingEntity.java @@ -41,10 +41,21 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.MetadataTyp import java.util.Optional; import java.util.UUID; +/* + * Relevant bits: + * - LevelSoundEvent2Packet(sound=SPAWN, position=(233.5, 112.295, 4717.5), extraData=-1, identifier=minecraft:creaking, babySound=false, relativeVolumeDisabled=false) + * - [11:29:34:768] [CLIENT BOUND] - LevelSoundEvent2Packet(sound=CREAKING_HEART_SPAWN, position=(233.0, 110.0, 4717.0), extraData=-1, identifier=minecraft:creaking, babySound=false, relativeVolumeDisabled=false) + * - [11:29:34:768] [CLIENT BOUND] - LevelSoundEvent2Packet(sound=CREAKING_HEART_SPAWN, position=(235.0, 113.0, 4722.0), extraData=13734, identifier=, babySound=false, relativeVolumeDisabled=false) + * - [11:29:34:768] [CLIENT BOUND] - LevelEventPacket(type=PARTICLE_MOB_BLOCK_SPAWN, position=(233.0, 110.0, 4717.0), data=769) + * + */ public class CreakingEntity extends MonsterEntity { private Vector3i homePosition; + public static final String CREAKING_STATE = "minecraft:creaking_state"; + public static final String CREAKING_SWAYING_TICKS = "minecraft:creaking_swaying_ticks"; + public CreakingEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); } @@ -58,7 +69,7 @@ public class CreakingEntity extends MonsterEntity { @Override public void addAdditionalSpawnData(AddEntityPacket addEntityPacket) { - propertyManager.add("minecraft:creaking_state", "neutral"); + propertyManager.add(CREAKING_STATE, "neutral"); propertyManager.add("minecraft:creaking_swaying_ticks", 0); propertyManager.applyIntProperties(addEntityPacket.getProperties().getIntProperties()); } @@ -68,11 +79,11 @@ public class CreakingEntity extends MonsterEntity { setFlag(EntityFlag.BODY_ROTATION_BLOCKED, false); // unfreeze sound? SoundEvent.UNFREEZE - propertyManager.add("minecraft:creaking_state", "hostile_unobserved"); + propertyManager.add(CREAKING_STATE, "hostile_unobserved"); updateBedrockEntityProperties(); } else { setFlag(EntityFlag.BODY_ROTATION_BLOCKED, true); - propertyManager.add("minecraft:creaking_state", "hostile_observed"); + propertyManager.add(CREAKING_STATE, "hostile_observed"); updateBedrockEntityProperties(); } @@ -92,7 +103,7 @@ public class CreakingEntity extends MonsterEntity { // setFlag(EntityFlag.HIDDEN_WHEN_INVISIBLE, true); // setFlag(EntityFlag.BODY_ROTATION_BLOCKED, true); } else { - propertyManager.add("minecraft:creaking_state", "neutral"); + propertyManager.add(CREAKING_STATE, "neutral"); } GeyserImpl.getInstance().getLogger().warning("set active; " + booleanEntityMetadata.toString()); } @@ -100,7 +111,7 @@ public class CreakingEntity extends MonsterEntity { public void setIsTearingDown(EntityMetadata> booleanEntityMetadata) { GeyserImpl.getInstance().getLogger().warning("set isTearingDown; " + booleanEntityMetadata.toString()); if (booleanEntityMetadata.getValue()) { - propertyManager.add("minecraft:creaking_state", "crumbling"); + propertyManager.add(CREAKING_STATE, "crumbling"); updateBedrockEntityProperties(); // LevelEventPacket levelEventPacket = new LevelEventPacket(); // levelEventPacket.setType(ParticleType.CREAKING_CRUMBLE); diff --git a/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java b/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java index 459d8adf8..3ea78a942 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java @@ -40,10 +40,7 @@ import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.item.BedrockEnchantment; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.enchantment.Enchantment; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.session.cache.registry.JavaRegistries; -import org.geysermc.geyser.session.cache.tags.GeyserHolderSet; import org.geysermc.geyser.translator.inventory.InventoryTranslator; import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; @@ -403,8 +400,7 @@ public class AnvilInventoryUpdater extends InventoryUpdater { return false; } - GeyserHolderSet set = GeyserHolderSet.convertHolderSet(JavaRegistries.ITEM, repairable); - return session.getTagCache().is(set, material.asItem()); + return session.getTagCache().isItem(repairable, material.asItem()); } private boolean isRenaming(GeyserSession session, AnvilContainer anvilContainer, boolean bedrock) { diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java index 26b6aad96..c77081eb0 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java @@ -28,16 +28,19 @@ package org.geysermc.geyser.session.cache; import it.unimi.dsi.fastutil.ints.IntArrays; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import net.kyori.adventure.key.Key; +import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.GeyserLogger; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.type.Item; +import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.registry.JavaRegistries; import org.geysermc.geyser.session.cache.registry.JavaRegistryKey; import org.geysermc.geyser.session.cache.tags.GeyserHolderSet; import org.geysermc.geyser.session.cache.tags.Tag; import org.geysermc.geyser.util.MinecraftKey; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.HolderSet; import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundUpdateTagsPacket; import javax.annotation.ParametersAreNonnullByDefault; @@ -127,6 +130,34 @@ public final class TagCache { return contains(holderSet.resolveRaw(this), holderSet.getRegistry().toNetworkId(session, object)); } + /** + * Accessible via the {@link #isItem(HolderSet, Item)} method. + * @return true if the specified network ID is in the given {@link HolderSet} set. + */ + private boolean is(@Nullable HolderSet holderSet, @NonNull JavaRegistryKey registry, int id) { + if (holderSet == null) { + return false; + } + + int[] entries = holderSet.resolve(key -> { + if (key.value().startsWith("#")) { + key = Key.key(key.namespace(), key.value().substring(1)); + } + return getRaw(new Tag<>(registry, key)); + }); + + return contains(entries, id); + } + + public boolean isItem(@Nullable HolderSet holderSet, @NonNull Item item) { + return is(holderSet, JavaRegistries.ITEM, item.javaId()); + } + + public boolean isBlock(@Nullable HolderSet holderSet, @NonNull Block block) { + return is(holderSet, JavaRegistries.BLOCK, block.javaId()); + } + + public List get(Tag tag) { return mapRawArray(session, getRaw(tag), tag.registry()); } diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/tags/GeyserHolderSet.java b/core/src/main/java/org/geysermc/geyser/session/cache/tags/GeyserHolderSet.java index 0e0d117a4..c77f0a642 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/tags/GeyserHolderSet.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/tags/GeyserHolderSet.java @@ -33,7 +33,6 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.TagCache; import org.geysermc.geyser.session.cache.registry.JavaRegistryKey; -import org.geysermc.mcprotocollib.protocol.data.game.item.component.HolderSet; import java.util.List; import java.util.Objects; @@ -88,27 +87,6 @@ public final class GeyserHolderSet { return tagCache.getRaw(Objects.requireNonNull(tag, "HolderSet must have a tag if it doesn't have a list of IDs")); } - /** - * Reads a MCPL {@link HolderSet} and turns it into a GeyserHolderSet. - * @param registry the registry the HolderSet contains IDs from. - * @param holderSet the HolderSet as the MCPL HolderSet object - */ - public static GeyserHolderSet convertHolderSet(@NonNull JavaRegistryKey registry, @Nullable HolderSet holderSet) { - if (holderSet == null) { - return new GeyserHolderSet<>(registry, IntArrays.EMPTY_ARRAY); - } - - if (holderSet.getHolders() != null) { - return new GeyserHolderSet<>(registry, holderSet.getHolders()); - } - - if (holderSet.getLocation() != null) { - return new GeyserHolderSet<>(registry, new Tag<>(registry, holderSet.getLocation())); - } - - throw new IllegalStateException("HolderSet must have a tag or a list of IDs! " + holderSet); - } - /** * Reads a HolderSet from an object from NBT. * diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/input/BedrockBlockActions.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/input/BedrockBlockActions.java index ea386ebcf..b8facaa10 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/input/BedrockBlockActions.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/input/BedrockBlockActions.java @@ -89,7 +89,7 @@ final class BedrockBlockActions { LevelEventPacket startBreak = new LevelEventPacket(); startBreak.setType(LevelEvent.BLOCK_START_BREAK); startBreak.setPosition(vector.toFloat()); - double breakTime = BlockUtils.getSessionBreakTime(session, BlockState.of(blockState).block()) * 20; // TODO afdaöwelfunöwoaenf + double breakTime = BlockUtils.getSessionBreakTimeTicks(session, BlockState.of(blockState).block()); // If the block is custom or the breaking item is custom, we must keep track of break time ourselves GeyserItemStack item = session.getPlayerInventory().getItemInHand(); @@ -137,7 +137,7 @@ final class BedrockBlockActions { Direction direction = Direction.VALUES[blockFace]; spawnBlockBreakParticles(session, direction, vector, breakingBlockState); - double breakTime = BlockUtils.getSessionBreakTime(session, breakingBlockState.block()) * 20; + double breakTime = BlockUtils.getSessionBreakTimeTicks(session, breakingBlockState.block()); // If the block is custom, we must keep track of when it should break ourselves long blockBreakStartTime = session.getBlockBreakStartTime(); if (blockBreakStartTime != 0) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaSelectKnownPacksTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaSelectKnownPacksTranslator.java index 67717febb..f2ab22e60 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaSelectKnownPacksTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaSelectKnownPacksTranslator.java @@ -40,7 +40,7 @@ import java.util.Set; @Translator(packet = ClientboundSelectKnownPacks.class) public class JavaSelectKnownPacksTranslator extends PacketTranslator { // todo: dump from client? - private static final Set KNOWN_PACK_IDS = Set.of("core", "winter_drop", "trade_rebalance", "redstone_experiments", "minecart_improvements"); + private static final Set KNOWN_PACK_IDS = Set.of("core", "trade_rebalance", "redstone_experiments", "minecart_improvements"); @Override public void translate(GeyserSession session, ClientboundSelectKnownPacks packet) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaEntityEventTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaEntityEventTranslator.java index d52a2b501..504348b5b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaEntityEventTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaEntityEventTranslator.java @@ -37,6 +37,7 @@ import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEvent2Packet; import org.cloudburstmc.protocol.bedrock.packet.PlaySoundPacket; import org.cloudburstmc.protocol.bedrock.packet.SetEntityDataPacket; import org.cloudburstmc.protocol.bedrock.packet.SetEntityMotionPacket; +import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.entity.type.EvokerFangsEntity; @@ -294,6 +295,8 @@ public class JavaEntityEventTranslator extends PacketTranslator set = GeyserHolderSet.convertHolderSet(JavaRegistries.BLOCK, rule.getBlocks()); - if (session.getTagCache().is(set, block)) { + if (session.getTagCache().isBlock(rule.getBlocks(), block)) { return rule.getCorrectForDrops(); } } @@ -84,8 +81,7 @@ public final class BlockUtils { for (ToolData.Rule rule : tool.getRules()) { if (rule.getSpeed() != null) { - GeyserHolderSet set = GeyserHolderSet.convertHolderSet(JavaRegistries.BLOCK, rule.getBlocks()); - if (session.getTagCache().is(set, block)) { + if (session.getTagCache().isBlock(rule.getBlocks(), block)) { return rule.getSpeed(); } } @@ -94,8 +90,8 @@ public final class BlockUtils { return tool.getDefaultMiningSpeed(); } - private static float getPlayerDestroySpeed(GeyserSession session, BlockState blockState, GeyserItemStack itemInHand) { - float destroySpeed = getItemDestroySpeed(session, blockState.block(), itemInHand); + private static float getPlayerDestroySpeed(GeyserSession session, Block block, GeyserItemStack itemInHand) { + float destroySpeed = getItemDestroySpeed(session, block, itemInHand); EntityEffectCache effectCache = session.getEffectCache(); if (destroySpeed > 1.0F) { @@ -133,17 +129,8 @@ public final class BlockUtils { return Math.max(cache.getHaste(), cache.getConduitPower()); } - public int getDestroyStage(GeyserSession session) { - return session.getDestroyProgress() > 0F ? (int) session.getDestroyProgress() * 10 : -1; - } - - // TODO 1.21.4 this changed probably; no more tiers - public static double getBreakTime(GeyserSession session, Block block, ItemMapping item, @Nullable DataComponents components, boolean isSessionPlayer) { - return 0.0; // TODO 1.21.4 - } - - public static double getSessionBreakTime(GeyserSession session, Block block) { - return 0.0; // TODO 1.21.4 + public static double getSessionBreakTimeTicks(GeyserSession session, Block block) { + return Math.ceil(1 / getBlockMiningProgressPerTick(session, block, session.getPlayerInventory().getItemInHand())); } /**