mirror of
https://github.com/Flowsqy/ShopChest.git
synced 2025-01-07 07:47:41 +01:00
Implement v1_18_R2
This commit is contained in:
parent
6d834588c3
commit
346d1685f5
@ -1,99 +1,16 @@
|
||||
package de.epiceric.shopchest.nms.v1_18_R2;
|
||||
|
||||
import de.epiceric.shopchest.nms.FakeArmorStand;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import net.md_5.bungee.chat.ComponentSerializer;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket;
|
||||
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 org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class FakeArmorStandImpl extends FakeEntityImpl<String> implements FakeArmorStand {
|
||||
|
||||
private final static byte INVISIBLE_FLAG = 0b100000;
|
||||
private final static byte MARKER_FLAG = 0b10000;
|
||||
private final static EntityDataAccessor<Byte> DATA_SHARED_FLAGS_ID;
|
||||
private final static EntityDataAccessor<Optional<Component>> DATA_CUSTOM_NAME;
|
||||
private final static EntityDataAccessor<Boolean> DATA_CUSTOM_NAME_VISIBLE;
|
||||
private final static float MARKER_ARMOR_STAND_OFFSET = 1.975f;
|
||||
|
||||
static {
|
||||
try {
|
||||
final Field dataSharedFlagsId = Entity.class.getDeclaredField("Z"); // DATA_SHARED_FLAGS_ID
|
||||
dataSharedFlagsId.setAccessible(true);
|
||||
DATA_SHARED_FLAGS_ID = forceCast(dataSharedFlagsId.get(null));
|
||||
final Field dataCustomNameField = Entity.class.getDeclaredField("aM"); // DATA_CUSTOM_NAME
|
||||
dataCustomNameField.setAccessible(true);
|
||||
DATA_CUSTOM_NAME = forceCast(dataCustomNameField.get(null));
|
||||
final Field dataCustomNameVisibleField = Entity.class.getDeclaredField("aN"); // DATA_CUSTOM_NAME_VISIBLE
|
||||
dataCustomNameVisibleField.setAccessible(true);
|
||||
DATA_CUSTOM_NAME_VISIBLE = forceCast(dataCustomNameVisibleField.get(null));
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
public class FakeArmorStandImpl extends FakeEntityImpl implements FakeArmorStand {
|
||||
|
||||
public FakeArmorStandImpl() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendData(String name, Iterable<Player> receivers) {
|
||||
sendData(receivers, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EntityType<?> getEntityType() {
|
||||
return EntityType.ARMOR_STAND;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float getSpawnOffSet() {
|
||||
return MARKER_ARMOR_STAND_OFFSET;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getDataItemCount() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addSpecificData(List<SynchedEntityData.DataItem<?>> packedItems, String name) {
|
||||
packedItems.add(new SynchedEntityData.DataItem<>(DATA_SHARED_FLAGS_ID, INVISIBLE_FLAG));
|
||||
packedItems.add(new SynchedEntityData.DataItem<>(DATA_CUSTOM_NAME, Optional.ofNullable(
|
||||
Component.Serializer.fromJson(
|
||||
ComponentSerializer.toString(
|
||||
TextComponent.fromLegacyText(name)
|
||||
)
|
||||
)
|
||||
)));
|
||||
packedItems.add(new SynchedEntityData.DataItem<>(DATA_CUSTOM_NAME_VISIBLE, true));
|
||||
packedItems.add(new SynchedEntityData.DataItem<>(ArmorStand.DATA_CLIENT_FLAGS, MARKER_FLAG));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLocation(Location location, Iterable<Player> receivers) {
|
||||
final FriendlyByteBuf buffer = new FriendlyByteBuf(Unpooled.buffer());
|
||||
buffer.writeVarInt(entityId);
|
||||
buffer.writeDouble(location.getX());
|
||||
buffer.writeDouble(location.getY() + MARKER_ARMOR_STAND_OFFSET);
|
||||
buffer.writeDouble(location.getZ());
|
||||
buffer.writeByte(0);
|
||||
buffer.writeByte(0);
|
||||
buffer.writeBoolean(false);
|
||||
final ClientboundTeleportEntityPacket positionPacket = new ClientboundTeleportEntityPacket(buffer);
|
||||
sendPacket(positionPacket, receivers);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,43 +1,35 @@
|
||||
package de.epiceric.shopchest.nms.v1_18_R2;
|
||||
|
||||
import de.epiceric.shopchest.nms.FakeEntity;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
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.syncher.EntityDataAccessor;
|
||||
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_18_R2.metadata.ExplicitMetadataValue;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.protocol.game.*;
|
||||
import net.minecraft.network.syncher.SynchedEntityData;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
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<T> implements FakeEntity {
|
||||
public abstract class FakeEntityImpl implements FakeEntity {
|
||||
|
||||
private final static AtomicInteger ENTITY_COUNTER;
|
||||
private final static EntityDataAccessor<Boolean> DATA_NO_GRAVITY;
|
||||
private final static EntityDataAccessor<Boolean> DATA_SILENT;
|
||||
private final static Field packedItemField;
|
||||
|
||||
static {
|
||||
try {
|
||||
final Field entityCounterField = Entity.class.getDeclaredField("c"); // ENTITY_COUNTER
|
||||
entityCounterField.setAccessible(true);
|
||||
ENTITY_COUNTER = (AtomicInteger) entityCounterField.get(null);
|
||||
final Field dataNoGravityField = Entity.class.getDeclaredField("aP"); // DATA_NO_GRAVITY
|
||||
dataNoGravityField.setAccessible(true);
|
||||
DATA_NO_GRAVITY = forceCast(dataNoGravityField.get(null));
|
||||
final Field dataSilentField = Entity.class.getDeclaredField("aO"); // DATA_SILENT
|
||||
dataSilentField.setAccessible(true);
|
||||
DATA_SILENT = forceCast(dataSilentField.get(null));
|
||||
ENTITY_COUNTER = (AtomicInteger) ReflectionUtils.getPrivateStaticFieldValue(Entity.class, "c");
|
||||
packedItemField = ClientboundSetEntityDataPacket.class.getDeclaredField("b"); // packedItems
|
||||
packedItemField.setAccessible(true);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
@ -45,35 +37,24 @@ public abstract class FakeEntityImpl<T> implements FakeEntity {
|
||||
}
|
||||
}
|
||||
|
||||
protected final int entityId;
|
||||
private final int entityId;
|
||||
|
||||
public FakeEntityImpl() {
|
||||
entityId = ENTITY_COUNTER.incrementAndGet();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected static <T> T forceCast(Object o) {
|
||||
return (T) o;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEntityId() {
|
||||
return entityId;
|
||||
}
|
||||
|
||||
protected void sendPacket(Packet<?> packet, Iterable<Player> receivers) {
|
||||
for (Player receiver : receivers) {
|
||||
((CraftPlayer) receiver).getHandle().connection.send(packet);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void spawn(UUID uuid, Location location, Iterable<Player> receivers) {
|
||||
final ClientboundAddEntityPacket spawnPacket = new ClientboundAddEntityPacket(
|
||||
public void create(PacketQueue packetQueue, UUID uuid, Location location) {
|
||||
final ClientboundAddEntityPacket addPacket = new ClientboundAddEntityPacket(
|
||||
entityId,
|
||||
uuid,
|
||||
location.getX(),
|
||||
location.getY() + getSpawnOffSet(),
|
||||
location.getY(),
|
||||
location.getZ(),
|
||||
0f,
|
||||
0f,
|
||||
@ -81,25 +62,38 @@ public abstract class FakeEntityImpl<T> implements FakeEntity {
|
||||
0,
|
||||
Vec3.ZERO
|
||||
);
|
||||
sendPacket(spawnPacket, receivers);
|
||||
((PacketQueueImpl) packetQueue).register(addPacket);
|
||||
}
|
||||
|
||||
protected abstract EntityType<?> getEntityType();
|
||||
|
||||
@Override
|
||||
public void remove(PacketQueue packetQueue) {
|
||||
final ClientboundRemoveEntitiesPacket removePacket = new ClientboundRemoveEntitiesPacket(entityId);
|
||||
((PacketQueueImpl) packetQueue).register(removePacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(Iterable<Player> receivers) {
|
||||
final ClientboundRemoveEntitiesPacket removePacket = new ClientboundRemoveEntitiesPacket(entityId);
|
||||
sendPacket(removePacket, receivers);
|
||||
public void teleport(PacketQueue packetQueue, Vector position) {
|
||||
final FriendlyByteBuf buffer = new FriendlyByteBuf(Unpooled.buffer());
|
||||
buffer.writeVarInt(entityId);
|
||||
buffer.writeDouble(position.getX());
|
||||
buffer.writeDouble(position.getY());
|
||||
buffer.writeDouble(position.getZ());
|
||||
buffer.writeByte(0);
|
||||
buffer.writeByte(0);
|
||||
buffer.writeBoolean(false);
|
||||
final ClientboundTeleportEntityPacket positionPacket = new ClientboundTeleportEntityPacket(buffer);
|
||||
((PacketQueueImpl) packetQueue).register(positionPacket);
|
||||
}
|
||||
|
||||
protected void sendData(Iterable<Player> receivers, T data) {
|
||||
// Create packet
|
||||
@Override
|
||||
public void metadata(PacketQueue packetQueue, MetadataValue[] values) {
|
||||
final List<SynchedEntityData.DataItem<?>> packedItems = Stream.of(values)
|
||||
.map(value -> ((ExplicitMetadataValue) value).toNMS())
|
||||
.collect(Collectors.toList());
|
||||
final SynchedEntityData entityData = new SynchedEntityData(null);
|
||||
final ClientboundSetEntityDataPacket dataPacket = new ClientboundSetEntityDataPacket(entityId, entityData, false);
|
||||
final List<SynchedEntityData.DataItem<?>> packedItems = new ArrayList<>(2 + getDataItemCount());
|
||||
|
||||
// Setup data
|
||||
packedItems.add(new SynchedEntityData.DataItem<>(DATA_NO_GRAVITY, true));
|
||||
packedItems.add(new SynchedEntityData.DataItem<>(DATA_SILENT, true));
|
||||
addSpecificData(packedItems, data);
|
||||
|
||||
try {
|
||||
packedItemField.set(dataPacket, packedItems);
|
||||
@ -107,18 +101,13 @@ public abstract class FakeEntityImpl<T> implements FakeEntity {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
// Send packet
|
||||
sendPacket(dataPacket, receivers);
|
||||
((PacketQueueImpl) packetQueue).register(dataPacket);
|
||||
}
|
||||
|
||||
protected abstract EntityType<?> getEntityType();
|
||||
|
||||
protected float getSpawnOffSet() {
|
||||
return 0f;
|
||||
@Override
|
||||
public void cancelVelocity(PacketQueue packetQueue) {
|
||||
final ClientboundSetEntityMotionPacket velocityPacket = new ClientboundSetEntityMotionPacket(getEntityId(), Vec3.ZERO);
|
||||
((PacketQueueImpl) packetQueue).register(velocityPacket);
|
||||
}
|
||||
|
||||
protected abstract int getDataItemCount();
|
||||
|
||||
protected abstract void addSpecificData(List<SynchedEntityData.DataItem<?>> packedItems, T data);
|
||||
|
||||
}
|
||||
|
@ -1,60 +1,16 @@
|
||||
package de.epiceric.shopchest.nms.v1_18_R2;
|
||||
|
||||
import de.epiceric.shopchest.nms.FakeItem;
|
||||
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_18_R2.inventory.CraftItemStack;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
|
||||
public class FakeItemImpl extends FakeEntityImpl<ItemStack> implements FakeItem {
|
||||
|
||||
private final static EntityDataAccessor<net.minecraft.world.item.ItemStack> DATA_ITEM;
|
||||
|
||||
static {
|
||||
try {
|
||||
final Field dataItemField = ItemEntity.class.getDeclaredField("c"); // DATA_ITEM
|
||||
dataItemField.setAccessible(true);
|
||||
DATA_ITEM = forceCast(dataItemField.get(null));
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
public class FakeItemImpl extends FakeEntityImpl implements FakeItem {
|
||||
|
||||
public FakeItemImpl() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendData(ItemStack item, Iterable<Player> receivers) {
|
||||
sendData(receivers, item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetVelocity(Iterable<Player> receivers) {
|
||||
final ClientboundSetEntityMotionPacket velocityPacket = new ClientboundSetEntityMotionPacket(entityId, Vec3.ZERO);
|
||||
sendPacket(velocityPacket, receivers);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EntityType<?> getEntityType() {
|
||||
return EntityType.ITEM;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getDataItemCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addSpecificData(List<SynchedEntityData.DataItem<?>> packedItems, ItemStack data) {
|
||||
packedItems.add(new SynchedEntityData.DataItem<>(DATA_ITEM, CraftItemStack.asNMSCopy(data)));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,33 @@
|
||||
package de.epiceric.shopchest.nms.v1_18_R2;
|
||||
|
||||
import de.epiceric.shopchest.nms.PacketQueue;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.server.network.ServerPlayerConnection;
|
||||
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class PacketQueueImpl implements PacketQueue {
|
||||
|
||||
private final List<Packet<?>> packets;
|
||||
|
||||
public PacketQueueImpl() {
|
||||
packets = new LinkedList<>();
|
||||
}
|
||||
|
||||
public void register(Packet<?> packet) {
|
||||
packets.add(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(Iterable<Player> receivers) {
|
||||
for (Player player : receivers) {
|
||||
final ServerPlayerConnection connection = ((CraftPlayer) player).getHandle().connection;
|
||||
for (Packet<?> packet : packets) {
|
||||
connection.send(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +1,8 @@
|
||||
package de.epiceric.shopchest.nms.v1_18_R2;
|
||||
|
||||
import de.epiceric.shopchest.nms.FakeArmorStand;
|
||||
import de.epiceric.shopchest.nms.FakeItem;
|
||||
import de.epiceric.shopchest.nms.Platform;
|
||||
import de.epiceric.shopchest.nms.TextComponentHelper;
|
||||
import de.epiceric.shopchest.nms.*;
|
||||
import de.epiceric.shopchest.nms.metadata.MetadataProperties;
|
||||
import de.epiceric.shopchest.nms.v1_18_R2.metadata.MetadataPropertiesImpl;
|
||||
|
||||
public class PlatformImpl implements Platform {
|
||||
|
||||
@ -17,9 +16,19 @@ public class PlatformImpl implements Platform {
|
||||
return new FakeItemImpl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketQueue createPacketQueue() {
|
||||
return new PacketQueueImpl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextComponentHelper getTextComponentHelper() {
|
||||
return new TextComponentHelperImpl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MetadataProperties getMetadataProperties() {
|
||||
return new MetadataPropertiesImpl();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,17 @@
|
||||
package de.epiceric.shopchest.nms.v1_18_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<Boolean> marker() {
|
||||
return value -> (ExplicitMetadataValue) () -> new SynchedEntityData.DataItem<>(ArmorStand.DATA_CLIENT_FLAGS, value ? MARKER_FLAG : 0);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
package de.epiceric.shopchest.nms.v1_18_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<Boolean> DATA_NO_GRAVITY;
|
||||
private final static EntityDataAccessor<Boolean> DATA_SILENT;
|
||||
private final static EntityDataAccessor<Byte> DATA_SHARED_FLAGS_ID;
|
||||
private final static EntityDataAccessor<Optional<Component>> DATA_CUSTOM_NAME;
|
||||
private final static EntityDataAccessor<Boolean> 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<Boolean> noGravity() {
|
||||
return value -> (ExplicitMetadataValue) () -> new SynchedEntityData.DataItem<>(DATA_NO_GRAVITY, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MetadataProperty<Boolean> silent() {
|
||||
return value -> (ExplicitMetadataValue) () -> new SynchedEntityData.DataItem<>(DATA_SILENT, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MetadataProperty<Boolean> invisible() {
|
||||
return value -> (ExplicitMetadataValue) () -> new SynchedEntityData.DataItem<>(DATA_SHARED_FLAGS_ID, value ? INVISIBLE_FLAG : 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MetadataProperty<NMSComponent> customName() {
|
||||
// TODO Handle customName properly
|
||||
return value -> (ExplicitMetadataValue) () -> new SynchedEntityData.DataItem<>(DATA_CUSTOM_NAME, Optional.ofNullable(null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MetadataProperty<Boolean> customNameVisible() {
|
||||
return value -> (ExplicitMetadataValue) () -> new SynchedEntityData.DataItem<>(DATA_CUSTOM_NAME_VISIBLE, true);
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package de.epiceric.shopchest.nms.v1_18_R2.metadata;
|
||||
|
||||
import de.epiceric.shopchest.nms.metadata.MetadataValue;
|
||||
import net.minecraft.network.syncher.SynchedEntityData;
|
||||
|
||||
public interface ExplicitMetadataValue extends MetadataValue {
|
||||
|
||||
SynchedEntityData.DataItem<?> toNMS();
|
||||
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package de.epiceric.shopchest.nms.v1_18_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_18_R2.inventory.CraftItemStack;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class ItemMetadataProperties implements MetadataProperties.Item {
|
||||
|
||||
private final static EntityDataAccessor<net.minecraft.world.item.ItemStack> DATA_ITEM;
|
||||
|
||||
static {
|
||||
try {
|
||||
DATA_ITEM = ReflectionUtils.forceCast(ReflectionUtils.getPrivateStaticFieldValue(ItemEntity.class, "c"));
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public MetadataProperty<ItemStack> item() {
|
||||
return value -> (ExplicitMetadataValue) () -> new SynchedEntityData.DataItem<>(DATA_ITEM, CraftItemStack.asNMSCopy(value));
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package de.epiceric.shopchest.nms.v1_18_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();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user