diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RBlockDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RBlockDisplay.java new file mode 100644 index 00000000..a349e8c0 --- /dev/null +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RBlockDisplay.java @@ -0,0 +1,30 @@ +package de.steamwar.entity; + +import com.comphenix.tinyprotocol.Reflection; +import de.steamwar.core.BountifulWrapper; +import de.steamwar.core.Core; +import lombok.Getter; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.data.BlockData; +import org.bukkit.entity.EntityType; + +public class RBlockDisplay extends RDisplay { + + @Getter + private BlockData block = Material.AIR.createBlockData(); + + public RBlockDisplay(REntityServer server, Location location) { + super(server, EntityType.BLOCK_DISPLAY, location); + } + + private static final Class iBlockDataClass = Reflection.getClass("{nms.world}.level.block.state.IBlockData"); + private static final Reflection.MethodInvoker getState = Reflection.getTypedMethod(Reflection.getClass("{obc}.block.data.CraftBlockData"), "getState", iBlockDataClass); + private static final Object blockWatcher = BountifulWrapper.impl.getDataWatcherObject(23, iBlockDataClass); + public void setBlock(BlockData block) { + this.block = block; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(blockWatcher, getState.invoke(block))); + } + } +} diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RDisplay.java new file mode 100644 index 00000000..2cc86492 --- /dev/null +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RDisplay.java @@ -0,0 +1,154 @@ +package de.steamwar.entity; + +import de.steamwar.core.BountifulWrapper; +import de.steamwar.core.Core; +import lombok.Getter; +import lombok.NonNull; +import org.bukkit.Color; +import org.bukkit.Location; +import org.bukkit.entity.Display; +import org.bukkit.entity.EntityType; +import org.bukkit.util.Transformation; +import org.joml.Quaternionf; +import org.joml.Vector3f; + +public class RDisplay extends REntity { + + @Getter + private Transformation transform = new Transformation(new Vector3f(), new Quaternionf(0, 0, 0, 1), new Vector3f(1, 1, 1), new Quaternionf(0, 0, 0, 1)); + + @Getter + private int interpolationDuration = 0; + + @Getter + private float viewRange = 1.0F; + + @Getter + private float shadowRadius = 0.0F; + + @Getter + private float shadowStrength = 1.0F; + + @Getter + private float displayWidth = 0.0F; + + @Getter + private float displayHeight = 0.0F; + + @Getter + private int interpolationDelay = 0; + + @Getter + private Display.Billboard billboard = Display.Billboard.FIXED; + + @Getter + private Color glowColorOverride = null; + + @Getter + private Display.Brightness brightness = null; + + protected RDisplay(REntityServer server, EntityType entityType, Location location) { + super(server, entityType, location); + } + + private static final Object translationWatcher = BountifulWrapper.impl.getDataWatcherObject(10, Vector3f.class); + private static final Object leftRotationWatcher = BountifulWrapper.impl.getDataWatcherObject(12, Quaternionf.class); + private static final Object scaleWatcher = BountifulWrapper.impl.getDataWatcherObject(11, Vector3f.class); + private static final Object rightRotationWatcher = BountifulWrapper.impl.getDataWatcherObject(13, Quaternionf.class); + public void setTransform(@NonNull Transformation transform) { + this.transform = transform; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(translationWatcher, transform.getTranslation())); + server.updateEntity(this, getDataWatcherPacket(leftRotationWatcher, transform.getLeftRotation())); + server.updateEntity(this, getDataWatcherPacket(scaleWatcher, transform.getScale())); + server.updateEntity(this, getDataWatcherPacket(rightRotationWatcher, transform.getRightRotation())); + } + } + + private static final Object transformationInterpolationDurationWatcher = BountifulWrapper.impl.getDataWatcherObject(9, Integer.class); + private static final Object positionOrRotationInterpolationDurationWatcher = BountifulWrapper.impl.getDataWatcherObject(10, Integer.class); + public void setInterpolationDuration(int interpolationDuration) { + this.interpolationDuration = interpolationDuration; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(transformationInterpolationDurationWatcher, interpolationDuration)); + server.updateEntity(this, getDataWatcherPacket(positionOrRotationInterpolationDurationWatcher, interpolationDuration)); + } + } + + private static final Object viewRangeWatcher = BountifulWrapper.impl.getDataWatcherObject(17, Float.class); + public void setViewRange(float viewRange) { + this.viewRange = viewRange; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(viewRangeWatcher, viewRange)); + } + } + + private static final Object shadowRadiusWatcher = BountifulWrapper.impl.getDataWatcherObject(18, Float.class); + public void setShadowRadius(float shadowRadius) { + this.shadowRadius = shadowRadius; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(shadowRadiusWatcher, shadowRadius)); + } + } + + private static final Object shadowStrengthWatcher = BountifulWrapper.impl.getDataWatcherObject(19, Float.class); + public void setShadowStrength(float shadowStrength) { + this.shadowStrength = shadowStrength; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(shadowStrengthWatcher, shadowStrength)); + } + } + + private static final Object displayWidthWatcher = BountifulWrapper.impl.getDataWatcherObject(20, Float.class); + public void setDisplayWidth(float displayWidth) { + this.displayWidth = displayWidth; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(displayWidthWatcher, displayWidth)); + } + } + + private static final Object displayHeightWatcher = BountifulWrapper.impl.getDataWatcherObject(21, Float.class); + public void setDisplayHeight(float displayHeight) { + this.displayHeight = displayHeight; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(displayHeightWatcher, displayHeight)); + } + } + + private static final Object interpolationDelayWatcher = BountifulWrapper.impl.getDataWatcherObject(22, Integer.class); + public void setInterpolationDelay(int interpolationDelay) { + this.interpolationDelay = interpolationDelay; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(interpolationDelayWatcher, interpolationDelay)); + } + } + + private static final Object billboardWatcher = BountifulWrapper.impl.getDataWatcherObject(15, Byte.class); + public void setBillboard(Display.Billboard billboard) { + this.billboard = billboard; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(billboardWatcher, (byte) billboard.ordinal())); + } + } + + private static final Object glowColorOverrideWatcher = BountifulWrapper.impl.getDataWatcherObject(3, Integer.class); + public void setGlowColorOverride(Color glowColorOverride) { + this.glowColorOverride = glowColorOverride; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(glowColorOverrideWatcher, glowColorOverride == null ? -1 : glowColorOverride.asARGB())); + } + } + + private static final Object brightnessWatcher = BountifulWrapper.impl.getDataWatcherObject(16, Integer.class); + public void setBrightness(Display.Brightness brightness) { + this.brightness = brightness; + if (Core.getVersion() >= 20) { + if (brightness == null) { + server.updateEntity(this, getDataWatcherPacket(brightnessWatcher, -1)); + } else { + int brightnessData = brightness.getBlockLight() << 4 | brightness.getSkyLight() << 20; + server.updateEntity(this, getDataWatcherPacket(brightnessWatcher, brightnessData)); + } + } + } +} diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/REntity.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/REntity.java index e7ecb1a8..66c13c40 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/REntity.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/REntity.java @@ -45,7 +45,7 @@ public class REntity { private static int entityIdCounter = -1; private static final Random random = new Random(); - private final REntityServer server; + protected final REntityServer server; private final EntityType entityType; @Getter protected final int entityId; diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RItemDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RItemDisplay.java new file mode 100644 index 00000000..c45db756 --- /dev/null +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RItemDisplay.java @@ -0,0 +1,41 @@ +package de.steamwar.entity; + +import com.comphenix.tinyprotocol.Reflection; +import de.steamwar.core.BountifulWrapper; +import de.steamwar.core.Core; +import lombok.Getter; +import org.bukkit.Location; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.ItemDisplay; +import org.bukkit.inventory.ItemStack; + +public class RItemDisplay extends RDisplay { + + @Getter + private ItemStack itemStack; + + @Getter + private ItemDisplay.ItemDisplayTransform itemDisplayTransform; + + public RItemDisplay(REntityServer server, Location location) { + super(server, EntityType.ITEM_DISPLAY, location); + } + + private static final Class itemStackClass = Reflection.getClass("{nms.world}.item.ItemStack"); + private static final Reflection.MethodInvoker asNMSCopy = Reflection.getTypedMethod(Reflection.getClass("{obc}.inventory.CraftItemStack"), "asNMSCopy", itemStackClass); + private static final Object itemStackWatcher = BountifulWrapper.impl.getDataWatcherObject(23, itemStackClass); + public void setItemStack(ItemStack itemStack) { + this.itemStack = itemStack; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(itemStackWatcher, asNMSCopy.invoke(itemStack))); + } + } + + private static final Object itemDisplayTransformWatcher = BountifulWrapper.impl.getDataWatcherObject(24, Byte.class); + public void setItemDisplayTransform(ItemDisplay.ItemDisplayTransform itemDisplayTransform) { + this.itemDisplayTransform = itemDisplayTransform; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(itemDisplayTransformWatcher, (byte) itemDisplayTransform.ordinal())); + } + } +} diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RTextDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RTextDisplay.java new file mode 100644 index 00000000..459dd9e8 --- /dev/null +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RTextDisplay.java @@ -0,0 +1,116 @@ +package de.steamwar.entity; + +import com.comphenix.tinyprotocol.Reflection; +import de.steamwar.core.BountifulWrapper; +import de.steamwar.core.ChatWrapper; +import de.steamwar.core.Core; +import lombok.Getter; +import org.bukkit.Location; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.TextDisplay; + +public class RTextDisplay extends RDisplay { + + @Getter + private String text = ""; + + @Getter + private int lineWidth = 200; + + @Getter + private byte textOpacity = (byte) -1; + + @Getter + private boolean shadowed = false; + + @Getter + private boolean seeThrough = false; + + @Getter + private boolean defaultBackground = false; + + @Getter + private TextDisplay.TextAlignment alignment = TextDisplay.TextAlignment.CENTER; + + public RTextDisplay(REntityServer server, Location location) { + super(server, EntityType.TEXT_DISPLAY, location); + } + + private static final Class iChatBaseComponent = Reflection.getClass("{nms.network.chat}.IChatBaseComponent"); + private static final Object textWatcher = BountifulWrapper.impl.getDataWatcherObject(23, iChatBaseComponent); + public void setText(String text) { + this.text = text; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(textWatcher, ChatWrapper.impl.stringToChatComponent(text))); + } + } + + private static final Object lineWidthWatcher = BountifulWrapper.impl.getDataWatcherObject(24, Integer.class); + public void setLineWidth(int lineWidth) { + this.lineWidth = lineWidth; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(lineWidthWatcher, lineWidth)); + } + } + + private static final Object textOpacityWatcher = BountifulWrapper.impl.getDataWatcherObject(26, Byte.class); + public void setTextOpacity(byte textOpacity) { + this.textOpacity = textOpacity; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(textOpacityWatcher, textOpacity)); + } + } + + private static final Object textStatusWatcher = BountifulWrapper.impl.getDataWatcherObject(27, Byte.class); + + public void setShadowed(boolean shadowed) { + this.shadowed = shadowed; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(textStatusWatcher, getTextStatus())); + } + } + + public void setSeeThrough(boolean seeThrough) { + this.seeThrough = seeThrough; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(textStatusWatcher, getTextStatus())); + } + } + + public void setDefaultBackground(boolean defaultBackground) { + this.defaultBackground = defaultBackground; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(textStatusWatcher, getTextStatus())); + } + } + + public void setAlignment(TextDisplay.TextAlignment alignment) { + this.alignment = alignment; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(textStatusWatcher, getTextStatus())); + } + } + + private byte getTextStatus() { + byte status = 0; + + if (shadowed) { + status |= 0x01; + } + if (seeThrough) { + status |= 0x02; + } + if (defaultBackground) { + status |= 0x04; + } + if (alignment == TextDisplay.TextAlignment.CENTER) { + // Do nothing + } else if (alignment == TextDisplay.TextAlignment.LEFT) { + status |= 0x08; + } else if (alignment == TextDisplay.TextAlignment.RIGHT) { + status |= 0x0F; + } + + return status; + } +}