From c9b266756d67fc08f28e99aea186ff676cb5611d Mon Sep 17 00:00:00 2001 From: vytskalt Date: Mon, 19 Feb 2024 17:07:11 +0200 Subject: [PATCH 01/13] prepare --- INSTALLATION.md | 11 ++++- .../implementation/PacketAdapterLoader.java | 27 +++++++++-- settings.gradle.kts | 5 ++- versions/protocollib/build.gradle.kts | 12 +++++ .../PacketAdapterProviderImpl.java | 45 +++++++++++++++++++ 5 files changed, 93 insertions(+), 7 deletions(-) create mode 100644 versions/protocollib/build.gradle.kts create mode 100644 versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/PacketAdapterProviderImpl.java diff --git a/INSTALLATION.md b/INSTALLATION.md index 8657b451..02b835f6 100644 --- a/INSTALLATION.md +++ b/INSTALLATION.md @@ -19,10 +19,11 @@ dependencies { val scoreboardLibraryVersion = "{VERSION HERE}" implementation("com.github.megavexnetwork.scoreboard-library:scoreboard-library-api:$scoreboardLibraryVersion") runtimeOnly("com.github.megavexnetwork.scoreboard-library:scoreboard-library-implementation:$scoreboardLibraryVersion") - implementation("com.github.megavexnetwork.scoreboard-library:scoreboard-library-extra-kotlin:$scoreboardLibraryVersion") // If using Kotlin + implementation("com.github.megavexnetwork.scoreboard-library:scoreboard-library-extra-kotlin:$scoreboardLibraryVersion") // Kotlin specific extensions (optional) // Add packet adapter implementations you want: runtimeOnly("com.github.megavexnetwork.scoreboard-library:scoreboard-library-modern:$scoreboardLibraryVersion") // 1.17+ + runtimeOnly("com.github.megavexnetwork.scoreboard-library:scoreboard-library-protocollib:$scoreboardLibraryVersion") // 1.8+ runtimeOnly("com.github.megavexnetwork.scoreboard-library:scoreboard-library-packetevents:$scoreboardLibraryVersion") // 1.8+ runtimeOnly("com.github.megavexnetwork.scoreboard-library:scoreboard-library-v1_8_R3:$scoreboardLibraryVersion") // 1.8 @@ -67,7 +68,7 @@ Then add the dependencies: {VERSION HERE} runtime - + com.github.megavexnetwork.scoreboard-library scoreboard-library-extra-kotlin @@ -81,6 +82,12 @@ Then add the dependencies: {VERSION HERE} runtime + + com.github.megavexnetwork.scoreboard-library + scoreboard-library-protocollib + {VERSION HERE} + runtime + com.github.megavexnetwork.scoreboard-library scoreboard-library-packetevents diff --git a/implementation/src/main/java/net/megavex/scoreboardlibrary/implementation/PacketAdapterLoader.java b/implementation/src/main/java/net/megavex/scoreboardlibrary/implementation/PacketAdapterLoader.java index 4200597f..95126eb5 100644 --- a/implementation/src/main/java/net/megavex/scoreboardlibrary/implementation/PacketAdapterLoader.java +++ b/implementation/src/main/java/net/megavex/scoreboardlibrary/implementation/PacketAdapterLoader.java @@ -3,6 +3,9 @@ import net.megavex.scoreboardlibrary.api.exception.NoPacketAdapterAvailableException; import net.megavex.scoreboardlibrary.implementation.packetAdapter.PacketAdapterProvider; import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginDescriptionFile; +import org.bukkit.plugin.java.JavaPlugin; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -32,6 +35,11 @@ private PacketAdapterLoader() { return nmsClass; } + Class plibClass = tryLoadProtocolLib(); + if (plibClass != null) { + return plibClass; + } + return tryLoadPacketEvents(); } @@ -61,15 +69,26 @@ private PacketAdapterLoader() { } } - private static @Nullable Class tryLoadPacketEvents() { - Class nmsClass = tryLoadImplementationClass("packetevents"); - if (nmsClass == null) { + private static @Nullable Class tryLoadProtocolLib() { + Plugin loaderPlugin = JavaPlugin.getProvidingPlugin(PacketAdapterLoader.class); + + Plugin plibPlugin = loaderPlugin.getServer().getPluginManager().getPlugin("ProtocolLib"); + if (plibPlugin == null) { + return null; + } + + PluginDescriptionFile d = loaderPlugin.getDescription(); + if (!d.getDepend().contains(plibPlugin.getName()) && !d.getSoftDepend().contains(plibPlugin.getName())) { return null; } + return tryLoadImplementationClass("protocollib"); + } + + private static @Nullable Class tryLoadPacketEvents() { try { Class.forName("com.github.retrooper.packetevents.PacketEvents"); - return nmsClass; + return tryLoadImplementationClass("packetevents"); } catch (ClassNotFoundException ignored) { return null; } diff --git a/settings.gradle.kts b/settings.gradle.kts index cd854a1c..d63591b2 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -3,7 +3,7 @@ rootProject.name = "scoreboard-library" include(":api") include(":commons") include(":implementation") -include("extra-kotlin") +include(":extra-kotlin") include(":packet-adapter-base") project(":packet-adapter-base").projectDir = file("versions/packet-adapter-base") @@ -11,6 +11,9 @@ project(":packet-adapter-base").projectDir = file("versions/packet-adapter-base" include(":packetevents") project(":packetevents").projectDir = file("versions/packetevents") +include(":protocollib") +project(":protocollib").projectDir = file("versions/protocollib") + include(":modern") project(":modern").projectDir = file("versions/modern") diff --git a/versions/protocollib/build.gradle.kts b/versions/protocollib/build.gradle.kts new file mode 100644 index 00000000..26bfaf0c --- /dev/null +++ b/versions/protocollib/build.gradle.kts @@ -0,0 +1,12 @@ +plugins { + id("net.megavex.scoreboardlibrary.publish-conventions") +} + +repositories { + maven("https://repo.dmulloy2.net/repository/public/") +} + +dependencies { + compileOnly(project(":scoreboard-library-packet-adapter-base")) + compileOnly("com.comphenix.protocol:ProtocolLib:5.1.0") +} diff --git a/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/PacketAdapterProviderImpl.java b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/PacketAdapterProviderImpl.java new file mode 100644 index 00000000..4eb0c2e3 --- /dev/null +++ b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/PacketAdapterProviderImpl.java @@ -0,0 +1,45 @@ +package net.megavex.scoreboardlibrary.implementation.packetAdapter.protocollib; + +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.ProtocolManager; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.utility.MinecraftVersion; +import net.megavex.scoreboardlibrary.implementation.packetAdapter.PacketAdapterProvider; +import net.megavex.scoreboardlibrary.implementation.packetAdapter.PacketSender; +import net.megavex.scoreboardlibrary.implementation.packetAdapter.objective.ObjectivePacketAdapter; +import net.megavex.scoreboardlibrary.implementation.packetAdapter.team.TeamsPacketAdapter; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +import java.util.Objects; + +@SuppressWarnings("unused") +public class PacketAdapterProviderImpl implements PacketAdapterProvider, PacketSender { + private final ProtocolManager pm; + private final boolean isLegacyVersion; + + public PacketAdapterProviderImpl() { + this.pm = Objects.requireNonNull(ProtocolLibrary.getProtocolManager()); + this.isLegacyVersion = !MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.AQUATIC_UPDATE); + } + + @Override + public @NotNull ObjectivePacketAdapter createObjectiveAdapter(@NotNull String objectiveName) { + throw new UnsupportedOperationException(); + } + + @Override + public @NotNull TeamsPacketAdapter createTeamPacketAdapter(@NotNull String teamName) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isLegacy(@NotNull Player player) { + return isLegacyVersion; + } + + @Override + public void sendPacket(Player player, PacketContainer packet) { + pm.sendServerPacket(player, packet); + } +} From 49f010feae853ee23e5da0e4770ec8eb496360c3 Mon Sep 17 00:00:00 2001 From: vytskalt Date: Mon, 19 Feb 2024 17:37:09 +0200 Subject: [PATCH 02/13] [ci skip] update docs --- INSTALLATION.md | 25 +++++++++++++++++++------ README.md | 12 +++++++----- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/INSTALLATION.md b/INSTALLATION.md index 02b835f6..63c31a6f 100644 --- a/INSTALLATION.md +++ b/INSTALLATION.md @@ -2,6 +2,19 @@ Latest version: `2.0.2` +## ProtocolLib + +If you're going to use the ProtocolLib packet adapter, make sure to add ProtocolLib as a `depend` or `softdepend` in your `plugin.yml`: +```yaml +depend: +- ProtocolLib +``` +or +```yaml +softdepend: +- ProtocolLib +``` + ## Gradle Make sure you have the Jitpack repository: @@ -27,19 +40,19 @@ dependencies { runtimeOnly("com.github.megavexnetwork.scoreboard-library:scoreboard-library-packetevents:$scoreboardLibraryVersion") // 1.8+ runtimeOnly("com.github.megavexnetwork.scoreboard-library:scoreboard-library-v1_8_R3:$scoreboardLibraryVersion") // 1.8 - // If using the PacketEvents implementation, scoreboard-library expects PacketEvents to be in the classpath. + // If using the PacketEvents adapter, scoreboard-library expects PacketEvents to be loaded in the classpath. // Follow either of: // - https://github.com/retrooper/packetevents/wiki/Depending-on-pre%E2%80%90built-PacketEvents // - https://github.com/retrooper/packetevents/wiki/Shading-PacketEvents // Example how to load PacketEvents in your plugin: // https://github.com/retrooper/packetevents-example/blob/24f0c842d47362aef122b794dea29b8fee113fa3/thread-safe-listener/src/main/java/main/Main.java - // If using the 1.8 version implementation, add Adventure as well: + // If targeting platforms that don't support native adventure, add it as well: implementation("net.kyori:adventure-platform-bukkit:4.0.1") } ``` -You will need to shade these dependencies and relocate them with something +You will need to shade these dependencies and relocate them using something like [Shadow](https://imperceptiblethoughts.com/shadow/). ## Maven @@ -102,7 +115,7 @@ Then add the dependencies: - + net.kyori adventure-platform-bukkit @@ -119,5 +132,5 @@ Then add the dependencies: ``` -You will need to shade these dependencies and relocate them with something +You will need to shade these dependencies and relocate them using something like [maven-shade-plugin](https://maven.apache.org/plugins/maven-shade-plugin/). diff --git a/README.md b/README.md index 4978bf4c..890ee753 100644 --- a/README.md +++ b/README.md @@ -20,14 +20,16 @@ Join the [Discord](https://discord.gg/v7nmTDTW8W) or create an issue for support - Works with `TranslatableComponent`s, meaning all components are automatically translated using `GlobalTranslator` for each players client locale (and automatically update whenever the player changes it in their settings) -## Packet Adapters +## Available Packet Adapters -- **modern.** Supports 1.17-1.20.4. Takes advantage of [Paper](https://papermc.io)'s native adventure support to improve - performance. [Spigot](https://www.spigotmc.org/) is also supported, but will have worse performance -- **PacketEvents.** Requires [PacketEvents 2.0](https://github.com/retrooper/packetevents/tree/2.0) to be loaded in the - classpath. Should work on all versions 1.8+ +- **modern.** Supports 1.17-1.20.4. Can take advantage of [Paper](https://papermc.io)'s native adventure support to be more efficient. +- **ProtocolLib**. Supports 1.8+. Requires [ProtocolLib](https://www.spigotmc.org/resources/protocollib.1997/) to be installed on the server. +- **PacketEvents.** Supports 1.8+. Requires [PacketEvents 2.0](https://github.com/retrooper/packetevents/tree/2.0) to be shaded or installed as a plugin. Can be less stable than ProtocolLib. - **1.8.8.** +> [!NOTE] +> You can add multiple packet adapters, the best one will automatically be picked depending on the server version. + ## Installation See installation instructions [here](https://github.com/MegavexNetwork/scoreboard-library/blob/dev/2.0/INSTALLATION.md) From 967397cff9c9c30fc250f80c4f93efb0fdc8015e Mon Sep 17 00:00:00 2001 From: vytskalt Date: Mon, 19 Feb 2024 17:45:56 +0200 Subject: [PATCH 03/13] [ci skip] again --- README.md | 10 +++++----- build.gradle.kts | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 890ee753..2e5d16fb 100644 --- a/README.md +++ b/README.md @@ -12,13 +12,13 @@ Join the [Discord](https://discord.gg/v7nmTDTW8W) or create an issue for support - Teams. Supports showing different properties (display name, prefix, entries etc.) of the same team to different players - Objectives. -- Doesn't require extra dependencies (assuming you're targeting the latest version of Paper) -- Packet-level, meaning it works with other scoreboard plugins (and is faster) +- Doesn't require extra dependencies (assuming you're targeting modern versions of Paper) +- Packet-level, meaning it works with other scoreboard plugins - Supports [Folia](https://github.com/PaperMC/Folia) -- Fully async. All packet work is done asynchronously so you can (but don't have to) use the library from the main +- Fully async. All packet work is done asynchronously, so you can use the library from the main thread without sacrificing any performance -- Works with `TranslatableComponent`s, meaning all components are automatically translated using `GlobalTranslator` for - each players client locale (and automatically update whenever the player changes it in their settings) +- Automatically works with `TranslatableComponent`s. All components are translated using `GlobalTranslator` for + each player's client locale and automatically update whenever the player changes it in their settings ## Available Packet Adapters diff --git a/build.gradle.kts b/build.gradle.kts index f2730374..c0319575 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,9 +3,9 @@ plugins { } allprojects { - version = "2.0.2" + version = "2.0.3-SNAPSHOT" group = "net.megavex" - description = "Powerful packet-level sidebar/teams library for Paper/Spigot servers" + description = "Powerful packet-level scoreboard library for Paper/Spigot servers" repositories { mavenCentral() From 371d0476d0d48239372685f348dc9c0eb946f9a3 Mon Sep 17 00:00:00 2001 From: vytskalt Date: Mon, 26 Feb 2024 20:02:02 +0200 Subject: [PATCH 04/13] [ci skip] implement objective adapter --- .../implementation/PacketAdapterLoader.java | 2 + versions/protocollib/build.gradle.kts | 3 +- .../ObjectivePacketAdapterImpl.java | 137 ++++++++++++++++++ .../PacketAdapterProviderImpl.java | 14 +- 4 files changed, 146 insertions(+), 10 deletions(-) create mode 100644 versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/ObjectivePacketAdapterImpl.java diff --git a/implementation/src/main/java/net/megavex/scoreboardlibrary/implementation/PacketAdapterLoader.java b/implementation/src/main/java/net/megavex/scoreboardlibrary/implementation/PacketAdapterLoader.java index 95126eb5..34dbfb5e 100644 --- a/implementation/src/main/java/net/megavex/scoreboardlibrary/implementation/PacketAdapterLoader.java +++ b/implementation/src/main/java/net/megavex/scoreboardlibrary/implementation/PacketAdapterLoader.java @@ -21,6 +21,8 @@ private PacketAdapterLoader() { throw new NoPacketAdapterAvailableException(); } + System.out.println("[scoreboard-library] Using packet adapter: " + nmsClass.getName()); + try { return (PacketAdapterProvider) nmsClass.getConstructors()[0].newInstance(); } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { diff --git a/versions/protocollib/build.gradle.kts b/versions/protocollib/build.gradle.kts index 26bfaf0c..afcd57a2 100644 --- a/versions/protocollib/build.gradle.kts +++ b/versions/protocollib/build.gradle.kts @@ -3,10 +3,11 @@ plugins { } repositories { + mavenLocal() // temporary maven("https://repo.dmulloy2.net/repository/public/") } dependencies { compileOnly(project(":scoreboard-library-packet-adapter-base")) - compileOnly("com.comphenix.protocol:ProtocolLib:5.1.0") + compileOnly("com.comphenix.protocol:ProtocolLib:5.2.0-SNAPSHOT") } diff --git a/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/ObjectivePacketAdapterImpl.java b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/ObjectivePacketAdapterImpl.java new file mode 100644 index 00000000..0472a297 --- /dev/null +++ b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/ObjectivePacketAdapterImpl.java @@ -0,0 +1,137 @@ +package net.megavex.scoreboardlibrary.implementation.packetAdapter.protocollib; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolManager; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.utility.MinecraftVersion; +import com.comphenix.protocol.wrappers.EnumWrappers; +import com.comphenix.protocol.wrappers.WrappedChatComponent; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.translation.GlobalTranslator; +import net.megavex.scoreboardlibrary.api.objective.ObjectiveDisplaySlot; +import net.megavex.scoreboardlibrary.api.objective.ObjectiveRenderType; +import net.megavex.scoreboardlibrary.implementation.commons.LegacyFormatUtil; +import net.megavex.scoreboardlibrary.implementation.packetAdapter.PacketSender; +import net.megavex.scoreboardlibrary.implementation.packetAdapter.PropertiesPacketType; +import net.megavex.scoreboardlibrary.implementation.packetAdapter.objective.ObjectiveConstants; +import net.megavex.scoreboardlibrary.implementation.packetAdapter.objective.ObjectivePacketAdapter; +import net.megavex.scoreboardlibrary.implementation.packetAdapter.util.LocalePacketUtil; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; + +import static net.kyori.adventure.text.serializer.gson.GsonComponentSerializer.gson; +import static net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection; + +public class ObjectivePacketAdapterImpl implements ObjectivePacketAdapter { + private static final EnumWrappers.DisplaySlot[] DISPLAY_SLOTS = EnumWrappers.DisplaySlot.values(); + + private final ProtocolManager pm; + private final String objectiveName; + private PacketContainer removePacket; + + public ObjectivePacketAdapterImpl(@NotNull ProtocolManager pm, @NotNull String objectiveName) { + this.pm = pm; + this.objectiveName = objectiveName; + } + + @Override + public void display(@NotNull Collection players, @NotNull ObjectiveDisplaySlot slot) { + PacketContainer packet = pm.createPacket(PacketType.Play.Server.SCOREBOARD_DISPLAY_OBJECTIVE); + packet.getStrings().write(0, objectiveName); + + int displaySlotIdx = ObjectiveConstants.displaySlotIndex(slot); + if (MinecraftVersion.getCurrentVersion().isAtLeast(new MinecraftVersion(1, 20, 2))) { + packet.getDisplaySlots().write(0, DISPLAY_SLOTS[displaySlotIdx]); + } else { + packet.getIntegers().write(0, displaySlotIdx); + } + + for (Player player : players) { + pm.sendServerPacket(player, packet); + } + } + + @Override + public void sendProperties(@NotNull Collection players, @NotNull PropertiesPacketType packetType, @NotNull Component value, @NotNull ObjectiveRenderType renderType) { + PacketSender sender = pm::sendServerPacket; + LocalePacketUtil.sendLocalePackets(sender, players, locale -> { + EnumWrappers.RenderType wrappedRenderType; + switch (renderType) { + case INTEGER: + wrappedRenderType = EnumWrappers.RenderType.INTEGER; + break; + case HEARTS: + wrappedRenderType = EnumWrappers.RenderType.HEARTS; + break; + default: + throw new IllegalStateException(); + } + + PacketContainer packet = pm.createPacket(PacketType.Play.Server.SCOREBOARD_OBJECTIVE); + packet.getIntegers().write(0, ObjectiveConstants.mode(packetType)); + packet.getStrings().write(0, objectiveName); + + Component translatedValue = GlobalTranslator.render(value, locale); + if (MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.AQUATIC_UPDATE)) { // TODO: DOUBLE CHECK IF CORRECT + WrappedChatComponent wrappedValue = WrappedChatComponent.fromJson(gson().serialize(translatedValue)); + packet.getChatComponents().write(0, wrappedValue); + } else { + String legacyValue = LegacyFormatUtil.limitLegacyText( + legacySection().serialize(translatedValue), + ObjectiveConstants.LEGACY_VALUE_CHAR_LIMIT + ); + packet.getStrings().write(1, legacyValue); + } + + packet.getRenderTypes().write(0, wrappedRenderType); + return packet; + }); + } + + @Override + public void remove(@NotNull Collection players) { + if (removePacket == null) { + removePacket = pm.createPacket(PacketType.Play.Server.SCOREBOARD_OBJECTIVE); + removePacket.getIntegers().write(0, ObjectiveConstants.MODE_REMOVE); + removePacket.getStrings().write(0, objectiveName); + } + + for (Player player : players) { + pm.sendServerPacket(player, removePacket); + } + } + + @Override + public void sendScore(@NotNull Collection players, @NotNull String entry, int value) { + PacketContainer packet = pm.createPacket(PacketType.Play.Server.SCOREBOARD_SCORE); + packet.getScoreboardActions().write(0, EnumWrappers.ScoreboardAction.CHANGE); + packet.getStrings().write(0, entry) + .write(1, objectiveName); + packet.getIntegers().write(0, value); + + for (Player player : players) { + pm.sendServerPacket(player, packet); + } + } + + @Override + public void removeScore(@NotNull Collection players, @NotNull String entry) { + PacketContainer packet; + if (MinecraftVersion.getCurrentVersion().isAtLeast(new MinecraftVersion(1, 20, 3))) { + packet = pm.createPacket(PacketType.Play.Server.RESET_SCORE); + packet.getStrings().write(0, entry) + .write(1, objectiveName); + } else { + packet = pm.createPacket(PacketType.Play.Server.SCOREBOARD_SCORE); + packet.getScoreboardActions().write(0, EnumWrappers.ScoreboardAction.REMOVE); + packet.getStrings().write(0, entry) + .write(1, objectiveName); + } + + for (Player player : players) { + pm.sendServerPacket(player, packet); + } + } +} diff --git a/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/PacketAdapterProviderImpl.java b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/PacketAdapterProviderImpl.java index 4eb0c2e3..43ae9764 100644 --- a/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/PacketAdapterProviderImpl.java +++ b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/PacketAdapterProviderImpl.java @@ -2,10 +2,9 @@ import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolManager; -import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.utility.MinecraftVersion; +import com.comphenix.protocol.wrappers.EnumWrappers; import net.megavex.scoreboardlibrary.implementation.packetAdapter.PacketAdapterProvider; -import net.megavex.scoreboardlibrary.implementation.packetAdapter.PacketSender; import net.megavex.scoreboardlibrary.implementation.packetAdapter.objective.ObjectivePacketAdapter; import net.megavex.scoreboardlibrary.implementation.packetAdapter.team.TeamsPacketAdapter; import org.bukkit.entity.Player; @@ -14,18 +13,20 @@ import java.util.Objects; @SuppressWarnings("unused") -public class PacketAdapterProviderImpl implements PacketAdapterProvider, PacketSender { +public class PacketAdapterProviderImpl implements PacketAdapterProvider { private final ProtocolManager pm; private final boolean isLegacyVersion; public PacketAdapterProviderImpl() { this.pm = Objects.requireNonNull(ProtocolLibrary.getProtocolManager()); this.isLegacyVersion = !MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.AQUATIC_UPDATE); + System.out.println("[scoreboard-library] Render type class = " + EnumWrappers.getRenderTypeClass()); + System.out.println("[scoreboard-library] Display slot class = " + EnumWrappers.getDisplaySlotClass()); } @Override public @NotNull ObjectivePacketAdapter createObjectiveAdapter(@NotNull String objectiveName) { - throw new UnsupportedOperationException(); + return new ObjectivePacketAdapterImpl(pm, objectiveName); } @Override @@ -37,9 +38,4 @@ public PacketAdapterProviderImpl() { public boolean isLegacy(@NotNull Player player) { return isLegacyVersion; } - - @Override - public void sendPacket(Player player, PacketContainer packet) { - pm.sendServerPacket(player, packet); - } } From 7ae65ccdae920ac28004a1d0bb53d7d7ade809cd Mon Sep 17 00:00:00 2001 From: vytskalt Date: Tue, 27 Feb 2024 19:33:45 +0200 Subject: [PATCH 05/13] [ci skip] implement subset of team packet adapter --- .../sidebar/line/locale/LegacyLocaleLine.java | 1 + .../sidebar/line/locale/ModernLocaleLine.java | 2 +- .../ObjectivePacketAdapterImpl.java | 2 +- .../PacketAdapterProviderImpl.java | 3 +- .../team/LegacyDisplayAdapter.java | 72 +++++++++++++++++++ .../team/ModernDisplayAdapter.java | 46 ++++++++++++ .../team/TeamsPacketAdapterImpl.java | 46 ++++++++++++ 7 files changed, 169 insertions(+), 3 deletions(-) create mode 100644 versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/team/LegacyDisplayAdapter.java create mode 100644 versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/team/ModernDisplayAdapter.java create mode 100644 versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/team/TeamsPacketAdapterImpl.java diff --git a/implementation/src/main/java/net/megavex/scoreboardlibrary/implementation/sidebar/line/locale/LegacyLocaleLine.java b/implementation/src/main/java/net/megavex/scoreboardlibrary/implementation/sidebar/line/locale/LegacyLocaleLine.java index 175c05fc..315b38d6 100644 --- a/implementation/src/main/java/net/megavex/scoreboardlibrary/implementation/sidebar/line/locale/LegacyLocaleLine.java +++ b/implementation/src/main/java/net/megavex/scoreboardlibrary/implementation/sidebar/line/locale/LegacyLocaleLine.java @@ -17,6 +17,7 @@ import static net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection; +// 1.12.2 and below class LegacyLocaleLine implements LocaleLine { private final GlobalLineInfo info; private final SidebarLineHandler handler; diff --git a/implementation/src/main/java/net/megavex/scoreboardlibrary/implementation/sidebar/line/locale/ModernLocaleLine.java b/implementation/src/main/java/net/megavex/scoreboardlibrary/implementation/sidebar/line/locale/ModernLocaleLine.java index 5d514fbf..ee7e3d90 100644 --- a/implementation/src/main/java/net/megavex/scoreboardlibrary/implementation/sidebar/line/locale/ModernLocaleLine.java +++ b/implementation/src/main/java/net/megavex/scoreboardlibrary/implementation/sidebar/line/locale/ModernLocaleLine.java @@ -13,7 +13,7 @@ import static net.kyori.adventure.text.Component.empty; -// Implementation for versions above 1.12.2 +// 1.13+ class ModernLocaleLine implements LocaleLine { private final GlobalLineInfo info; private final SidebarLineHandler handler; diff --git a/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/ObjectivePacketAdapterImpl.java b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/ObjectivePacketAdapterImpl.java index 0472a297..4866304e 100644 --- a/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/ObjectivePacketAdapterImpl.java +++ b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/ObjectivePacketAdapterImpl.java @@ -74,7 +74,7 @@ public void sendProperties(@NotNull Collection players, @NotNull Propert packet.getStrings().write(0, objectiveName); Component translatedValue = GlobalTranslator.render(value, locale); - if (MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.AQUATIC_UPDATE)) { // TODO: DOUBLE CHECK IF CORRECT + if (MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.AQUATIC_UPDATE)) { WrappedChatComponent wrappedValue = WrappedChatComponent.fromJson(gson().serialize(translatedValue)); packet.getChatComponents().write(0, wrappedValue); } else { diff --git a/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/PacketAdapterProviderImpl.java b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/PacketAdapterProviderImpl.java index 43ae9764..6406dbea 100644 --- a/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/PacketAdapterProviderImpl.java +++ b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/PacketAdapterProviderImpl.java @@ -6,6 +6,7 @@ import com.comphenix.protocol.wrappers.EnumWrappers; import net.megavex.scoreboardlibrary.implementation.packetAdapter.PacketAdapterProvider; import net.megavex.scoreboardlibrary.implementation.packetAdapter.objective.ObjectivePacketAdapter; +import net.megavex.scoreboardlibrary.implementation.packetAdapter.protocollib.team.TeamsPacketAdapterImpl; import net.megavex.scoreboardlibrary.implementation.packetAdapter.team.TeamsPacketAdapter; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; @@ -31,7 +32,7 @@ public PacketAdapterProviderImpl() { @Override public @NotNull TeamsPacketAdapter createTeamPacketAdapter(@NotNull String teamName) { - throw new UnsupportedOperationException(); + return new TeamsPacketAdapterImpl(pm, teamName); } @Override diff --git a/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/team/LegacyDisplayAdapter.java b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/team/LegacyDisplayAdapter.java new file mode 100644 index 00000000..742fe785 --- /dev/null +++ b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/team/LegacyDisplayAdapter.java @@ -0,0 +1,72 @@ +package net.megavex.scoreboardlibrary.implementation.packetAdapter.protocollib.team; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolManager; +import com.comphenix.protocol.events.PacketContainer; +import net.megavex.scoreboardlibrary.implementation.packetAdapter.ImmutableTeamProperties; +import net.megavex.scoreboardlibrary.implementation.packetAdapter.PropertiesPacketType; +import net.megavex.scoreboardlibrary.implementation.packetAdapter.team.EntriesPacketType; +import net.megavex.scoreboardlibrary.implementation.packetAdapter.team.TeamConstants; +import net.megavex.scoreboardlibrary.implementation.packetAdapter.team.TeamDisplayPacketAdapter; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; + +import static net.megavex.scoreboardlibrary.implementation.commons.LegacyFormatUtil.limitLegacyText; + +// 1.12.2 and below +public class LegacyDisplayAdapter implements TeamDisplayPacketAdapter { + private final ProtocolManager pm; + private final String teamName; + private final ImmutableTeamProperties properties; + + public LegacyDisplayAdapter(@NotNull ProtocolManager pm, @NotNull String teamName, @NotNull ImmutableTeamProperties properties) { + this.pm = pm; + this.teamName = teamName; + this.properties = properties; + } + + @Override + public void sendEntries(@NotNull EntriesPacketType packetType, @NotNull Collection players, @NotNull Collection entries) { + PacketContainer packet = pm.createPacket(PacketType.Play.Server.SCOREBOARD_TEAM); + packet.getIntegers().write(1, TeamConstants.mode(packetType)); + packet.getStrings().write(0, teamName); + packet.getSpecificModifier(Collection.class).write(0, entries); + + for (Player player : players) { + pm.sendServerPacket(player, packet); + } + } + + @Override + public void sendProperties(@NotNull PropertiesPacketType packetType, @NotNull Collection players) { + String displayName = limit(properties.displayName()); + String prefix = limit(properties.prefix()); + String suffix = limit(properties.suffix()); + + PacketContainer packet = pm.createPacket(PacketType.Play.Server.SCOREBOARD_TEAM); + packet.getIntegers() + .write(1, TeamConstants.mode(packetType)) + .write(2, properties.packOptions()); + + packet.getStrings() + .write(0, teamName) + .write(1, displayName) + .write(2, prefix) + .write(2, suffix) + .write(3, properties.nameTagVisibility().key()); + + if (packetType == PropertiesPacketType.CREATE) { + packet.getSpecificModifier(Collection.class).write(0, properties.entries()); + } + + for (Player player : players) { + pm.sendServerPacket(player, packet); + } + } + + private @NotNull String limit(@NotNull String msg) { + return limitLegacyText(msg, TeamConstants.LEGACY_CHAR_LIMIT); + } +} diff --git a/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/team/ModernDisplayAdapter.java b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/team/ModernDisplayAdapter.java new file mode 100644 index 00000000..bc0f80d1 --- /dev/null +++ b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/team/ModernDisplayAdapter.java @@ -0,0 +1,46 @@ +package net.megavex.scoreboardlibrary.implementation.packetAdapter.protocollib.team; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolManager; +import com.comphenix.protocol.events.PacketContainer; +import net.kyori.adventure.text.Component; +import net.megavex.scoreboardlibrary.implementation.packetAdapter.ImmutableTeamProperties; +import net.megavex.scoreboardlibrary.implementation.packetAdapter.PropertiesPacketType; +import net.megavex.scoreboardlibrary.implementation.packetAdapter.team.EntriesPacketType; +import net.megavex.scoreboardlibrary.implementation.packetAdapter.team.TeamConstants; +import net.megavex.scoreboardlibrary.implementation.packetAdapter.team.TeamDisplayPacketAdapter; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; + +// 1.13+ +public class ModernDisplayAdapter implements TeamDisplayPacketAdapter { + private final ProtocolManager pm; + private final String teamName; + private final ImmutableTeamProperties properties; + private PacketContainer removePacket; + + public ModernDisplayAdapter(@NotNull ProtocolManager pm, @NotNull String teamName, @NotNull ImmutableTeamProperties properties) { + this.pm = pm; + this.teamName = teamName; + this.properties = properties; + } + + @Override + public void sendEntries(@NotNull EntriesPacketType packetType, @NotNull Collection players, @NotNull Collection entries) { + PacketContainer packet = pm.createPacket(PacketType.Play.Server.SCOREBOARD_TEAM); + packet.getIntegers().write(0, TeamConstants.mode(packetType)); + packet.getStrings().write(0, teamName); + packet.getSpecificModifier(Collection.class).write(0, players); + + for (Player player : players) { + pm.sendServerPacket(player, packet); + } + } + + @Override + public void sendProperties(@NotNull PropertiesPacketType packetType, @NotNull Collection players) { + // TODO + } +} diff --git a/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/team/TeamsPacketAdapterImpl.java b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/team/TeamsPacketAdapterImpl.java new file mode 100644 index 00000000..d800de1a --- /dev/null +++ b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/team/TeamsPacketAdapterImpl.java @@ -0,0 +1,46 @@ +package net.megavex.scoreboardlibrary.implementation.packetAdapter.protocollib.team; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolManager; +import com.comphenix.protocol.events.PacketContainer; +import net.kyori.adventure.text.Component; +import net.megavex.scoreboardlibrary.implementation.packetAdapter.ImmutableTeamProperties; +import net.megavex.scoreboardlibrary.implementation.packetAdapter.team.TeamConstants; +import net.megavex.scoreboardlibrary.implementation.packetAdapter.team.TeamDisplayPacketAdapter; +import net.megavex.scoreboardlibrary.implementation.packetAdapter.team.TeamsPacketAdapter; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +public class TeamsPacketAdapterImpl implements TeamsPacketAdapter { + private final ProtocolManager pm; + private final String teamName; + private PacketContainer removePacket; + + public TeamsPacketAdapterImpl(@NotNull ProtocolManager pm, @NotNull String teamName) { + this.pm = pm; + this.teamName = teamName; + } + + @Override + public void removeTeam(@NotNull Iterable players) { + if (removePacket == null) { + removePacket = pm.createPacket(PacketType.Play.Server.SCOREBOARD_TEAM); + removePacket.getIntegers().write(1, TeamConstants.MODE_REMOVE); + removePacket.getStrings().write(0, teamName); + } + + for (Player player : players) { + pm.sendServerPacket(player, removePacket); + } + } + + @Override + public @NotNull TeamDisplayPacketAdapter createTeamDisplayAdapter(@NotNull ImmutableTeamProperties properties) { + return new ModernDisplayAdapter(pm, teamName, properties); + } + + @Override + public @NotNull TeamDisplayPacketAdapter createLegacyTeamDisplayAdapter(@NotNull ImmutableTeamProperties properties) { + return new LegacyDisplayAdapter(pm, teamName, properties); + } +} From c79cf8ba02ee9a8c2bc2e93dbf692840518639ed Mon Sep 17 00:00:00 2001 From: vytskalt Date: Thu, 29 Feb 2024 20:05:47 +0200 Subject: [PATCH 06/13] [ci skip] implement modern team adapter --- .../team/LegacyDisplayAdapter.java | 4 +- .../team/ModernDisplayAdapter.java | 84 ++++++++++++++++++- .../team/TeamsPacketAdapterImpl.java | 4 +- 3 files changed, 86 insertions(+), 6 deletions(-) diff --git a/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/team/LegacyDisplayAdapter.java b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/team/LegacyDisplayAdapter.java index 742fe785..afdedc90 100644 --- a/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/team/LegacyDisplayAdapter.java +++ b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/team/LegacyDisplayAdapter.java @@ -54,8 +54,8 @@ public void sendProperties(@NotNull PropertiesPacketType packetType, @NotNull Co .write(0, teamName) .write(1, displayName) .write(2, prefix) - .write(2, suffix) - .write(3, properties.nameTagVisibility().key()); + .write(3, suffix) + .write(4, properties.nameTagVisibility().key()); if (packetType == PropertiesPacketType.CREATE) { packet.getSpecificModifier(Collection.class).write(0, properties.entries()); diff --git a/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/team/ModernDisplayAdapter.java b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/team/ModernDisplayAdapter.java index bc0f80d1..70cc57d2 100644 --- a/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/team/ModernDisplayAdapter.java +++ b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/team/ModernDisplayAdapter.java @@ -3,23 +3,36 @@ import com.comphenix.protocol.PacketType; import com.comphenix.protocol.ProtocolManager; import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.utility.MinecraftVersion; +import com.comphenix.protocol.wrappers.EnumWrappers; +import com.comphenix.protocol.wrappers.WrappedChatComponent; +import com.comphenix.protocol.wrappers.WrappedTeamParameters; import net.kyori.adventure.text.Component; +import net.kyori.adventure.translation.GlobalTranslator; +import net.megavex.scoreboardlibrary.implementation.commons.LegacyFormatUtil; import net.megavex.scoreboardlibrary.implementation.packetAdapter.ImmutableTeamProperties; +import net.megavex.scoreboardlibrary.implementation.packetAdapter.PacketSender; import net.megavex.scoreboardlibrary.implementation.packetAdapter.PropertiesPacketType; import net.megavex.scoreboardlibrary.implementation.packetAdapter.team.EntriesPacketType; import net.megavex.scoreboardlibrary.implementation.packetAdapter.team.TeamConstants; import net.megavex.scoreboardlibrary.implementation.packetAdapter.team.TeamDisplayPacketAdapter; +import net.megavex.scoreboardlibrary.implementation.packetAdapter.util.LocalePacketUtil; +import org.bukkit.ChatColor; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import java.util.Collection; +import java.util.Optional; + +import static net.kyori.adventure.text.serializer.gson.GsonComponentSerializer.gson; +import static net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection; +import static net.megavex.scoreboardlibrary.implementation.commons.LegacyFormatUtil.limitLegacyText; // 1.13+ public class ModernDisplayAdapter implements TeamDisplayPacketAdapter { private final ProtocolManager pm; private final String teamName; private final ImmutableTeamProperties properties; - private PacketContainer removePacket; public ModernDisplayAdapter(@NotNull ProtocolManager pm, @NotNull String teamName, @NotNull ImmutableTeamProperties properties) { this.pm = pm; @@ -30,7 +43,8 @@ public ModernDisplayAdapter(@NotNull ProtocolManager pm, @NotNull String teamNam @Override public void sendEntries(@NotNull EntriesPacketType packetType, @NotNull Collection players, @NotNull Collection entries) { PacketContainer packet = pm.createPacket(PacketType.Play.Server.SCOREBOARD_TEAM); - packet.getIntegers().write(0, TeamConstants.mode(packetType)); + int modeIdx = MinecraftVersion.AQUATIC_UPDATE.atOrAbove() ? 0 : 1; + packet.getIntegers().write(modeIdx, TeamConstants.MODE_REMOVE); packet.getStrings().write(0, teamName); packet.getSpecificModifier(Collection.class).write(0, players); @@ -41,6 +55,70 @@ public void sendEntries(@NotNull EntriesPacketType packetType, @NotNull Collecti @Override public void sendProperties(@NotNull PropertiesPacketType packetType, @NotNull Collection players) { - // TODO + PacketSender sender = pm::sendServerPacket; + char legacyChar = LegacyFormatUtil.getChar(properties.playerColor()); + EnumWrappers.ChatFormatting color = EnumWrappers.ChatFormatting.fromBukkit(ChatColor.getByChar(legacyChar)); + boolean usesParameters = MinecraftVersion.CAVES_CLIFFS_1.atOrAbove(); + boolean usesComponents = MinecraftVersion.AQUATIC_UPDATE.atOrAbove(); + + LocalePacketUtil.sendLocalePackets(sender, players, locale -> { + PacketContainer packet = pm.createPacket(PacketType.Play.Server.SCOREBOARD_TEAM); + int modeIdx = usesComponents ? 0 : 1; + packet.getIntegers().write(modeIdx, TeamConstants.mode(packetType)); + packet.getStrings().write(0, teamName); + packet.getSpecificModifier(Collection.class).write(0, properties.entries()); + + Component displayName = GlobalTranslator.render(properties.displayName(), locale); + Component prefix = GlobalTranslator.render(properties.prefix(), locale); + Component suffix = GlobalTranslator.render(properties.suffix(), locale); + + if (usesParameters) { + WrappedTeamParameters params = WrappedTeamParameters.newBuilder() + .displayName(wrapComponent(displayName)) + .prefix(wrapComponent(prefix)) + .suffix(wrapComponent(suffix)) + .nametagVisibility(properties.nameTagVisibility().key()) + .collisionRule(properties.collisionRule().key()) + .color(color) + .options(properties.packOptions()) + .build(); + packet.getOptionalTeamParameters().write(0, Optional.of(params)); + } else { + packet.getIntegers().write(modeIdx + 1, properties.packOptions()); + if (usesComponents) { + packet.getChatFormattings().write(0, color); + } else { + packet.getIntegers().write(0, color.ordinal()); + } + + if (usesComponents) { + packet.getChatComponents() + .write(0, wrapComponent(displayName)) + .write(1, wrapComponent(prefix)) + .write(2, wrapComponent(suffix)); + + packet.getStrings() + .write(1, properties.nameTagVisibility().key()) + .write(2, properties.collisionRule().key()); + } else { + packet.getStrings() + .write(1, toLegacy(displayName)) + .write(2, toLegacy(prefix)) + .write(3, toLegacy(suffix)) + .write(4, properties.nameTagVisibility().key()) + .writeSafely(5, properties.collisionRule().key()); // Added in 1.9 + } + } + + return packet; + }); + } + + private @NotNull WrappedChatComponent wrapComponent(@NotNull Component component) { + return WrappedChatComponent.fromJson(gson().serialize(component)); + } + + private @NotNull String toLegacy(@NotNull Component component) { + return limitLegacyText(legacySection().serialize(component), TeamConstants.LEGACY_CHAR_LIMIT); } } diff --git a/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/team/TeamsPacketAdapterImpl.java b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/team/TeamsPacketAdapterImpl.java index d800de1a..5d0edbf3 100644 --- a/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/team/TeamsPacketAdapterImpl.java +++ b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/team/TeamsPacketAdapterImpl.java @@ -3,6 +3,7 @@ import com.comphenix.protocol.PacketType; import com.comphenix.protocol.ProtocolManager; import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.utility.MinecraftVersion; import net.kyori.adventure.text.Component; import net.megavex.scoreboardlibrary.implementation.packetAdapter.ImmutableTeamProperties; import net.megavex.scoreboardlibrary.implementation.packetAdapter.team.TeamConstants; @@ -25,7 +26,8 @@ public TeamsPacketAdapterImpl(@NotNull ProtocolManager pm, @NotNull String teamN public void removeTeam(@NotNull Iterable players) { if (removePacket == null) { removePacket = pm.createPacket(PacketType.Play.Server.SCOREBOARD_TEAM); - removePacket.getIntegers().write(1, TeamConstants.MODE_REMOVE); + int modeIdx = MinecraftVersion.AQUATIC_UPDATE.atOrAbove() ? 0 : 1; + removePacket.getIntegers().write(modeIdx, TeamConstants.MODE_REMOVE); removePacket.getStrings().write(0, teamName); } From 97b1abc6315151d57718dd9eae9e80895e171036 Mon Sep 17 00:00:00 2001 From: vytskalt Date: Sat, 2 Mar 2024 21:14:37 +0200 Subject: [PATCH 07/13] [ci skip] cleanup --- .../protocollib/ComponentConversions.java | 25 +++++++++++++++ .../ObjectivePacketAdapterImpl.java | 11 +++---- .../PacketAdapterProviderImpl.java | 5 +-- .../team/ModernDisplayAdapter.java | 31 ++++++++----------- .../v1_8_R3/PacketAdapterProviderImpl.java | 2 +- 5 files changed, 44 insertions(+), 30 deletions(-) create mode 100644 versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/ComponentConversions.java diff --git a/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/ComponentConversions.java b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/ComponentConversions.java new file mode 100644 index 00000000..93f2652a --- /dev/null +++ b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/ComponentConversions.java @@ -0,0 +1,25 @@ +package net.megavex.scoreboardlibrary.implementation.packetAdapter.protocollib; + +import com.comphenix.protocol.utility.MinecraftVersion; +import com.comphenix.protocol.wrappers.WrappedChatComponent; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; +import org.jetbrains.annotations.NotNull; + +// NOTE: ProtocolLib already has these utilities (AdventureComponentConverter) +// but they cannot be used as adventure is potentially relocated +public final class ComponentConversions { + private static final GsonComponentSerializer SERIALIZER; + + static { + if (MinecraftVersion.NETHER_UPDATE.atOrAbove()) { + SERIALIZER = GsonComponentSerializer.gson(); + } else { + SERIALIZER = GsonComponentSerializer.colorDownsamplingGson(); + } + } + + public static @NotNull WrappedChatComponent wrapAdventure(@NotNull Component component) { + return WrappedChatComponent.fromJson(SERIALIZER.serialize(component)); + } +} diff --git a/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/ObjectivePacketAdapterImpl.java b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/ObjectivePacketAdapterImpl.java index 4866304e..d108a04e 100644 --- a/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/ObjectivePacketAdapterImpl.java +++ b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/ObjectivePacketAdapterImpl.java @@ -5,7 +5,6 @@ import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.utility.MinecraftVersion; import com.comphenix.protocol.wrappers.EnumWrappers; -import com.comphenix.protocol.wrappers.WrappedChatComponent; import net.kyori.adventure.text.Component; import net.kyori.adventure.translation.GlobalTranslator; import net.megavex.scoreboardlibrary.api.objective.ObjectiveDisplaySlot; @@ -21,7 +20,6 @@ import java.util.Collection; -import static net.kyori.adventure.text.serializer.gson.GsonComponentSerializer.gson; import static net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection; public class ObjectivePacketAdapterImpl implements ObjectivePacketAdapter { @@ -42,7 +40,7 @@ public void display(@NotNull Collection players, @NotNull ObjectiveDispl packet.getStrings().write(0, objectiveName); int displaySlotIdx = ObjectiveConstants.displaySlotIndex(slot); - if (MinecraftVersion.getCurrentVersion().isAtLeast(new MinecraftVersion(1, 20, 2))) { + if (new MinecraftVersion(1, 20, 2).atOrAbove()) { packet.getDisplaySlots().write(0, DISPLAY_SLOTS[displaySlotIdx]); } else { packet.getIntegers().write(0, displaySlotIdx); @@ -74,9 +72,8 @@ public void sendProperties(@NotNull Collection players, @NotNull Propert packet.getStrings().write(0, objectiveName); Component translatedValue = GlobalTranslator.render(value, locale); - if (MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.AQUATIC_UPDATE)) { - WrappedChatComponent wrappedValue = WrappedChatComponent.fromJson(gson().serialize(translatedValue)); - packet.getChatComponents().write(0, wrappedValue); + if (MinecraftVersion.AQUATIC_UPDATE.atOrAbove()) { + packet.getChatComponents().write(0, ComponentConversions.wrapAdventure(translatedValue)); } else { String legacyValue = LegacyFormatUtil.limitLegacyText( legacySection().serialize(translatedValue), @@ -119,7 +116,7 @@ public void sendScore(@NotNull Collection players, @NotNull String entry @Override public void removeScore(@NotNull Collection players, @NotNull String entry) { PacketContainer packet; - if (MinecraftVersion.getCurrentVersion().isAtLeast(new MinecraftVersion(1, 20, 3))) { + if (new MinecraftVersion(1, 20, 3).atOrAbove()) { packet = pm.createPacket(PacketType.Play.Server.RESET_SCORE); packet.getStrings().write(0, entry) .write(1, objectiveName); diff --git a/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/PacketAdapterProviderImpl.java b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/PacketAdapterProviderImpl.java index 6406dbea..3c3f95c7 100644 --- a/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/PacketAdapterProviderImpl.java +++ b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/PacketAdapterProviderImpl.java @@ -3,7 +3,6 @@ import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolManager; import com.comphenix.protocol.utility.MinecraftVersion; -import com.comphenix.protocol.wrappers.EnumWrappers; import net.megavex.scoreboardlibrary.implementation.packetAdapter.PacketAdapterProvider; import net.megavex.scoreboardlibrary.implementation.packetAdapter.objective.ObjectivePacketAdapter; import net.megavex.scoreboardlibrary.implementation.packetAdapter.protocollib.team.TeamsPacketAdapterImpl; @@ -20,9 +19,7 @@ public class PacketAdapterProviderImpl implements PacketAdapterProvider { public PacketAdapterProviderImpl() { this.pm = Objects.requireNonNull(ProtocolLibrary.getProtocolManager()); - this.isLegacyVersion = !MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.AQUATIC_UPDATE); - System.out.println("[scoreboard-library] Render type class = " + EnumWrappers.getRenderTypeClass()); - System.out.println("[scoreboard-library] Display slot class = " + EnumWrappers.getDisplaySlotClass()); + this.isLegacyVersion = !MinecraftVersion.AQUATIC_UPDATE.atOrAbove(); } @Override diff --git a/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/team/ModernDisplayAdapter.java b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/team/ModernDisplayAdapter.java index 70cc57d2..d354a4a0 100644 --- a/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/team/ModernDisplayAdapter.java +++ b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/team/ModernDisplayAdapter.java @@ -5,7 +5,6 @@ import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.utility.MinecraftVersion; import com.comphenix.protocol.wrappers.EnumWrappers; -import com.comphenix.protocol.wrappers.WrappedChatComponent; import com.comphenix.protocol.wrappers.WrappedTeamParameters; import net.kyori.adventure.text.Component; import net.kyori.adventure.translation.GlobalTranslator; @@ -13,6 +12,7 @@ import net.megavex.scoreboardlibrary.implementation.packetAdapter.ImmutableTeamProperties; import net.megavex.scoreboardlibrary.implementation.packetAdapter.PacketSender; import net.megavex.scoreboardlibrary.implementation.packetAdapter.PropertiesPacketType; +import net.megavex.scoreboardlibrary.implementation.packetAdapter.protocollib.ComponentConversions; import net.megavex.scoreboardlibrary.implementation.packetAdapter.team.EntriesPacketType; import net.megavex.scoreboardlibrary.implementation.packetAdapter.team.TeamConstants; import net.megavex.scoreboardlibrary.implementation.packetAdapter.team.TeamDisplayPacketAdapter; @@ -24,7 +24,6 @@ import java.util.Collection; import java.util.Optional; -import static net.kyori.adventure.text.serializer.gson.GsonComponentSerializer.gson; import static net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection; import static net.megavex.scoreboardlibrary.implementation.commons.LegacyFormatUtil.limitLegacyText; @@ -58,12 +57,12 @@ public void sendProperties(@NotNull PropertiesPacketType packetType, @NotNull Co PacketSender sender = pm::sendServerPacket; char legacyChar = LegacyFormatUtil.getChar(properties.playerColor()); EnumWrappers.ChatFormatting color = EnumWrappers.ChatFormatting.fromBukkit(ChatColor.getByChar(legacyChar)); - boolean usesParameters = MinecraftVersion.CAVES_CLIFFS_1.atOrAbove(); - boolean usesComponents = MinecraftVersion.AQUATIC_UPDATE.atOrAbove(); + boolean v1_17OrAbove = MinecraftVersion.CAVES_CLIFFS_1.atOrAbove(); + boolean v1_13OrAbove = MinecraftVersion.AQUATIC_UPDATE.atOrAbove(); LocalePacketUtil.sendLocalePackets(sender, players, locale -> { PacketContainer packet = pm.createPacket(PacketType.Play.Server.SCOREBOARD_TEAM); - int modeIdx = usesComponents ? 0 : 1; + int modeIdx = v1_13OrAbove ? 0 : 1; packet.getIntegers().write(modeIdx, TeamConstants.mode(packetType)); packet.getStrings().write(0, teamName); packet.getSpecificModifier(Collection.class).write(0, properties.entries()); @@ -72,11 +71,11 @@ public void sendProperties(@NotNull PropertiesPacketType packetType, @NotNull Co Component prefix = GlobalTranslator.render(properties.prefix(), locale); Component suffix = GlobalTranslator.render(properties.suffix(), locale); - if (usesParameters) { + if (v1_17OrAbove) { WrappedTeamParameters params = WrappedTeamParameters.newBuilder() - .displayName(wrapComponent(displayName)) - .prefix(wrapComponent(prefix)) - .suffix(wrapComponent(suffix)) + .displayName(ComponentConversions.wrapAdventure(displayName)) + .prefix(ComponentConversions.wrapAdventure(prefix)) + .suffix(ComponentConversions.wrapAdventure(suffix)) .nametagVisibility(properties.nameTagVisibility().key()) .collisionRule(properties.collisionRule().key()) .color(color) @@ -85,17 +84,17 @@ public void sendProperties(@NotNull PropertiesPacketType packetType, @NotNull Co packet.getOptionalTeamParameters().write(0, Optional.of(params)); } else { packet.getIntegers().write(modeIdx + 1, properties.packOptions()); - if (usesComponents) { + if (v1_13OrAbove) { packet.getChatFormattings().write(0, color); } else { packet.getIntegers().write(0, color.ordinal()); } - if (usesComponents) { + if (v1_13OrAbove) { packet.getChatComponents() - .write(0, wrapComponent(displayName)) - .write(1, wrapComponent(prefix)) - .write(2, wrapComponent(suffix)); + .write(0, ComponentConversions.wrapAdventure(displayName)) + .write(1, ComponentConversions.wrapAdventure(prefix)) + .write(2, ComponentConversions.wrapAdventure(suffix)); packet.getStrings() .write(1, properties.nameTagVisibility().key()) @@ -114,10 +113,6 @@ public void sendProperties(@NotNull PropertiesPacketType packetType, @NotNull Co }); } - private @NotNull WrappedChatComponent wrapComponent(@NotNull Component component) { - return WrappedChatComponent.fromJson(gson().serialize(component)); - } - private @NotNull String toLegacy(@NotNull Component component) { return limitLegacyText(legacySection().serialize(component), TeamConstants.LEGACY_CHAR_LIMIT); } diff --git a/versions/v1_8_R3/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/v1_8_R3/PacketAdapterProviderImpl.java b/versions/v1_8_R3/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/v1_8_R3/PacketAdapterProviderImpl.java index 34e4e53c..e368e9ac 100644 --- a/versions/v1_8_R3/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/v1_8_R3/PacketAdapterProviderImpl.java +++ b/versions/v1_8_R3/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/v1_8_R3/PacketAdapterProviderImpl.java @@ -1,8 +1,8 @@ package net.megavex.scoreboardlibrary.implementation.packetAdapter.v1_8_R3; -import net.megavex.scoreboardlibrary.implementation.packetAdapter.objective.ObjectivePacketAdapter; import net.megavex.scoreboardlibrary.implementation.packetAdapter.PacketAdapterProvider; import net.megavex.scoreboardlibrary.implementation.packetAdapter.PacketSender; +import net.megavex.scoreboardlibrary.implementation.packetAdapter.objective.ObjectivePacketAdapter; import net.megavex.scoreboardlibrary.implementation.packetAdapter.team.TeamsPacketAdapter; import net.minecraft.server.v1_8_R3.Packet; import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer; From 8011663a4bb4aee53b29752943a3bfd84a632866 Mon Sep 17 00:00:00 2001 From: vytskalt Date: Sat, 2 Mar 2024 21:18:36 +0200 Subject: [PATCH 08/13] [ci skip] remove debug println --- .../scoreboardlibrary/implementation/PacketAdapterLoader.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/implementation/src/main/java/net/megavex/scoreboardlibrary/implementation/PacketAdapterLoader.java b/implementation/src/main/java/net/megavex/scoreboardlibrary/implementation/PacketAdapterLoader.java index 34dbfb5e..95126eb5 100644 --- a/implementation/src/main/java/net/megavex/scoreboardlibrary/implementation/PacketAdapterLoader.java +++ b/implementation/src/main/java/net/megavex/scoreboardlibrary/implementation/PacketAdapterLoader.java @@ -21,8 +21,6 @@ private PacketAdapterLoader() { throw new NoPacketAdapterAvailableException(); } - System.out.println("[scoreboard-library] Using packet adapter: " + nmsClass.getName()); - try { return (PacketAdapterProvider) nmsClass.getConstructors()[0].newInstance(); } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { From d64434a369e2b5f348defdab3b0b490c0b0ce43f Mon Sep 17 00:00:00 2001 From: vytskalt Date: Wed, 6 Mar 2024 21:07:42 +0200 Subject: [PATCH 09/13] bruh --- README.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/README.md b/README.md index b71e569f..13724c07 100644 --- a/README.md +++ b/README.md @@ -12,10 +12,7 @@ Join the [Discord](https://discord.gg/v7nmTDTW8W) or create an issue for support - Teams. Supports showing different properties (display name, prefix, entries etc.) of the same team to different players - Objectives. -<<<<<<< HEAD -======= - Full support for new 1.20.4 features (score display names, custom score formats) ->>>>>>> main - Doesn't require extra dependencies (assuming you're targeting modern versions of Paper) - Packet-level, meaning it works with other scoreboard plugins - Supports [Folia](https://github.com/PaperMC/Folia) @@ -27,10 +24,6 @@ Join the [Discord](https://discord.gg/v7nmTDTW8W) or create an issue for support ## Available Packet Adapters - **modern.** Supports 1.17-1.20.4. Can take advantage of [Paper](https://papermc.io)'s native adventure support to be more efficient. -<<<<<<< HEAD -- **ProtocolLib**. Supports 1.8+. Requires [ProtocolLib](https://www.spigotmc.org/resources/protocollib.1997/) to be installed on the server. -======= ->>>>>>> main - **PacketEvents.** Supports 1.8+. Requires [PacketEvents 2.0](https://github.com/retrooper/packetevents/tree/2.0) to be shaded or installed as a plugin. Can be less stable than ProtocolLib. - **1.8.8.** From f73cf99b52190456942b897ba7b7de3d194a3c3a Mon Sep 17 00:00:00 2001 From: vytskalt Date: Wed, 6 Mar 2024 21:08:43 +0200 Subject: [PATCH 10/13] [ci skip] update readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 13724c07..4f85d99d 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ Join the [Discord](https://discord.gg/v7nmTDTW8W) or create an issue for support ## Available Packet Adapters - **modern.** Supports 1.17-1.20.4. Can take advantage of [Paper](https://papermc.io)'s native adventure support to be more efficient. +- **ProtocolLib**. Supports 1.8+. Requires [ProtocolLib](https://www.spigotmc.org/resources/protocollib.1997/) to be installed on the server. - **PacketEvents.** Supports 1.8+. Requires [PacketEvents 2.0](https://github.com/retrooper/packetevents/tree/2.0) to be shaded or installed as a plugin. Can be less stable than ProtocolLib. - **1.8.8.** From 00b6936bbdc3b41fc0e932b19bfb729f626faa06 Mon Sep 17 00:00:00 2001 From: vytskalt Date: Sun, 9 Jun 2024 17:04:58 +0300 Subject: [PATCH 11/13] get it to compile again --- INSTALLATION.md | 6 ++--- gradle/libs.versions.toml | 1 + versions/protocollib/build.gradle.kts | 5 ++--- .../ObjectivePacketAdapterImpl.java | 22 +++++++++++++++++-- .../PacketAdapterProviderImpl.java | 5 +++-- 5 files changed, 29 insertions(+), 10 deletions(-) diff --git a/INSTALLATION.md b/INSTALLATION.md index 97e1006b..40307e8c 100644 --- a/INSTALLATION.md +++ b/INSTALLATION.md @@ -31,8 +31,8 @@ dependencies { // Add packet adapter implementations you want: runtimeOnly("net.megavex:scoreboard-library-modern:$scoreboardLibraryVersion") // 1.17+ runtimeOnly("net.megavex:scoreboard-library-modern:$scoreboardLibraryVersion:mojmap") // Mojang mapped variant (only use if you know what you're doing!) - runtimeOnly("net.megavex:scoreboard-library-packetevents:$scoreboardLibraryVersion") // 1.8+ runtimeOnly("net.megavex:scoreboard-library-protocollib:$scoreboardLibraryVersion") // 1.8+ + runtimeOnly("net.megavex:scoreboard-library-packetevents:$scoreboardLibraryVersion") // 1.8+ runtimeOnly("net.megavex:scoreboard-library-v1_8_R3:$scoreboardLibraryVersion") // 1.8 // If using the PacketEvents adapter, scoreboard-library expects PacketEvents to be loaded in the classpath. @@ -83,13 +83,13 @@ like [Shadow](https://imperceptiblethoughts.com/shadow/). net.megavex - scoreboard-library-packetevents + scoreboard-library-protocollib {VERSION HERE} runtime net.megavex - scoreboard-library-protocollib + scoreboard-library-packetevents {VERSION HERE} runtime diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6be870a6..dbed7054 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,6 +6,7 @@ devBundle = "1.20.5-R0.1-SNAPSHOT" # modern packet adapter [libraries] spigotApi = "org.spigotmc:spigot-api:1.12.2-R0.1-SNAPSHOT" # do not update onePointEightPointEightNms = "org.github.spigot:1.8.8:1.8.8" +protocollib = "com.comphenix.protocol:ProtocolLib:5.3.0-SNAPSHOT" packetEvents = "com.github.retrooper.packetevents:spigot:2.3.0" buildIndra = { module = "net.kyori:indra-common", version = "3.1.3" } buildNmcp = "com.gradleup.nmcp:com.gradleup.nmcp.gradle.plugin:0.0.7" diff --git a/versions/protocollib/build.gradle.kts b/versions/protocollib/build.gradle.kts index afcd57a2..5238d11e 100644 --- a/versions/protocollib/build.gradle.kts +++ b/versions/protocollib/build.gradle.kts @@ -1,13 +1,12 @@ plugins { - id("net.megavex.scoreboardlibrary.publish-conventions") + id("net.megavex.scoreboardlibrary.base-conventions") } repositories { - mavenLocal() // temporary maven("https://repo.dmulloy2.net/repository/public/") } dependencies { compileOnly(project(":scoreboard-library-packet-adapter-base")) - compileOnly("com.comphenix.protocol:ProtocolLib:5.2.0-SNAPSHOT") + compileOnly(libs.protocollib) } diff --git a/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/ObjectivePacketAdapterImpl.java b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/ObjectivePacketAdapterImpl.java index d108a04e..7775dc08 100644 --- a/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/ObjectivePacketAdapterImpl.java +++ b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/ObjectivePacketAdapterImpl.java @@ -9,6 +9,7 @@ import net.kyori.adventure.translation.GlobalTranslator; import net.megavex.scoreboardlibrary.api.objective.ObjectiveDisplaySlot; import net.megavex.scoreboardlibrary.api.objective.ObjectiveRenderType; +import net.megavex.scoreboardlibrary.api.objective.ScoreFormat; import net.megavex.scoreboardlibrary.implementation.commons.LegacyFormatUtil; import net.megavex.scoreboardlibrary.implementation.packetAdapter.PacketSender; import net.megavex.scoreboardlibrary.implementation.packetAdapter.PropertiesPacketType; @@ -17,6 +18,7 @@ import net.megavex.scoreboardlibrary.implementation.packetAdapter.util.LocalePacketUtil; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Collection; @@ -52,7 +54,13 @@ public void display(@NotNull Collection players, @NotNull ObjectiveDispl } @Override - public void sendProperties(@NotNull Collection players, @NotNull PropertiesPacketType packetType, @NotNull Component value, @NotNull ObjectiveRenderType renderType) { + public void sendProperties( + @NotNull Collection players, + @NotNull PropertiesPacketType packetType, + @NotNull Component value, + @NotNull ObjectiveRenderType renderType, + @Nullable ScoreFormat scoreFormat + ) { PacketSender sender = pm::sendServerPacket; LocalePacketUtil.sendLocalePackets(sender, players, locale -> { EnumWrappers.RenderType wrappedRenderType; @@ -83,6 +91,7 @@ public void sendProperties(@NotNull Collection players, @NotNull Propert } packet.getRenderTypes().write(0, wrappedRenderType); + // TODO: scoreFormat return packet; }); } @@ -101,7 +110,14 @@ public void remove(@NotNull Collection players) { } @Override - public void sendScore(@NotNull Collection players, @NotNull String entry, int value) { + public void sendScore( + @NotNull Collection players, + @NotNull String entry, + int value, + @Nullable Component display, + @Nullable ScoreFormat scoreFormat + ) { + PacketContainer packet = pm.createPacket(PacketType.Play.Server.SCOREBOARD_SCORE); packet.getScoreboardActions().write(0, EnumWrappers.ScoreboardAction.CHANGE); packet.getStrings().write(0, entry) @@ -111,6 +127,8 @@ public void sendScore(@NotNull Collection players, @NotNull String entry for (Player player : players) { pm.sendServerPacket(player, packet); } + + // TODO: scoreFormat } @Override diff --git a/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/PacketAdapterProviderImpl.java b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/PacketAdapterProviderImpl.java index 3c3f95c7..e555af52 100644 --- a/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/PacketAdapterProviderImpl.java +++ b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/PacketAdapterProviderImpl.java @@ -3,6 +3,7 @@ import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolManager; import com.comphenix.protocol.utility.MinecraftVersion; +import net.megavex.scoreboardlibrary.implementation.commons.LineRenderingStrategy; import net.megavex.scoreboardlibrary.implementation.packetAdapter.PacketAdapterProvider; import net.megavex.scoreboardlibrary.implementation.packetAdapter.objective.ObjectivePacketAdapter; import net.megavex.scoreboardlibrary.implementation.packetAdapter.protocollib.team.TeamsPacketAdapterImpl; @@ -33,7 +34,7 @@ public PacketAdapterProviderImpl() { } @Override - public boolean isLegacy(@NotNull Player player) { - return isLegacyVersion; + public @NotNull LineRenderingStrategy lineRenderingStrategy(@NotNull Player player) { + return isLegacyVersion ? LineRenderingStrategy.LEGACY : LineRenderingStrategy.MODERN; } } From 0d7f41615db7feef4265d88309c7c6fcb6f27a88 Mon Sep 17 00:00:00 2001 From: vytskalt Date: Sun, 9 Jun 2024 18:45:39 +0300 Subject: [PATCH 12/13] implement new score stuff --- .../protocollib/ComponentConversions.java | 8 ++- .../ObjectivePacketAdapterImpl.java | 54 +++++++++++++++---- .../protocollib/ScoreFormatConverter.java | 29 ++++++++++ .../team/ModernDisplayAdapter.java | 12 ++--- 4 files changed, 85 insertions(+), 18 deletions(-) create mode 100644 versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/ScoreFormatConverter.java diff --git a/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/ComponentConversions.java b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/ComponentConversions.java index 93f2652a..266c1e41 100644 --- a/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/ComponentConversions.java +++ b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/ComponentConversions.java @@ -2,7 +2,9 @@ import com.comphenix.protocol.utility.MinecraftVersion; import com.comphenix.protocol.wrappers.WrappedChatComponent; +import com.comphenix.protocol.wrappers.WrappedComponentStyle; import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.Style; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import org.jetbrains.annotations.NotNull; @@ -19,7 +21,11 @@ public final class ComponentConversions { } } - public static @NotNull WrappedChatComponent wrapAdventure(@NotNull Component component) { + public static @NotNull WrappedChatComponent wrapAdventureComponent(@NotNull Component component) { return WrappedChatComponent.fromJson(SERIALIZER.serialize(component)); } + + public static @NotNull WrappedComponentStyle wrapAdventureStyle(@NotNull Style style) { + return WrappedComponentStyle.fromJson(SERIALIZER.serializer().toJsonTree(style)); + } } diff --git a/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/ObjectivePacketAdapterImpl.java b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/ObjectivePacketAdapterImpl.java index 7775dc08..c4d1d0f4 100644 --- a/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/ObjectivePacketAdapterImpl.java +++ b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/ObjectivePacketAdapterImpl.java @@ -4,7 +4,10 @@ import com.comphenix.protocol.ProtocolManager; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.utility.MinecraftVersion; +import com.comphenix.protocol.wrappers.BukkitConverters; import com.comphenix.protocol.wrappers.EnumWrappers; +import com.comphenix.protocol.wrappers.WrappedChatComponent; +import com.comphenix.protocol.wrappers.WrappedNumberFormat; import net.kyori.adventure.text.Component; import net.kyori.adventure.translation.GlobalTranslator; import net.megavex.scoreboardlibrary.api.objective.ObjectiveDisplaySlot; @@ -21,6 +24,7 @@ import org.jetbrains.annotations.Nullable; import java.util.Collection; +import java.util.Optional; import static net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection; @@ -78,10 +82,19 @@ public void sendProperties( PacketContainer packet = pm.createPacket(PacketType.Play.Server.SCOREBOARD_OBJECTIVE); packet.getIntegers().write(0, ObjectiveConstants.mode(packetType)); packet.getStrings().write(0, objectiveName); + if (WrappedNumberFormat.isSupported() && scoreFormat != null) { + WrappedNumberFormat wrapped = ScoreFormatConverter.convert(locale, scoreFormat); + if (MinecraftVersion.v1_20_5.atOrAbove()) { + packet.getOptionals(BukkitConverters.getWrappedNumberFormatConverter()) + .write(0, Optional.of(wrapped)); + } else { + packet.getNumberFormats().write(0, wrapped); + } + } Component translatedValue = GlobalTranslator.render(value, locale); if (MinecraftVersion.AQUATIC_UPDATE.atOrAbove()) { - packet.getChatComponents().write(0, ComponentConversions.wrapAdventure(translatedValue)); + packet.getChatComponents().write(0, ComponentConversions.wrapAdventureComponent(translatedValue)); } else { String legacyValue = LegacyFormatUtil.limitLegacyText( legacySection().serialize(translatedValue), @@ -91,7 +104,6 @@ public void sendProperties( } packet.getRenderTypes().write(0, wrappedRenderType); - // TODO: scoreFormat return packet; }); } @@ -118,17 +130,37 @@ public void sendScore( @Nullable ScoreFormat scoreFormat ) { - PacketContainer packet = pm.createPacket(PacketType.Play.Server.SCOREBOARD_SCORE); - packet.getScoreboardActions().write(0, EnumWrappers.ScoreboardAction.CHANGE); - packet.getStrings().write(0, entry) - .write(1, objectiveName); - packet.getIntegers().write(0, value); + PacketSender sender = pm::sendServerPacket; + LocalePacketUtil.sendLocalePackets(sender, players, locale -> { + PacketContainer packet = pm.createPacket(PacketType.Play.Server.SCOREBOARD_SCORE); + packet.getScoreboardActions().write(0, EnumWrappers.ScoreboardAction.CHANGE); + packet.getStrings().write(0, entry) + .write(1, objectiveName); + packet.getIntegers().write(0, value); + + if (WrappedNumberFormat.isSupported() && scoreFormat != null) { + WrappedNumberFormat wrapped = ScoreFormatConverter.convert(locale, scoreFormat); + if (MinecraftVersion.v1_20_5.atOrAbove()) { + packet.getOptionals(BukkitConverters.getWrappedNumberFormatConverter()) + .write(1, Optional.of(wrapped)); + } else { + packet.getNumberFormats().write(0, wrapped); + } + } - for (Player player : players) { - pm.sendServerPacket(player, packet); - } + if (MinecraftVersion.v1_20_4.atOrAbove() && display != null) { + WrappedChatComponent wrapped = ComponentConversions.wrapAdventureComponent(GlobalTranslator.render(display, locale)); + if (MinecraftVersion.v1_20_5.atOrAbove()) { + packet.getChatComponents().write(0, wrapped); + } else { + packet.getOptionals(BukkitConverters.getWrappedChatComponentConverter()) + .write(0, Optional.of(wrapped)); + } + } + + return packet; + }); - // TODO: scoreFormat } @Override diff --git a/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/ScoreFormatConverter.java b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/ScoreFormatConverter.java new file mode 100644 index 00000000..cb559b50 --- /dev/null +++ b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/ScoreFormatConverter.java @@ -0,0 +1,29 @@ +package net.megavex.scoreboardlibrary.implementation.packetAdapter.protocollib; + +import com.comphenix.protocol.wrappers.WrappedNumberFormat; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.Style; +import net.kyori.adventure.translation.GlobalTranslator; +import net.megavex.scoreboardlibrary.api.objective.ScoreFormat; +import org.jetbrains.annotations.NotNull; + +import java.util.Locale; + +public final class ScoreFormatConverter { + private ScoreFormatConverter() { + } + + public static @NotNull WrappedNumberFormat convert(@NotNull Locale locale, @NotNull ScoreFormat format) { + if (format == ScoreFormat.blank()) { + return WrappedNumberFormat.blank(); + } else if (format instanceof ScoreFormat.Styled) { + Style style = ((ScoreFormat.Styled) format).style(); + return WrappedNumberFormat.styled(ComponentConversions.wrapAdventureStyle(style)); + } else if (format instanceof ScoreFormat.Fixed) { + Component content = GlobalTranslator.render(((ScoreFormat.Fixed) format).content(), locale); + return WrappedNumberFormat.fixed(ComponentConversions.wrapAdventureComponent(content)); + } else { + throw new IllegalArgumentException("Invalid score format: " + format); + } + } +} diff --git a/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/team/ModernDisplayAdapter.java b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/team/ModernDisplayAdapter.java index d354a4a0..67b9a940 100644 --- a/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/team/ModernDisplayAdapter.java +++ b/versions/protocollib/src/main/java/net/megavex/scoreboardlibrary/implementation/packetAdapter/protocollib/team/ModernDisplayAdapter.java @@ -73,9 +73,9 @@ public void sendProperties(@NotNull PropertiesPacketType packetType, @NotNull Co if (v1_17OrAbove) { WrappedTeamParameters params = WrappedTeamParameters.newBuilder() - .displayName(ComponentConversions.wrapAdventure(displayName)) - .prefix(ComponentConversions.wrapAdventure(prefix)) - .suffix(ComponentConversions.wrapAdventure(suffix)) + .displayName(ComponentConversions.wrapAdventureComponent(displayName)) + .prefix(ComponentConversions.wrapAdventureComponent(prefix)) + .suffix(ComponentConversions.wrapAdventureComponent(suffix)) .nametagVisibility(properties.nameTagVisibility().key()) .collisionRule(properties.collisionRule().key()) .color(color) @@ -92,9 +92,9 @@ public void sendProperties(@NotNull PropertiesPacketType packetType, @NotNull Co if (v1_13OrAbove) { packet.getChatComponents() - .write(0, ComponentConversions.wrapAdventure(displayName)) - .write(1, ComponentConversions.wrapAdventure(prefix)) - .write(2, ComponentConversions.wrapAdventure(suffix)); + .write(0, ComponentConversions.wrapAdventureComponent(displayName)) + .write(1, ComponentConversions.wrapAdventureComponent(prefix)) + .write(2, ComponentConversions.wrapAdventureComponent(suffix)); packet.getStrings() .write(1, properties.nameTagVisibility().key()) From cc0a7b8710cce04a7feb63b84bc6b4797a765357 Mon Sep 17 00:00:00 2001 From: vytskalt Date: Sun, 9 Jun 2024 19:07:34 +0300 Subject: [PATCH 13/13] add version check --- build.gradle.kts | 2 +- .../implementation/PacketAdapterLoader.java | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index f7be587d..114e5bf8 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,5 +1,5 @@ allprojects { - version = "2.1.9" + version = "2.2.0-SNAPSHOT" group = "net.megavex" description = "Powerful packet-level scoreboard library for Paper/Spigot servers" } diff --git a/implementation/src/main/java/net/megavex/scoreboardlibrary/implementation/PacketAdapterLoader.java b/implementation/src/main/java/net/megavex/scoreboardlibrary/implementation/PacketAdapterLoader.java index 4e8abba3..3eaf7666 100644 --- a/implementation/src/main/java/net/megavex/scoreboardlibrary/implementation/PacketAdapterLoader.java +++ b/implementation/src/main/java/net/megavex/scoreboardlibrary/implementation/PacketAdapterLoader.java @@ -14,7 +14,8 @@ public final class PacketAdapterLoader { private static final String MODERN = "modern", V1_8_R3 = "v1_8_R3", - PACKET_EVENTS = "packetevents"; + PACKET_EVENTS = "packetevents", + PROTOCOL_LIB = "protocollib"; private PacketAdapterLoader() { } @@ -99,13 +100,19 @@ private PacketAdapterLoader() { return null; } - return tryLoadImplementationClass("protocollib"); + try { + // ensure we are on a supported ProtocolLib version + Class.forName("com.comphenix.protocol.wrappers.WrappedTeamParameters"); + return tryLoadImplementationClass(PROTOCOL_LIB); + } catch (ClassNotFoundException e) { + return null; + } } private static @Nullable Class tryLoadPacketEvents() { try { Class.forName("com.github.retrooper.packetevents.PacketEvents"); - return tryLoadImplementationClass("packetevents"); + return tryLoadImplementationClass(PACKET_EVENTS); } catch (ClassNotFoundException ignored) { return null; }