From ae3fb6d770f28cf86191abd51b541401b81a6339 Mon Sep 17 00:00:00 2001 From: Oliver <79666085+OliverSchlueter@users.noreply.github.com> Date: Tue, 7 May 2024 14:22:57 +0200 Subject: [PATCH] Add support for 1.20.5 and 1.20.6 (#83) --- README.md | 2 +- api/build.gradle.kts | 2 +- build.gradle.kts | 35 ++- gradle/wrapper/gradle-wrapper.properties | 2 +- implementation_1_19_4/build.gradle.kts | 2 +- implementation_1_20_1/build.gradle.kts | 2 +- implementation_1_20_2/build.gradle.kts | 2 +- implementation_1_20_4/build.gradle.kts | 2 +- implementation_1_20_6/build.gradle.kts | 35 +++ .../version/Hologram1_20_6.java | 267 ++++++++++++++++++ .../version/MappingKeys1_20_6.java | 20 ++ settings.gradle.kts | 1 + .../oliver/fancyholograms/FancyHolograms.java | 8 +- 13 files changed, 355 insertions(+), 25 deletions(-) create mode 100644 implementation_1_20_6/build.gradle.kts create mode 100644 implementation_1_20_6/src/main/java/de/oliver/fancyholograms/version/Hologram1_20_6.java create mode 100644 implementation_1_20_6/src/main/java/de/oliver/fancyholograms/version/MappingKeys1_20_6.java diff --git a/README.md b/README.md index 7386d12b..c95bb5ee 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ It is lightweight and fast (using [packets](https://wiki.vg/Protocol)). PlaceholderAPI and MiniPlaceholders is supported. -**Only for minecraft server versions 1.19.4 - 1.20.4**
+**Only for minecraft server versions 1.19.4 - 1.20.6**
_Using [paper](https://papermc.io/downloads) is highly recommended_ ## Get the plugin diff --git a/api/build.gradle.kts b/api/build.gradle.kts index a95fdeb9..ee6d28f6 100644 --- a/api/build.gradle.kts +++ b/api/build.gradle.kts @@ -1,7 +1,7 @@ plugins { id("java-library") id("maven-publish") - id("com.github.johnrengelman.shadow") version "8.1.1" + id("io.github.goooler.shadow") version "8.1.7" } dependencies { diff --git a/build.gradle.kts b/build.gradle.kts index 404ce77d..21d225fe 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -5,8 +5,8 @@ plugins { id("java-library") id("maven-publish") - id("xyz.jpenilla.run-paper") version "2.2.2" - id("com.github.johnrengelman.shadow") version "8.1.1" + id("xyz.jpenilla.run-paper") version "2.2.4" + id("io.github.goooler.shadow") version "8.1.7" } runPaper.folia.registerTask() @@ -14,14 +14,15 @@ runPaper.folia.registerTask() allprojects { group = "de.oliver" val buildId = System.getenv("BUILD_ID") - version = "2.0.6" + (if (buildId != null) ".$buildId" else "") + version = "2.1.0-SNAPSHOT" + (if (buildId != null) ".$buildId" else "") description = "Simple, lightweight and fast hologram plugin using display entities" repositories { mavenCentral() - maven(url = "https://papermc.io/repo/repository/maven-public/") + maven(url = "https://repo.papermc.io/repository/maven-public/") + maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") maven(url = "https://repo.fancyplugins.de/snapshots") maven(url = "https://repo.smrt-1.com/releases") @@ -33,6 +34,7 @@ dependencies { compileOnly("io.papermc.paper:paper-api:${findProperty("minecraftVersion")}-R0.1-SNAPSHOT") implementation(project(":api")) + implementation(project(":implementation_1_20_6", configuration = "reobf")) implementation(project(":implementation_1_20_4", configuration = "reobf")) implementation(project(":implementation_1_20_2", configuration = "reobf")) implementation(project(":implementation_1_20_1", configuration = "reobf")) @@ -54,20 +56,21 @@ tasks { dependsOn(":api:shadowJar") - relocate("me.dave.chatcolorhandler", "de.oliver.fancyholograms.libs.chatcolorhandler") +// relocate("me.dave.chatcolorhandler", "de.oliver.fancyholograms.libs.chatcolorhandler") relocate("io.sentry", "de.oliver.fancyholograms.libs.sentry") } runServer { - minecraftVersion(findProperty("minecraftVersion").toString()) +// minecraftVersion(findProperty("minecraftVersion").toString()) + minecraftVersion("1.20.6") downloadPlugins { - hangar("FancyNpcs", findProperty("fancyNpcsVersion").toString()) - hangar("PlaceholderAPI", "2.11.5") - modrinth("miniplaceholders", "M6gjRuIx") - - hangar("ViaVersion", "4.9.3-SNAPSHOT+216") - hangar("ViaBackwards", "4.9.2-SNAPSHOT+131") +// hangar("FancyNpcs", findProperty("fancyNpcsVersion").toString()) +// hangar("PlaceholderAPI", "2.11.5") +// modrinth("miniplaceholders", "M6gjRuIx") +// +// hangar("ViaVersion", "4.9.3-SNAPSHOT+216") +// hangar("ViaBackwards", "4.9.2-SNAPSHOT+131") } } @@ -124,11 +127,17 @@ tasks { expand(props) } } + + compileJava { + options.encoding = Charsets.UTF_8.name() // We want UTF-8 for everything + options.release = 21 + } + } java { toolchain { - languageVersion.set(JavaLanguageVersion.of(17)) + languageVersion.set(JavaLanguageVersion.of(21)) } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 59bc51a2..48c0a02c 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/implementation_1_19_4/build.gradle.kts b/implementation_1_19_4/build.gradle.kts index 6444d1b3..826693b9 100644 --- a/implementation_1_19_4/build.gradle.kts +++ b/implementation_1_19_4/build.gradle.kts @@ -1,6 +1,6 @@ plugins { id("java-library") - id("io.papermc.paperweight.userdev") version "1.5.11" + id("io.papermc.paperweight.userdev") version "1.6.2" } diff --git a/implementation_1_20_1/build.gradle.kts b/implementation_1_20_1/build.gradle.kts index b860f8d6..a9a0b15f 100644 --- a/implementation_1_20_1/build.gradle.kts +++ b/implementation_1_20_1/build.gradle.kts @@ -1,6 +1,6 @@ plugins { id("java-library") - id("io.papermc.paperweight.userdev") version "1.5.11" + id("io.papermc.paperweight.userdev") version "1.6.2" } diff --git a/implementation_1_20_2/build.gradle.kts b/implementation_1_20_2/build.gradle.kts index 7531bd95..02ce7b72 100644 --- a/implementation_1_20_2/build.gradle.kts +++ b/implementation_1_20_2/build.gradle.kts @@ -1,6 +1,6 @@ plugins { id("java-library") - id("io.papermc.paperweight.userdev") version "1.5.11" + id("io.papermc.paperweight.userdev") version "1.6.2" } diff --git a/implementation_1_20_4/build.gradle.kts b/implementation_1_20_4/build.gradle.kts index e5a80b9c..5a476c9d 100644 --- a/implementation_1_20_4/build.gradle.kts +++ b/implementation_1_20_4/build.gradle.kts @@ -1,6 +1,6 @@ plugins { id("java-library") - id("io.papermc.paperweight.userdev") version "1.5.11" + id("io.papermc.paperweight.userdev") version "1.6.2" } diff --git a/implementation_1_20_6/build.gradle.kts b/implementation_1_20_6/build.gradle.kts new file mode 100644 index 00000000..7fb5350f --- /dev/null +++ b/implementation_1_20_6/build.gradle.kts @@ -0,0 +1,35 @@ +plugins { + id("java-library") + id("io.papermc.paperweight.userdev") version "1.6.2" +} + + +val minecraftVersion = "1.20.6" + +paperweight.reobfArtifactConfiguration = io.papermc.paperweight.userdev.ReobfArtifactConfiguration.MOJANG_PRODUCTION + + +dependencies { + paperweight.paperDevBundle("$minecraftVersion-R0.1-SNAPSHOT") + + implementation(project(":api")) + implementation("de.oliver:FancyLib:${findProperty("fancyLibVersion")}") + compileOnly("com.viaversion:viaversion-api:${findProperty("viaversionVersion")}") +} + + +tasks { + named("assemble") { + dependsOn(named("reobfJar")) + } + + javadoc { + options.encoding = Charsets.UTF_8.name() + } + + compileJava { + options.encoding = Charsets.UTF_8.name() + + options.release.set(21) + } +} \ No newline at end of file diff --git a/implementation_1_20_6/src/main/java/de/oliver/fancyholograms/version/Hologram1_20_6.java b/implementation_1_20_6/src/main/java/de/oliver/fancyholograms/version/Hologram1_20_6.java new file mode 100644 index 00000000..83440d71 --- /dev/null +++ b/implementation_1_20_6/src/main/java/de/oliver/fancyholograms/version/Hologram1_20_6.java @@ -0,0 +1,267 @@ +package de.oliver.fancyholograms.version; + +import com.mojang.math.Transformation; +import com.viaversion.viaversion.api.Via; +import de.oliver.fancyholograms.api.FancyHologramsPlugin; +import de.oliver.fancyholograms.api.Hologram; +import de.oliver.fancyholograms.api.data.BlockHologramData; +import de.oliver.fancyholograms.api.data.HologramData; +import de.oliver.fancyholograms.api.data.ItemHologramData; +import de.oliver.fancyholograms.api.data.TextHologramData; +import de.oliver.fancyholograms.api.events.HologramHideEvent; +import de.oliver.fancyholograms.api.events.HologramShowEvent; +import de.oliver.fancylib.ReflectionUtils; +import io.papermc.paper.adventure.PaperAdventure; +import net.minecraft.core.registries.BuiltInRegistries; +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.syncher.SynchedEntityData; +import net.minecraft.network.syncher.SynchedEntityData.DataValue; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.util.Brightness; +import net.minecraft.world.entity.Display; +import net.minecraft.world.entity.Display.TextDisplay; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.Block; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.joml.Quaternionf; + +import java.util.ArrayList; + +import static de.oliver.fancylib.ReflectionUtils.getValue; + +public final class Hologram1_20_6 extends Hologram { + + @Nullable + private Display display; + + public Hologram1_20_6(@NotNull final HologramData data) { + super(data); + } + + @Override + public org.bukkit.entity.@Nullable Display getDisplayEntity() { + if (display == null) return null; + return (org.bukkit.entity.Display) display.getBukkitEntity(); + } + + @Override + public void create() { + final var location = data.getDisplayData().getLocation(); + if (location == null || location.getWorld() == null) { + return; // no location data, cannot be created + } + + ServerLevel world = ((CraftWorld) location.getWorld()).getHandle(); + + switch (data.getType()) { + case TEXT -> this.display = new Display.TextDisplay(EntityType.TEXT_DISPLAY, world); + case BLOCK -> this.display = new Display.BlockDisplay(EntityType.BLOCK_DISPLAY, world); + case ITEM -> this.display = new Display.ItemDisplay(EntityType.ITEM_DISPLAY, world); + } + + final var DATA_TRANSFORMATION_INTERPOLATION_DURATION_ID = ReflectionUtils.getStaticValue(Display.class, MappingKeys1_20_6.DISPLAY__DATA_TRANSFORMATION_INTERPOLATION_DURATION_ID.getMapping()); + display.getEntityData().set((EntityDataAccessor) DATA_TRANSFORMATION_INTERPOLATION_DURATION_ID, 1); + + final var DATA_TRANSFORMATION_INTERPOLATION_START_DELTA_TICKS_ID = ReflectionUtils.getStaticValue(Display.class, MappingKeys1_20_6.DISPLAY__DATA_TRANSFORMATION_INTERPOLATION_START_DELTA_TICKS_ID.getMapping()); + display.getEntityData().set((EntityDataAccessor) DATA_TRANSFORMATION_INTERPOLATION_START_DELTA_TICKS_ID, 0); + + updateHologram(); + } + + @Override + public void delete() { + this.display = null; + } + + @Override + public void update() { + final var display = this.display; + if (display == null) { + return; // doesn't exist, nothing to update + } + + // location data + final var location = data.getDisplayData().getLocation(); + if (location == null || location.getWorld() == null || !location.isWorldLoaded()) { + return; + } else { + display.setPosRaw(location.x(), location.y(), location.z()); + display.setYRot(location.getYaw()); + display.setXRot(location.getPitch()); + } + + + // billboard data + display.setBillboardConstraints(switch (data.getDisplayData().getBillboard()) { + case FIXED -> Display.BillboardConstraints.FIXED; + case VERTICAL -> Display.BillboardConstraints.VERTICAL; + case HORIZONTAL -> Display.BillboardConstraints.HORIZONTAL; + case CENTER -> Display.BillboardConstraints.CENTER; + }); + + + if (display instanceof TextDisplay textDisplay && data.getTypeData() instanceof TextHologramData textData) { + // line width + final var DATA_LINE_WIDTH_ID = ReflectionUtils.getStaticValue(TextDisplay.class, MappingKeys1_20_6.TEXT_DISPLAY__DATA_LINE_WIDTH_ID.getMapping()); + display.getEntityData().set((EntityDataAccessor) DATA_LINE_WIDTH_ID, Hologram.LINE_WIDTH); + + // background + final var DATA_BACKGROUND_COLOR_ID = ReflectionUtils.getStaticValue(TextDisplay.class, MappingKeys1_20_6.TEXT_DISPLAY__DATA_BACKGROUND_COLOR_ID.getMapping()); + + final var background = textData.getBackground(); + if (background == null) { + display.getEntityData().set((EntityDataAccessor) DATA_BACKGROUND_COLOR_ID, TextDisplay.INITIAL_BACKGROUND); + } else if (background == Hologram.TRANSPARENT) { + display.getEntityData().set((EntityDataAccessor) DATA_BACKGROUND_COLOR_ID, 0); + } else { + display.getEntityData().set((EntityDataAccessor) DATA_BACKGROUND_COLOR_ID, background.value() | 0xC8000000); + } + + // text shadow + if (textData.isTextShadow()) { + textDisplay.setFlags((byte) (textDisplay.getFlags() | TextDisplay.FLAG_SHADOW)); + } else { + textDisplay.setFlags((byte) (textDisplay.getFlags() & ~TextDisplay.FLAG_SHADOW)); + } + + // see through + if (textData.isSeeThrough()) { + textDisplay.setFlags((byte) (textDisplay.getFlags() | TextDisplay.FLAG_SEE_THROUGH)); + } else { + textDisplay.setFlags((byte) (textDisplay.getFlags() & ~TextDisplay.FLAG_SEE_THROUGH)); + } + + // text alignment + if (textData.getTextAlignment() == org.bukkit.entity.TextDisplay.TextAlignment.LEFT) { + textDisplay.setFlags((byte) (textDisplay.getFlags() | TextDisplay.FLAG_ALIGN_LEFT)); + } else { + textDisplay.setFlags((byte) (textDisplay.getFlags() & ~TextDisplay.FLAG_ALIGN_LEFT)); + } + + if (textData.getTextAlignment() == org.bukkit.entity.TextDisplay.TextAlignment.RIGHT) { + textDisplay.setFlags((byte) (textDisplay.getFlags() | TextDisplay.FLAG_ALIGN_RIGHT)); + } else { + textDisplay.setFlags((byte) (textDisplay.getFlags() & ~TextDisplay.FLAG_ALIGN_RIGHT)); + } + + } else if (display instanceof Display.ItemDisplay itemDisplay && data.getTypeData() instanceof ItemHologramData itemData) { + // item + itemDisplay.setItemStack(ItemStack.fromBukkitCopy(itemData.getItem())); + + } else if (display instanceof Display.BlockDisplay blockDisplay && data.getTypeData() instanceof BlockHologramData blockData) { + Block block = BuiltInRegistries.BLOCK.get(ResourceLocation.of("minecraft:" + blockData.getBlock().name().toLowerCase(), ':')); + blockDisplay.setBlockState(block.defaultBlockState()); + } + + // brightness + if (data.getDisplayData().getBrightness() != null) { + display.setBrightnessOverride(new Brightness(data.getDisplayData().getBrightness().getBlockLight(), + data.getDisplayData().getBrightness().getSkyLight())); + } + + // entity scale AND MORE! + display.setTransformation(new Transformation( + data.getDisplayData().getTranslation(), + new Quaternionf(), + data.getDisplayData().getScale(), + new Quaternionf()) + ); + + + // entity shadow + display.setShadowRadius(data.getDisplayData().getShadowRadius()); + display.setShadowStrength(data.getDisplayData().getShadowStrength()); + } + + + @Override + public boolean show(@NotNull final Player player) { + if (!new HologramShowEvent(this, player).callEvent()) { + return false; + } + + if (this.display == null) { + create(); // try to create it if it doesn't exist every time + } + + final var display = this.display; + if (display == null) { + return false; // could not be created, nothing to show + } + + if (!data.getDisplayData().getLocation().getWorld().getName().equals(player.getLocation().getWorld().getName())) { + return false; + } + + ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle(); + + // TODO: cache player protocol version + final var protocolVersion = FancyHologramsPlugin.get().isUsingViaVersion() ? Via.getAPI().getPlayerVersion(player) : MINIMUM_PROTOCOL_VERSION; + if (protocolVersion < MINIMUM_PROTOCOL_VERSION) { + return false; + } + + serverPlayer.connection.send(new ClientboundAddEntityPacket(display)); + this.shown.add(player.getUniqueId()); + refreshHologram(player); + + return true; + } + + @Override + public boolean hide(@NotNull final Player player) { + if (!new HologramHideEvent(this, player).callEvent()) { + return false; + } + + final var display = this.display; + if (display == null) { + return false; // doesn't exist, nothing to hide + } + + ((CraftPlayer) player).getHandle().connection.send(new ClientboundRemoveEntitiesPacket(display.getId())); + + this.shown.remove(player.getUniqueId()); + return true; + } + + + @Override + public void refresh(@NotNull final Player player) { + final var display = this.display; + if (display == null) { + return; // doesn't exist, nothing to refresh + } + + if (!isShown(player)) { + return; + } + + ((CraftPlayer) player).getHandle().connection.send(new ClientboundTeleportEntityPacket(display)); + + if (display instanceof TextDisplay textDisplay) { + textDisplay.setText(PaperAdventure.asVanilla(getShownText(player))); + } + + final var values = new ArrayList>(); + + //noinspection unchecked + for (final var item : ((SynchedEntityData.DataItem[]) getValue(display.getEntityData(), "itemsById"))) { + values.add(item.value()); + } + + ((CraftPlayer) player).getHandle().connection.send(new ClientboundSetEntityDataPacket(display.getId(), values)); + } + +} diff --git a/implementation_1_20_6/src/main/java/de/oliver/fancyholograms/version/MappingKeys1_20_6.java b/implementation_1_20_6/src/main/java/de/oliver/fancyholograms/version/MappingKeys1_20_6.java new file mode 100644 index 00000000..afc1a228 --- /dev/null +++ b/implementation_1_20_6/src/main/java/de/oliver/fancyholograms/version/MappingKeys1_20_6.java @@ -0,0 +1,20 @@ +package de.oliver.fancyholograms.version; + +public enum MappingKeys1_20_6 { + + DISPLAY__DATA_TRANSFORMATION_INTERPOLATION_DURATION_ID("DATA_TRANSFORMATION_INTERPOLATION_DURATION_ID"), + DISPLAY__DATA_TRANSFORMATION_INTERPOLATION_START_DELTA_TICKS_ID("DATA_TRANSFORMATION_INTERPOLATION_START_DELTA_TICKS_ID"), + TEXT_DISPLAY__DATA_LINE_WIDTH_ID("DATA_LINE_WIDTH_ID"), + TEXT_DISPLAY__DATA_BACKGROUND_COLOR_ID("DATA_BACKGROUND_COLOR_ID"), + ; + + private final String mapping; + + MappingKeys1_20_6(String mapping) { + this.mapping = mapping; + } + + public String getMapping() { + return mapping; + } +} diff --git a/settings.gradle.kts b/settings.gradle.kts index 854f7dd2..58a8d006 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,6 +1,7 @@ rootProject.name = "FancyHolograms" include("api") +include("implementation_1_20_6") include("implementation_1_20_4") include("implementation_1_20_2") include("implementation_1_20_1") diff --git a/src/main/java/de/oliver/fancyholograms/FancyHolograms.java b/src/main/java/de/oliver/fancyholograms/FancyHolograms.java index 01d22150..432b3334 100644 --- a/src/main/java/de/oliver/fancyholograms/FancyHolograms.java +++ b/src/main/java/de/oliver/fancyholograms/FancyHolograms.java @@ -9,10 +9,7 @@ import de.oliver.fancyholograms.listeners.NpcListener; import de.oliver.fancyholograms.listeners.PlayerListener; import de.oliver.fancyholograms.storage.FlatFileHologramStorage; -import de.oliver.fancyholograms.version.Hologram1_19_4; -import de.oliver.fancyholograms.version.Hologram1_20_1; -import de.oliver.fancyholograms.version.Hologram1_20_2; -import de.oliver.fancyholograms.version.Hologram1_20_4; +import de.oliver.fancyholograms.version.*; import de.oliver.fancylib.FancyLib; import de.oliver.fancylib.Metrics; import de.oliver.fancylib.VersionConfig; @@ -41,7 +38,7 @@ public final class FancyHolograms extends JavaPlugin implements FancyHologramsPlugin { - public static final String[] SUPPORTED_VERSIONS = {"1.19.4", "1.20", "1.20.1", "1.20.2", "1.20.3", "1.20.4"}; + public static final String[] SUPPORTED_VERSIONS = {"1.19.4", "1.20", "1.20.1", "1.20.2", "1.20.3", "1.20.4", "1.20.5", "1.20.6"}; @Nullable @@ -204,6 +201,7 @@ public ExecutorService getFileStorageExecutor() { final var version = Bukkit.getMinecraftVersion(); return switch (version) { + case "1.20.5", "1.20.6" -> Hologram1_20_6::new; case "1.20.3", "1.20.4" -> Hologram1_20_4::new; case "1.20.2" -> Hologram1_20_2::new; case "1.20", "1.20.1" -> Hologram1_20_1::new;