From c8035de7399eb227eb227881a7d2c52f03d11b66 Mon Sep 17 00:00:00 2001 From: Flowsqy <47575244+Flowsqy@users.noreply.github.com> Date: Sat, 31 Dec 2022 17:48:32 +0100 Subject: [PATCH] Change the way nms handle metadata packet --- .../shopchest/nms/FakeArmorStand.java | 10 ---- .../de/epiceric/shopchest/nms/FakeEntity.java | 16 +++++ .../de/epiceric/shopchest/nms/FakeItem.java | 19 ------ .../de/epiceric/shopchest/nms/Platform.java | 9 +++ .../nms/metadata/MetadataProperties.java | 35 +++++++++++ .../nms/metadata/MetadataProperty.java | 14 +++++ .../shopchest/nms/metadata/MetadataValue.java | 5 ++ .../nms/v1_19_R2/FakeArmorStandImpl.java | 40 ------------- .../nms/v1_19_R2/FakeEntityImpl.java | 38 +++++------- .../shopchest/nms/v1_19_R2/FakeItemImpl.java | 36 ----------- .../shopchest/nms/v1_19_R2/PlatformImpl.java | 7 +++ .../ArmorStandMetadataProperties.java | 17 ++++++ .../metadata/EntityMetadataProperties.java | 60 +++++++++++++++++++ .../metadata/ExplicitMetadataValue.java | 10 ++++ .../metadata/ItemMetadataProperties.java | 28 +++++++++ .../metadata/MetadataPropertiesImpl.java | 21 +++++++ .../shopchest/nms/ArmorStandWrapper.java | 36 ++++++++--- .../java/de/epiceric/shopchest/shop/Shop.java | 3 + .../de/epiceric/shopchest/shop/ShopItem.java | 31 +++++++--- 19 files changed, 293 insertions(+), 142 deletions(-) create mode 100644 nms/interface/src/main/java/de/epiceric/shopchest/nms/metadata/MetadataProperties.java create mode 100644 nms/interface/src/main/java/de/epiceric/shopchest/nms/metadata/MetadataProperty.java create mode 100644 nms/interface/src/main/java/de/epiceric/shopchest/nms/metadata/MetadataValue.java create mode 100644 nms/v1_19_R2/src/main/java/de/epiceric/shopchest/nms/v1_19_R2/metadata/ArmorStandMetadataProperties.java create mode 100644 nms/v1_19_R2/src/main/java/de/epiceric/shopchest/nms/v1_19_R2/metadata/EntityMetadataProperties.java create mode 100644 nms/v1_19_R2/src/main/java/de/epiceric/shopchest/nms/v1_19_R2/metadata/ExplicitMetadataValue.java create mode 100644 nms/v1_19_R2/src/main/java/de/epiceric/shopchest/nms/v1_19_R2/metadata/ItemMetadataProperties.java create mode 100644 nms/v1_19_R2/src/main/java/de/epiceric/shopchest/nms/v1_19_R2/metadata/MetadataPropertiesImpl.java diff --git a/nms/interface/src/main/java/de/epiceric/shopchest/nms/FakeArmorStand.java b/nms/interface/src/main/java/de/epiceric/shopchest/nms/FakeArmorStand.java index 0f74174..5a21614 100644 --- a/nms/interface/src/main/java/de/epiceric/shopchest/nms/FakeArmorStand.java +++ b/nms/interface/src/main/java/de/epiceric/shopchest/nms/FakeArmorStand.java @@ -5,14 +5,4 @@ package de.epiceric.shopchest.nms; */ public interface FakeArmorStand extends FakeEntity { - /** - * Register a 'metadata' packet in the {@link PacketQueue} - *
- * It sets the invisibility, the custom name, make it visible and the marker flag - * - * @param packetQueue The {@link PacketQueue} to store the packet - * @param customName The name to set - */ - void metadata(PacketQueue packetQueue, NMSComponent customName); - } diff --git a/nms/interface/src/main/java/de/epiceric/shopchest/nms/FakeEntity.java b/nms/interface/src/main/java/de/epiceric/shopchest/nms/FakeEntity.java index 0682ec7..b9b3b8e 100644 --- a/nms/interface/src/main/java/de/epiceric/shopchest/nms/FakeEntity.java +++ b/nms/interface/src/main/java/de/epiceric/shopchest/nms/FakeEntity.java @@ -1,5 +1,6 @@ package de.epiceric.shopchest.nms; +import de.epiceric.shopchest.nms.metadata.MetadataValue; import org.bukkit.Location; import org.bukkit.util.Vector; @@ -41,4 +42,19 @@ public interface FakeEntity { */ void teleport(PacketQueue packetQueue, Vector position); + /** + * Register a 'metadata' packet in the {@link PacketQueue} + * + * @param packetQueue The {@link PacketQueue} to store the packet + * @param metadataValues The {@link MetadataValue}s to set + */ + void metadata(PacketQueue packetQueue, MetadataValue... metadataValues); + + /** + * Register a zero 'velocity' packet in the {@link PacketQueue} to stop the item from moving + * + * @param packetQueue The {@link PacketQueue} to store the packet + */ + void cancelVelocity(PacketQueue packetQueue); + } diff --git a/nms/interface/src/main/java/de/epiceric/shopchest/nms/FakeItem.java b/nms/interface/src/main/java/de/epiceric/shopchest/nms/FakeItem.java index 6ceecf8..d498aa4 100644 --- a/nms/interface/src/main/java/de/epiceric/shopchest/nms/FakeItem.java +++ b/nms/interface/src/main/java/de/epiceric/shopchest/nms/FakeItem.java @@ -1,27 +1,8 @@ package de.epiceric.shopchest.nms; -import org.bukkit.inventory.ItemStack; - /** * Represent an Item entity that only exists clientside */ public interface FakeItem extends FakeEntity { - /** - * Register a 'metadata' packet in the {@link PacketQueue} - *
- * It sets the type of item - * - * @param packetQueue The {@link PacketQueue} to store the packet - * @param item The {@link ItemStack} type - */ - void metadata(PacketQueue packetQueue, ItemStack item); - - /** - * Register a zero 'velocity' packet in the {@link PacketQueue} to stop the item from moving - * - * @param packetQueue The {@link PacketQueue} to store the packet - */ - void cancelVelocity(PacketQueue packetQueue); - } diff --git a/nms/interface/src/main/java/de/epiceric/shopchest/nms/Platform.java b/nms/interface/src/main/java/de/epiceric/shopchest/nms/Platform.java index 31c9062..cad473d 100644 --- a/nms/interface/src/main/java/de/epiceric/shopchest/nms/Platform.java +++ b/nms/interface/src/main/java/de/epiceric/shopchest/nms/Platform.java @@ -1,5 +1,7 @@ package de.epiceric.shopchest.nms; +import de.epiceric.shopchest.nms.metadata.MetadataProperties; + /** * The platform that create all nms objects */ @@ -29,4 +31,11 @@ public interface Platform { TextComponentHelper getTextComponentHelper(); + /** + * Get a list of {@link de.epiceric.shopchest.nms.metadata.MetadataProperty} + * + * @return The {@link MetadataProperties} instance + */ + MetadataProperties getMetadataProperties(); + } diff --git a/nms/interface/src/main/java/de/epiceric/shopchest/nms/metadata/MetadataProperties.java b/nms/interface/src/main/java/de/epiceric/shopchest/nms/metadata/MetadataProperties.java new file mode 100644 index 0000000..d3a744b --- /dev/null +++ b/nms/interface/src/main/java/de/epiceric/shopchest/nms/metadata/MetadataProperties.java @@ -0,0 +1,35 @@ +package de.epiceric.shopchest.nms.metadata; + +import de.epiceric.shopchest.nms.NMSComponent; +import org.bukkit.inventory.ItemStack; + +public interface MetadataProperties { + + Entity entity(); + + ArmorStand armorStand(); + + Item item(); + + interface Entity { + + MetadataProperty noGravity(); + + MetadataProperty silent(); + + MetadataProperty invisible(); + + MetadataProperty customName(); + + MetadataProperty customNameVisible(); + } + + interface ArmorStand { + MetadataProperty marker(); + } + + interface Item { + MetadataProperty item(); + } + +} diff --git a/nms/interface/src/main/java/de/epiceric/shopchest/nms/metadata/MetadataProperty.java b/nms/interface/src/main/java/de/epiceric/shopchest/nms/metadata/MetadataProperty.java new file mode 100644 index 0000000..e9c1aba --- /dev/null +++ b/nms/interface/src/main/java/de/epiceric/shopchest/nms/metadata/MetadataProperty.java @@ -0,0 +1,14 @@ +package de.epiceric.shopchest.nms.metadata; + +public interface MetadataProperty { + + /** + * Create a new {@link MetadataValue} for this property + * + * @param value The value of the {@link MetadataValue} + * @return a new {@link MetadataValue} + */ + MetadataValue set(T value); + + +} diff --git a/nms/interface/src/main/java/de/epiceric/shopchest/nms/metadata/MetadataValue.java b/nms/interface/src/main/java/de/epiceric/shopchest/nms/metadata/MetadataValue.java new file mode 100644 index 0000000..669bb95 --- /dev/null +++ b/nms/interface/src/main/java/de/epiceric/shopchest/nms/metadata/MetadataValue.java @@ -0,0 +1,5 @@ +package de.epiceric.shopchest.nms.metadata; + +public interface MetadataValue { + +} diff --git a/nms/v1_19_R2/src/main/java/de/epiceric/shopchest/nms/v1_19_R2/FakeArmorStandImpl.java b/nms/v1_19_R2/src/main/java/de/epiceric/shopchest/nms/v1_19_R2/FakeArmorStandImpl.java index ddabf3a..fbb9b3f 100644 --- a/nms/v1_19_R2/src/main/java/de/epiceric/shopchest/nms/v1_19_R2/FakeArmorStandImpl.java +++ b/nms/v1_19_R2/src/main/java/de/epiceric/shopchest/nms/v1_19_R2/FakeArmorStandImpl.java @@ -1,54 +1,14 @@ package de.epiceric.shopchest.nms.v1_19_R2; import de.epiceric.shopchest.nms.FakeArmorStand; -import de.epiceric.shopchest.nms.NMSComponent; -import de.epiceric.shopchest.nms.PacketQueue; -import de.epiceric.shopchest.nms.ReflectionUtils; -import net.minecraft.network.chat.Component; -import net.minecraft.network.syncher.EntityDataAccessor; -import net.minecraft.network.syncher.SynchedEntityData; -import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.decoration.ArmorStand; - -import java.util.Arrays; -import java.util.List; -import java.util.Optional; public class FakeArmorStandImpl extends FakeEntityImpl implements FakeArmorStand { - private final static byte INVISIBLE_FLAG = 0b100000; - private final static byte MARKER_FLAG = 0b10000; - private final static EntityDataAccessor DATA_SHARED_FLAGS_ID; - private final static EntityDataAccessor> DATA_CUSTOM_NAME; - private final static EntityDataAccessor DATA_CUSTOM_NAME_VISIBLE; - - static { - try { - DATA_SHARED_FLAGS_ID = ReflectionUtils.forceCast(ReflectionUtils.getPrivateStaticFieldValue(Entity.class, "Z")); - DATA_CUSTOM_NAME = ReflectionUtils.forceCast(ReflectionUtils.getPrivateStaticFieldValue(Entity.class, "aM")); - DATA_CUSTOM_NAME_VISIBLE = ReflectionUtils.forceCast(ReflectionUtils.getPrivateStaticFieldValue(Entity.class, "aN")); - } catch (ReflectiveOperationException e) { - throw new RuntimeException(e); - } - } - public FakeArmorStandImpl() { super(); } - @Override - public void metadata(PacketQueue packetQueue, NMSComponent customName) { - final List> addProperties = Arrays.asList( - SynchedEntityData.DataValue.create(DATA_SHARED_FLAGS_ID, INVISIBLE_FLAG), - // TODO Handle customName properly - SynchedEntityData.DataValue.create(DATA_CUSTOM_NAME, Optional.ofNullable(null)), - SynchedEntityData.DataValue.create(DATA_CUSTOM_NAME_VISIBLE, true), - SynchedEntityData.DataValue.create(ArmorStand.DATA_CLIENT_FLAGS, MARKER_FLAG) - ); - super.metadata(packetQueue, addProperties); - } - @Override protected EntityType getEntityType() { return EntityType.ARMOR_STAND; diff --git a/nms/v1_19_R2/src/main/java/de/epiceric/shopchest/nms/v1_19_R2/FakeEntityImpl.java b/nms/v1_19_R2/src/main/java/de/epiceric/shopchest/nms/v1_19_R2/FakeEntityImpl.java index 1acb462..29f9cec 100644 --- a/nms/v1_19_R2/src/main/java/de/epiceric/shopchest/nms/v1_19_R2/FakeEntityImpl.java +++ b/nms/v1_19_R2/src/main/java/de/epiceric/shopchest/nms/v1_19_R2/FakeEntityImpl.java @@ -3,13 +3,11 @@ package de.epiceric.shopchest.nms.v1_19_R2; import de.epiceric.shopchest.nms.FakeEntity; import de.epiceric.shopchest.nms.PacketQueue; import de.epiceric.shopchest.nms.ReflectionUtils; +import de.epiceric.shopchest.nms.metadata.MetadataValue; +import de.epiceric.shopchest.nms.v1_19_R2.metadata.ExplicitMetadataValue; import io.netty.buffer.Unpooled; import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.network.protocol.game.ClientboundAddEntityPacket; -import net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket; -import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket; -import net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket; -import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.network.protocol.game.*; import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; @@ -17,22 +15,19 @@ import net.minecraft.world.phys.Vec3; import org.bukkit.Location; import org.bukkit.util.Vector; -import java.util.LinkedList; import java.util.List; import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; +import java.util.stream.Stream; public abstract class FakeEntityImpl implements FakeEntity { private final static AtomicInteger ENTITY_COUNTER; - private final static EntityDataAccessor DATA_NO_GRAVITY; - private final static EntityDataAccessor DATA_SILENT; static { try { ENTITY_COUNTER = (AtomicInteger) ReflectionUtils.getPrivateStaticFieldValue(Entity.class, "c"); - DATA_NO_GRAVITY = ReflectionUtils.forceCast(ReflectionUtils.getPrivateStaticFieldValue(Entity.class, "aP")); - DATA_SILENT = ReflectionUtils.forceCast(ReflectionUtils.getPrivateStaticFieldValue(Entity.class, "aO")); } catch (ReflectiveOperationException e) { throw new RuntimeException(e); } @@ -89,20 +84,19 @@ public abstract class FakeEntityImpl implements FakeEntity { ((PacketQueueImpl) packetQueue).register(positionPacket); } - /** - * Register a 'metadata' packet in the {@link PacketQueue} with the silent and no gravity properties - * - * @param packetQueue The {@link PacketQueue} to store the packet - * @param addProperties A {@link List} of {@link net.minecraft.network.syncher.SynchedEntityData.DataValue} to add - */ - public void metadata(PacketQueue packetQueue, List> addProperties) { - final List> packedItems = new LinkedList<>(); - packedItems.add(SynchedEntityData.DataValue.create(DATA_NO_GRAVITY, true)); - packedItems.add(SynchedEntityData.DataValue.create(DATA_SILENT, true)); - packedItems.addAll(addProperties); - + @Override + public void metadata(PacketQueue packetQueue, MetadataValue[] values) { + final List> packedItems = Stream.of(values) + .map(value -> ((ExplicitMetadataValue) value).toNMS()) + .collect(Collectors.toList()); final ClientboundSetEntityDataPacket dataPacket = new ClientboundSetEntityDataPacket(entityId, packedItems); ((PacketQueueImpl) packetQueue).register(dataPacket); } + @Override + public void cancelVelocity(PacketQueue packetQueue) { + final ClientboundSetEntityMotionPacket velocityPacket = new ClientboundSetEntityMotionPacket(getEntityId(), Vec3.ZERO); + ((PacketQueueImpl) packetQueue).register(velocityPacket); + } + } diff --git a/nms/v1_19_R2/src/main/java/de/epiceric/shopchest/nms/v1_19_R2/FakeItemImpl.java b/nms/v1_19_R2/src/main/java/de/epiceric/shopchest/nms/v1_19_R2/FakeItemImpl.java index 47a11a0..4a69095 100644 --- a/nms/v1_19_R2/src/main/java/de/epiceric/shopchest/nms/v1_19_R2/FakeItemImpl.java +++ b/nms/v1_19_R2/src/main/java/de/epiceric/shopchest/nms/v1_19_R2/FakeItemImpl.java @@ -1,50 +1,14 @@ package de.epiceric.shopchest.nms.v1_19_R2; import de.epiceric.shopchest.nms.FakeItem; -import de.epiceric.shopchest.nms.PacketQueue; -import de.epiceric.shopchest.nms.ReflectionUtils; -import net.minecraft.network.protocol.game.ClientboundSetEntityMotionPacket; -import net.minecraft.network.syncher.EntityDataAccessor; -import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.item.ItemEntity; -import net.minecraft.world.phys.Vec3; -import org.bukkit.craftbukkit.v1_19_R2.inventory.CraftItemStack; -import org.bukkit.inventory.ItemStack; - -import java.util.Collections; -import java.util.List; public class FakeItemImpl extends FakeEntityImpl implements FakeItem { - private final static EntityDataAccessor DATA_ITEM; - - static { - try { - DATA_ITEM = ReflectionUtils.forceCast(ReflectionUtils.getPrivateStaticFieldValue(ItemEntity.class, "c")); - } catch (ReflectiveOperationException e) { - throw new RuntimeException(e); - } - } - public FakeItemImpl() { super(); } - @Override - public void metadata(PacketQueue packetQueue, ItemStack item) { - final List> addProperties = Collections.singletonList( - SynchedEntityData.DataValue.create(DATA_ITEM, CraftItemStack.asNMSCopy(item)) - ); - metadata(packetQueue, addProperties); - } - - @Override - public void cancelVelocity(PacketQueue packetQueue) { - final ClientboundSetEntityMotionPacket velocityPacket = new ClientboundSetEntityMotionPacket(getEntityId(), Vec3.ZERO); - ((PacketQueueImpl) packetQueue).register(velocityPacket); - } - @Override protected EntityType getEntityType() { return EntityType.ITEM; diff --git a/nms/v1_19_R2/src/main/java/de/epiceric/shopchest/nms/v1_19_R2/PlatformImpl.java b/nms/v1_19_R2/src/main/java/de/epiceric/shopchest/nms/v1_19_R2/PlatformImpl.java index 9b17998..9cf12d7 100644 --- a/nms/v1_19_R2/src/main/java/de/epiceric/shopchest/nms/v1_19_R2/PlatformImpl.java +++ b/nms/v1_19_R2/src/main/java/de/epiceric/shopchest/nms/v1_19_R2/PlatformImpl.java @@ -1,6 +1,8 @@ package de.epiceric.shopchest.nms.v1_19_R2; import de.epiceric.shopchest.nms.*; +import de.epiceric.shopchest.nms.metadata.MetadataProperties; +import de.epiceric.shopchest.nms.v1_19_R2.metadata.MetadataPropertiesImpl; public class PlatformImpl implements Platform { @@ -24,4 +26,9 @@ public class PlatformImpl implements Platform { return new TextComponentHelperImpl(); } + @Override + public MetadataProperties getMetadataProperties() { + return new MetadataPropertiesImpl(); + } + } diff --git a/nms/v1_19_R2/src/main/java/de/epiceric/shopchest/nms/v1_19_R2/metadata/ArmorStandMetadataProperties.java b/nms/v1_19_R2/src/main/java/de/epiceric/shopchest/nms/v1_19_R2/metadata/ArmorStandMetadataProperties.java new file mode 100644 index 0000000..b944be3 --- /dev/null +++ b/nms/v1_19_R2/src/main/java/de/epiceric/shopchest/nms/v1_19_R2/metadata/ArmorStandMetadataProperties.java @@ -0,0 +1,17 @@ +package de.epiceric.shopchest.nms.v1_19_R2.metadata; + +import de.epiceric.shopchest.nms.metadata.MetadataProperties; +import de.epiceric.shopchest.nms.metadata.MetadataProperty; +import net.minecraft.network.syncher.SynchedEntityData; +import net.minecraft.world.entity.decoration.ArmorStand; + +public class ArmorStandMetadataProperties implements MetadataProperties.ArmorStand { + + private final static byte MARKER_FLAG = 0b10000; + + @Override + public MetadataProperty marker() { + return value -> (ExplicitMetadataValue) () -> SynchedEntityData.DataValue.create(ArmorStand.DATA_CLIENT_FLAGS, value ? MARKER_FLAG : 0); + } + +} diff --git a/nms/v1_19_R2/src/main/java/de/epiceric/shopchest/nms/v1_19_R2/metadata/EntityMetadataProperties.java b/nms/v1_19_R2/src/main/java/de/epiceric/shopchest/nms/v1_19_R2/metadata/EntityMetadataProperties.java new file mode 100644 index 0000000..d1e9f2b --- /dev/null +++ b/nms/v1_19_R2/src/main/java/de/epiceric/shopchest/nms/v1_19_R2/metadata/EntityMetadataProperties.java @@ -0,0 +1,60 @@ +package de.epiceric.shopchest.nms.v1_19_R2.metadata; + +import de.epiceric.shopchest.nms.NMSComponent; +import de.epiceric.shopchest.nms.ReflectionUtils; +import de.epiceric.shopchest.nms.metadata.MetadataProperties; +import de.epiceric.shopchest.nms.metadata.MetadataProperty; +import net.minecraft.network.chat.Component; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.network.syncher.SynchedEntityData; +import net.minecraft.world.entity.Entity; + +import java.util.Optional; + +public class EntityMetadataProperties implements MetadataProperties.Entity { + + private final static EntityDataAccessor DATA_NO_GRAVITY; + private final static EntityDataAccessor DATA_SILENT; + private final static EntityDataAccessor DATA_SHARED_FLAGS_ID; + private final static EntityDataAccessor> DATA_CUSTOM_NAME; + private final static EntityDataAccessor DATA_CUSTOM_NAME_VISIBLE; + private final static byte INVISIBLE_FLAG = 0b100000; + + static { + try { + DATA_NO_GRAVITY = ReflectionUtils.forceCast(ReflectionUtils.getPrivateStaticFieldValue(Entity.class, "aP")); + DATA_SILENT = ReflectionUtils.forceCast(ReflectionUtils.getPrivateStaticFieldValue(Entity.class, "aO")); + DATA_SHARED_FLAGS_ID = ReflectionUtils.forceCast(ReflectionUtils.getPrivateStaticFieldValue(Entity.class, "Z")); + DATA_CUSTOM_NAME = ReflectionUtils.forceCast(ReflectionUtils.getPrivateStaticFieldValue(Entity.class, "aM")); + DATA_CUSTOM_NAME_VISIBLE = ReflectionUtils.forceCast(ReflectionUtils.getPrivateStaticFieldValue(Entity.class, "aN")); + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } + + @Override + public MetadataProperty noGravity() { + return value -> (ExplicitMetadataValue) () -> SynchedEntityData.DataValue.create(DATA_NO_GRAVITY, value); + } + + @Override + public MetadataProperty silent() { + return value -> (ExplicitMetadataValue) () -> SynchedEntityData.DataValue.create(DATA_SILENT, value); + } + + @Override + public MetadataProperty invisible() { + return value -> (ExplicitMetadataValue) () -> SynchedEntityData.DataValue.create(DATA_SHARED_FLAGS_ID, value ? INVISIBLE_FLAG : 0); + } + + @Override + public MetadataProperty customName() { + // TODO Handle customName properly + return value -> (ExplicitMetadataValue) () -> SynchedEntityData.DataValue.create(DATA_CUSTOM_NAME, Optional.ofNullable(null)); + } + + @Override + public MetadataProperty customNameVisible() { + return value -> (ExplicitMetadataValue) () -> SynchedEntityData.DataValue.create(DATA_CUSTOM_NAME_VISIBLE, true); + } +} diff --git a/nms/v1_19_R2/src/main/java/de/epiceric/shopchest/nms/v1_19_R2/metadata/ExplicitMetadataValue.java b/nms/v1_19_R2/src/main/java/de/epiceric/shopchest/nms/v1_19_R2/metadata/ExplicitMetadataValue.java new file mode 100644 index 0000000..e9e6bc5 --- /dev/null +++ b/nms/v1_19_R2/src/main/java/de/epiceric/shopchest/nms/v1_19_R2/metadata/ExplicitMetadataValue.java @@ -0,0 +1,10 @@ +package de.epiceric.shopchest.nms.v1_19_R2.metadata; + +import de.epiceric.shopchest.nms.metadata.MetadataValue; +import net.minecraft.network.syncher.SynchedEntityData; + +public interface ExplicitMetadataValue extends MetadataValue { + + SynchedEntityData.DataValue toNMS(); + +} diff --git a/nms/v1_19_R2/src/main/java/de/epiceric/shopchest/nms/v1_19_R2/metadata/ItemMetadataProperties.java b/nms/v1_19_R2/src/main/java/de/epiceric/shopchest/nms/v1_19_R2/metadata/ItemMetadataProperties.java new file mode 100644 index 0000000..35f0f80 --- /dev/null +++ b/nms/v1_19_R2/src/main/java/de/epiceric/shopchest/nms/v1_19_R2/metadata/ItemMetadataProperties.java @@ -0,0 +1,28 @@ +package de.epiceric.shopchest.nms.v1_19_R2.metadata; + +import de.epiceric.shopchest.nms.ReflectionUtils; +import de.epiceric.shopchest.nms.metadata.MetadataProperties; +import de.epiceric.shopchest.nms.metadata.MetadataProperty; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.network.syncher.SynchedEntityData; +import net.minecraft.world.entity.item.ItemEntity; +import org.bukkit.craftbukkit.v1_19_R2.inventory.CraftItemStack; +import org.bukkit.inventory.ItemStack; + +public class ItemMetadataProperties implements MetadataProperties.Item { + + private final static EntityDataAccessor DATA_ITEM; + + static { + try { + DATA_ITEM = ReflectionUtils.forceCast(ReflectionUtils.getPrivateStaticFieldValue(ItemEntity.class, "c")); + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } + + @Override + public MetadataProperty item() { + return value -> (ExplicitMetadataValue) () -> SynchedEntityData.DataValue.create(DATA_ITEM, CraftItemStack.asNMSCopy(value)); + } +} diff --git a/nms/v1_19_R2/src/main/java/de/epiceric/shopchest/nms/v1_19_R2/metadata/MetadataPropertiesImpl.java b/nms/v1_19_R2/src/main/java/de/epiceric/shopchest/nms/v1_19_R2/metadata/MetadataPropertiesImpl.java new file mode 100644 index 0000000..ad0970d --- /dev/null +++ b/nms/v1_19_R2/src/main/java/de/epiceric/shopchest/nms/v1_19_R2/metadata/MetadataPropertiesImpl.java @@ -0,0 +1,21 @@ +package de.epiceric.shopchest.nms.v1_19_R2.metadata; + +import de.epiceric.shopchest.nms.metadata.MetadataProperties; + +public class MetadataPropertiesImpl implements MetadataProperties { + + @Override + public Entity entity() { + return new EntityMetadataProperties(); + } + + @Override + public ArmorStand armorStand() { + return new ArmorStandMetadataProperties(); + } + + @Override + public Item item() { + return new ItemMetadataProperties(); + } +} diff --git a/plugin/src/main/java/de/epiceric/shopchest/nms/ArmorStandWrapper.java b/plugin/src/main/java/de/epiceric/shopchest/nms/ArmorStandWrapper.java index 0bf269c..270a8e5 100644 --- a/plugin/src/main/java/de/epiceric/shopchest/nms/ArmorStandWrapper.java +++ b/plugin/src/main/java/de/epiceric/shopchest/nms/ArmorStandWrapper.java @@ -1,17 +1,18 @@ package de.epiceric.shopchest.nms; import de.epiceric.shopchest.ShopChest; +import de.epiceric.shopchest.nms.metadata.MetadataProperties; import org.bukkit.Location; import org.bukkit.entity.Player; import java.util.Collections; -import java.util.List; import java.util.Objects; import java.util.UUID; public class ArmorStandWrapper { private final UUID uuid = UUID.randomUUID(); + private final Platform platform; private final FakeArmorStand fakeArmorStand; private Location location; @@ -20,28 +21,47 @@ public class ArmorStandWrapper { public ArmorStandWrapper(ShopChest plugin, Location location, String customName) { this.location = location; this.customName = customName; - this.fakeArmorStand = plugin.getPlatform().createFakeArmorStand(); + this.platform = plugin.getPlatform(); + this.fakeArmorStand = platform.createFakeArmorStand(); } public void setVisible(Player player, boolean visible) { - final List receiver = Collections.singletonList(player); if(visible){ - fakeArmorStand.spawn(uuid, location, receiver); - fakeArmorStand.sendData(customName, receiver); + final PacketQueue packetQueue = platform.createPacketQueue(); + fakeArmorStand.create(packetQueue, uuid, location); + final MetadataProperties mdp = platform.getMetadataProperties(); + final MetadataProperties.Entity entityMdp = mdp.entity(); + fakeArmorStand.metadata(packetQueue, + entityMdp.noGravity().set(true), + entityMdp.silent().set(true), + entityMdp.invisible().set(true), + // TODO Handle custom name properly + entityMdp.customName().set(new NMSComponent()), + entityMdp.customNameVisible().set(true), + mdp.armorStand().marker().set(true) + ); + packetQueue.send(Collections.singletonList(player)); } else if(fakeArmorStand.getEntityId() != -1){ - fakeArmorStand.remove(receiver); + final PacketQueue packetQueue = platform.createPacketQueue(); + fakeArmorStand.remove(packetQueue); + packetQueue.send(Collections.singletonList(player)); } } public void setLocation(Location location) { this.location = location; - fakeArmorStand.setLocation(location, Objects.requireNonNull(location.getWorld()).getPlayers()); + final PacketQueue packetQueue = platform.createPacketQueue(); + fakeArmorStand.teleport(packetQueue, location.toVector()); + packetQueue.send(Objects.requireNonNull(location.getWorld()).getPlayers()); } public void setCustomName(String customName) { this.customName = customName; - fakeArmorStand.sendData(customName, Objects.requireNonNull(location.getWorld()).getPlayers()); + final PacketQueue packetQueue = platform.createPacketQueue(); + // TODO Handle custom name properly + fakeArmorStand.metadata(packetQueue, platform.getMetadataProperties().entity().customName().set(new NMSComponent())); + packetQueue.send(Objects.requireNonNull(location.getWorld()).getPlayers()); } public void remove() { diff --git a/plugin/src/main/java/de/epiceric/shopchest/shop/Shop.java b/plugin/src/main/java/de/epiceric/shopchest/shop/Shop.java index 5bc510f..76d108c 100644 --- a/plugin/src/main/java/de/epiceric/shopchest/shop/Shop.java +++ b/plugin/src/main/java/de/epiceric/shopchest/shop/Shop.java @@ -376,6 +376,9 @@ public class Shop { holoLocation.add(0, GlobalConfig.hologramLift, 0); + final float MARKER_ARMOR_STAND_OFFSET = 1.975f; + holoLocation.add(0, MARKER_ARMOR_STAND_OFFSET, 0); + return holoLocation; } diff --git a/plugin/src/main/java/de/epiceric/shopchest/shop/ShopItem.java b/plugin/src/main/java/de/epiceric/shopchest/shop/ShopItem.java index 4e2b73f..bc8d589 100644 --- a/plugin/src/main/java/de/epiceric/shopchest/shop/ShopItem.java +++ b/plugin/src/main/java/de/epiceric/shopchest/shop/ShopItem.java @@ -2,12 +2,18 @@ package de.epiceric.shopchest.shop; import de.epiceric.shopchest.ShopChest; import de.epiceric.shopchest.nms.FakeItem; +import de.epiceric.shopchest.nms.PacketQueue; +import de.epiceric.shopchest.nms.Platform; +import de.epiceric.shopchest.nms.metadata.MetadataProperties; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Set; +import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; public class ShopItem { @@ -17,12 +23,14 @@ public class ShopItem { private final ItemStack itemStack; private final Location location; private final UUID uuid = UUID.randomUUID(); + private final Platform platform; private final FakeItem fakeItem; public ShopItem(ShopChest plugin, ItemStack itemStack, Location location) { this.itemStack = itemStack; this.location = location; - this.fakeItem = plugin.getPlatform().createFakeItem(); + this.platform = plugin.getPlatform(); + this.fakeItem = platform.createFakeItem(); } /** @@ -60,10 +68,17 @@ public class ShopItem { */ public void showPlayer(Player p, boolean force) { if (viewers.add(p.getUniqueId()) || force) { - final List receiver = Collections.singletonList(p); - fakeItem.spawn(uuid, location, receiver); - fakeItem.sendData(itemStack, receiver); - fakeItem.resetVelocity(receiver); + final PacketQueue packetQueue = platform.createPacketQueue(); + fakeItem.create(packetQueue, uuid, location); + final MetadataProperties mdp = platform.getMetadataProperties(); + final MetadataProperties.Entity entityMdp = mdp.entity(); + fakeItem.metadata(packetQueue, + entityMdp.noGravity().set(true), + entityMdp.silent().set(true), + mdp.item().item().set(itemStack) + ); + fakeItem.cancelVelocity(packetQueue); + packetQueue.send(Collections.singletonList(p)); } } @@ -81,7 +96,9 @@ public class ShopItem { public void hidePlayer(Player p, boolean force) { if (viewers.remove(p.getUniqueId()) || force) { if (p.isOnline()) { - fakeItem.remove(Collections.singletonList(p)); + final PacketQueue packetQueue = platform.createPacketQueue(); + fakeItem.remove(packetQueue); + packetQueue.send(Collections.singletonList(p)); } } }