From 5f0b25c41294f44c8c6ed2d3d9766230a369d0fa Mon Sep 17 00:00:00 2001 From: Flowsqy <47575244+Flowsqy@users.noreply.github.com> Date: Wed, 29 Dec 2021 20:29:43 +0100 Subject: [PATCH] Add implementation for FakeArmorStand in reflection --- .../nms/reflection/FakeArmorStandImpl.java | 59 ++++++++++++++++++- .../nms/reflection/FakeEntityImpl.java | 23 +++++--- 2 files changed, 72 insertions(+), 10 deletions(-) diff --git a/nms/reflection/src/main/java/de/epiceric/shopchest/nms/reflection/FakeArmorStandImpl.java b/nms/reflection/src/main/java/de/epiceric/shopchest/nms/reflection/FakeArmorStandImpl.java index 6f3d86e..e0cba98 100644 --- a/nms/reflection/src/main/java/de/epiceric/shopchest/nms/reflection/FakeArmorStandImpl.java +++ b/nms/reflection/src/main/java/de/epiceric/shopchest/nms/reflection/FakeArmorStandImpl.java @@ -2,21 +2,78 @@ package de.epiceric.shopchest.nms.reflection; import de.epiceric.shopchest.nms.FakeArmorStand; import org.bukkit.Location; +import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; +import java.lang.reflect.Field; +import java.util.UUID; + public class FakeArmorStandImpl extends FakeEntityImpl implements FakeArmorStand { + private final Class packetPlayOutEntityTeleportClass = nmsClassResolver.resolveSilent("network.protocol.game.PacketPlayOutEntityTeleport"); + public FakeArmorStandImpl(ShopChestDebug debug) { super(debug); } @Override public void sendData(String name, Iterable receivers) { - + Object dataWatcher = ReflectionUtils.createDataWatcher(debug, name, null); + try { + for (Player receiver : receivers) { + ReflectionUtils.sendPacket(debug, packetPlayOutEntityMetadataClass.getConstructor(int.class, dataWatcherClass, boolean.class) + .newInstance(entityId, dataWatcher, true), receiver); + } + } catch (ReflectiveOperationException e) { + // TODO Handle this properly + throw new RuntimeException(e); + } } @Override public void setLocation(Location location, Iterable receivers) { + double y = location.getY() + (ReflectionUtils.getServerVersion().equals("v1_8_R1") ? 0 : 1.975); + try { + Object packet = packetPlayOutEntityTeleportClass.getConstructor().newInstance(); + Field[] fields = packetPlayOutEntityTeleportClass.getDeclaredFields(); + for (Field field : fields) { + field.setAccessible(true); + } + boolean isPre9 = ReflectionUtils.getMajorVersion() < 9; + fields[0].set(packet, entityId); + + if (isPre9) { + fields[1].set(packet, (int)(location.getX() * 32)); + fields[2].set(packet, (int)(y * 32)); + fields[3].set(packet, (int)(location.getZ() * 32)); + } else { + fields[1].set(packet, location.getX()); + fields[2].set(packet, y); + fields[3].set(packet, location.getZ()); + } + fields[4].set(packet, (byte) 0); + fields[5].set(packet, (byte) 0); + fields[6].set(packet, true); + + if (packet == null) { + debug.getLogger().severe("Could not set hologram location"); + debug.debug("Could not set armor stand location: Packet is null"); + return; + } + + for (Player receiver : receivers) { + ReflectionUtils.sendPacket(debug, packet, receiver); + } + }catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } + + @Override + public void spawn(UUID uuid, Location location, Iterable receivers) { + for(Player receiver : receivers) { + ReflectionUtils.sendPacket(debug, ReflectionUtils.createPacketSpawnEntity(debug, entityId, uuid, location, EntityType.ARMOR_STAND), receiver); + } } } diff --git a/nms/reflection/src/main/java/de/epiceric/shopchest/nms/reflection/FakeEntityImpl.java b/nms/reflection/src/main/java/de/epiceric/shopchest/nms/reflection/FakeEntityImpl.java index 8d59d69..27152fb 100644 --- a/nms/reflection/src/main/java/de/epiceric/shopchest/nms/reflection/FakeEntityImpl.java +++ b/nms/reflection/src/main/java/de/epiceric/shopchest/nms/reflection/FakeEntityImpl.java @@ -1,12 +1,15 @@ package de.epiceric.shopchest.nms.reflection; import de.epiceric.shopchest.nms.FakeEntity; -import org.bukkit.Location; import org.bukkit.entity.Player; +import org.inventivetalent.reflection.resolver.minecraft.NMSClassResolver; -import java.util.UUID; +public abstract class FakeEntityImpl implements FakeEntity { -public class FakeEntityImpl implements FakeEntity { + protected final NMSClassResolver nmsClassResolver = new NMSClassResolver(); + private final Class packetPlayOutEntityDestroyClass = nmsClassResolver.resolveSilent("network.protocol.game.PacketPlayOutEntityDestroy"); + protected final Class packetPlayOutEntityMetadataClass = nmsClassResolver.resolveSilent("network.protocol.game.PacketPlayOutEntityMetadata"); + protected final Class dataWatcherClass = nmsClassResolver.resolveSilent("network.syncher.DataWatcher"); protected final int entityId; protected final ShopChestDebug debug; @@ -21,13 +24,15 @@ public class FakeEntityImpl implements FakeEntity { return entityId; } - @Override - public void spawn(UUID uuid, Location location, Iterable receivers) { - - } - @Override public void remove(Iterable receivers) { - + try { + for(Player receiver : receivers) { + ReflectionUtils.sendPacket(debug, packetPlayOutEntityDestroyClass.getConstructor(int[].class).newInstance((Object) new int[]{entityId}), receiver); + } + } catch (ReflectiveOperationException e){ + // TODO Handle this properly + throw new RuntimeException(e); + } } }