diff --git a/connector/src/main/java/org/geysermc/connector/entity/ItemFrameEntity.java b/connector/src/main/java/org/geysermc/connector/entity/ItemFrameEntity.java index e10ad0afd..79711b0cb 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/ItemFrameEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/ItemFrameEntity.java @@ -35,6 +35,7 @@ import com.nukkitx.nbt.NbtMapBuilder; import com.nukkitx.protocol.bedrock.data.inventory.ItemData; import com.nukkitx.protocol.bedrock.packet.BlockEntityDataPacket; import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket; +import lombok.Getter; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.item.ItemEntry; @@ -69,6 +70,11 @@ public class ItemFrameEntity extends Entity { * Cached item frame's Bedrock compound tag. */ private NbtMap cachedTag; + /** + * The item currently in the item frame. Used for block picking. + */ + @Getter + private ItemStack heldItem = null; public ItemFrameEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation, HangingDirection direction) { super(entityId, geyserId, entityType, position, motion, rotation); @@ -87,7 +93,8 @@ public class ItemFrameEntity extends Entity { bedrockRuntimeId = session.getBlockTranslator().getItemFrame(blockBuilder.build()); bedrockPosition = Vector3i.from(position.getFloorX(), position.getFloorY(), position.getFloorZ()); - session.getItemFrameCache().put(bedrockPosition, entityId); + session.getItemFrameCache().put(bedrockPosition, this); + // Delay is required, or else loading in frames on chunk load is sketchy at best session.getConnector().getGeneralThreadPool().schedule(() -> { updateBlock(session); @@ -99,13 +106,14 @@ public class ItemFrameEntity extends Entity { @Override public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { if (entityMetadata.getId() == 7 && entityMetadata.getValue() != null) { - ItemData itemData = ItemTranslator.translateToBedrock(session, (ItemStack) entityMetadata.getValue()); + this.heldItem = (ItemStack) entityMetadata.getValue(); + ItemData itemData = ItemTranslator.translateToBedrock(session, heldItem); ItemEntry itemEntry = ItemRegistry.getItem((ItemStack) entityMetadata.getValue()); NbtMapBuilder builder = NbtMap.builder(); builder.putByte("Count", (byte) itemData.getCount()); if (itemData.getTag() != null) { - builder.put("tag", itemData.getTag().toBuilder().build()); + builder.put("tag", itemData.getTag()); } builder.putShort("Damage", (short) itemData.getDamage()); builder.putString("Name", itemEntry.getBedrockIdentifier()); @@ -146,7 +154,9 @@ public class ItemFrameEntity extends Entity { updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK); updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NEIGHBORS); session.sendUpstreamPacket(updateBlockPacket); - session.getItemFrameCache().remove(position, entityId); + + session.getItemFrameCache().remove(bedrockPosition, this); + valid = false; return true; } @@ -192,16 +202,7 @@ public class ItemFrameEntity extends Entity { * @param session GeyserSession. * @return Java entity ID or -1 if not found. */ - public static long getItemFrameEntityId(GeyserSession session, Vector3i position) { - return session.getItemFrameCache().getOrDefault(position, -1); - } - - /** - * Force-remove from the position-to-ID map so it doesn't cause conflicts. - * @param session GeyserSession. - * @param position position of the removed item frame. - */ - public static void removePosition(GeyserSession session, Vector3i position) { - session.getItemFrameCache().remove(position); + public static ItemFrameEntity getItemFrameEntity(GeyserSession session, Vector3i position) { + return session.getItemFrameCache().get(position); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java index 081ad859a..28aff40b9 100644 --- a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java +++ b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java @@ -66,10 +66,7 @@ import it.unimi.dsi.fastutil.ints.IntList; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectMaps; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; -import it.unimi.dsi.fastutil.objects.Object2LongMap; -import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap; -import it.unimi.dsi.fastutil.objects.ObjectIterator; -import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; +import it.unimi.dsi.fastutil.objects.*; import lombok.AccessLevel; import lombok.Getter; import lombok.NonNull; @@ -81,6 +78,7 @@ import org.geysermc.connector.command.CommandSender; import org.geysermc.connector.common.AuthType; import org.geysermc.connector.configuration.EmoteOffhandWorkaroundOption; import org.geysermc.connector.entity.Entity; +import org.geysermc.connector.entity.ItemFrameEntity; import org.geysermc.connector.entity.Tickable; import org.geysermc.connector.entity.attribute.Attribute; import org.geysermc.connector.entity.attribute.AttributeType; @@ -189,10 +187,10 @@ public class GeyserSession implements CommandSender { private final Long2ObjectMap storedMaps = Long2ObjectMaps.synchronize(new Long2ObjectOpenHashMap<>()); /** - * A map of Vector3i positions to Java entity IDs. + * A map of Vector3i positions to Java entities. * Used for translating Bedrock block actions to Java entity actions. */ - private final Object2LongMap itemFrameCache = new Object2LongOpenHashMap<>(); + private final Map itemFrameCache = new Object2ObjectOpenHashMap<>(); /** * Stores a list of all lectern locations and their block entity tags. diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockBlockPickRequestTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockBlockPickRequestTranslator.java index 350c029ff..ba74c7769 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockBlockPickRequestTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockBlockPickRequestTranslator.java @@ -27,6 +27,7 @@ package org.geysermc.connector.network.translators.bedrock; import com.nukkitx.math.vector.Vector3i; import com.nukkitx.protocol.bedrock.packet.BlockPickRequestPacket; +import org.geysermc.connector.entity.ItemFrameEntity; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; @@ -43,6 +44,18 @@ public class BedrockBlockPickRequestTranslator extends PacketTranslator