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));
}
}
}