From 885783cd9acf605ce571db1e7e99f48053302c2c Mon Sep 17 00:00:00 2001 From: NEZNAMY Date: Tue, 25 Feb 2025 17:16:54 +0100 Subject: [PATCH] [Bukkit] Refactor feature provider loaders --- .../bukkit/header/DummyHeaderFooter.java | 16 ++ .../platforms/bukkit/header/HeaderFooter.java | 39 +---- .../bukkit/header/PacketHeaderFooter.java | 6 +- .../nms/converter/ComponentConverter.java | 29 ---- .../bukkit/platform/BukkitPlatform.java | 155 ++++++++++++++++-- .../bukkit/scoreboard/ScoreboardLoader.java | 55 ------- .../scoreboard/packet/PacketScoreboard.java | 103 +++++------- .../bukkit/tablist/PacketTabList18.java | 2 - .../platforms/bukkit/tablist/TabListBase.java | 40 +---- 9 files changed, 209 insertions(+), 236 deletions(-) create mode 100644 bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/header/DummyHeaderFooter.java delete mode 100644 bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/scoreboard/ScoreboardLoader.java diff --git a/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/header/DummyHeaderFooter.java b/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/header/DummyHeaderFooter.java new file mode 100644 index 000000000..2abb55019 --- /dev/null +++ b/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/header/DummyHeaderFooter.java @@ -0,0 +1,16 @@ +package me.neznamy.tab.platforms.bukkit.header; + +import me.neznamy.chat.component.TabComponent; +import me.neznamy.tab.platforms.bukkit.BukkitTabPlayer; +import org.jetbrains.annotations.NotNull; + +/** + * An empty implementation that does not do anything. + */ +public class DummyHeaderFooter extends HeaderFooter { + + @Override + public void set(@NotNull BukkitTabPlayer player, @NotNull TabComponent header, @NotNull TabComponent footer) { + // Do nothing + } +} \ No newline at end of file diff --git a/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/header/HeaderFooter.java b/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/header/HeaderFooter.java index d9a95180c..b7db055c1 100644 --- a/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/header/HeaderFooter.java +++ b/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/header/HeaderFooter.java @@ -1,51 +1,14 @@ package me.neznamy.tab.platforms.bukkit.header; -import lombok.Getter; -import me.neznamy.tab.platforms.bukkit.BukkitTabPlayer; -import me.neznamy.tab.platforms.bukkit.BukkitUtils; import me.neznamy.chat.component.TabComponent; +import me.neznamy.tab.platforms.bukkit.BukkitTabPlayer; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; /** * A class responsible for sending header/footer to players on request. */ public abstract class HeaderFooter { - /** Instance of the class, null if no implementation is available */ - @Getter - @Nullable - private static HeaderFooter instance; - - /** - * Finds the best available instance for current server software. - */ - public static void findInstance() { - instance = findInstance0(); - } - - @Nullable - private static HeaderFooter findInstance0() { - try { - return new PacketHeaderFooter(); - } catch (Exception e) { - if (PaperHeaderFooter.isAvailable()) { - BukkitUtils.compatibilityError(e, "sending Header/Footer", "Paper API"); - return new PaperHeaderFooter(); - } - if (BukkitHeaderFooter.isAvailable()) { - BukkitUtils.compatibilityError(e, "sending Header/Footer", "Bukkit API", - "Header/Footer having drastically increased CPU usage", - "Header/Footer not supporting fonts (1.16+)"); - return new BukkitHeaderFooter(); - } else { - BukkitUtils.compatibilityError(e, "sending Header/Footer", null, - "Header/Footer feature not working"); - return null; - } - } - } - /** * Sends header/footer to player. * diff --git a/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/header/PacketHeaderFooter.java b/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/header/PacketHeaderFooter.java index 96df373b6..e89c11dfa 100644 --- a/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/header/PacketHeaderFooter.java +++ b/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/header/PacketHeaderFooter.java @@ -1,13 +1,12 @@ package me.neznamy.tab.platforms.bukkit.header; import lombok.SneakyThrows; +import me.neznamy.chat.component.TabComponent; import me.neznamy.tab.platforms.bukkit.BukkitTabPlayer; import me.neznamy.tab.platforms.bukkit.nms.BukkitReflection; -import me.neznamy.tab.platforms.bukkit.nms.converter.ComponentConverter; import me.neznamy.tab.platforms.bukkit.nms.PacketSender; -import me.neznamy.chat.component.TabComponent; -import me.neznamy.tab.shared.util.function.BiFunctionWithException; import me.neznamy.tab.shared.util.ReflectionUtils; +import me.neznamy.tab.shared.util.function.BiFunctionWithException; import org.jetbrains.annotations.NotNull; import java.lang.reflect.Constructor; @@ -32,7 +31,6 @@ public PacketHeaderFooter() throws ReflectiveOperationException { Class Component = BukkitReflection.getClass("network.chat.Component", "network.chat.IChatBaseComponent", "IChatBaseComponent"); Class HeaderFooterClass = BukkitReflection.getClass("network.protocol.game.ClientboundTabListPacket", "network.protocol.game.PacketPlayOutPlayerListHeaderFooter", "PacketPlayOutPlayerListHeaderFooter"); - if (ComponentConverter.INSTANCE == null) throw new IllegalStateException("Component converter is not available"); if (BukkitReflection.getMinorVersion() >= 17) { Constructor newHeaderFooter = HeaderFooterClass.getConstructor(Component, Component); createPacket = newHeaderFooter::newInstance; diff --git a/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/nms/converter/ComponentConverter.java b/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/nms/converter/ComponentConverter.java index 9f99233e0..ac5f69131 100644 --- a/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/nms/converter/ComponentConverter.java +++ b/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/nms/converter/ComponentConverter.java @@ -5,20 +5,13 @@ import me.neznamy.chat.component.TabComponent; import me.neznamy.chat.component.TextComponent; import me.neznamy.chat.component.TranslatableComponent; -import me.neznamy.tab.platforms.bukkit.BukkitUtils; -import me.neznamy.tab.platforms.bukkit.nms.BukkitReflection; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; /** * Interface for converting TAB components into NMS components (1.7+). */ public abstract class ComponentConverter { - /** Instance of this class */ - @Nullable - public static ComponentConverter INSTANCE; - /** * Converts TAB component to NMS component. * @@ -100,26 +93,4 @@ public Object convert(@NotNull TabComponent component) { * Child component to append */ public abstract void addSibling(@NotNull Object parent, @NotNull Object child); - - /** - * Attempts to load component converter. - */ - public static void tryLoad() { - try { - if (BukkitReflection.getMinorVersion() >= 19) { - // 1.19+ - INSTANCE = new ModernComponentConverter(); - } else if (BukkitReflection.getMinorVersion() >= 16) { - // 1.16 - 1.18.2 - INSTANCE = new ModerateComponentConverter(); - } else { - // 1.7 - 1.15.2 - INSTANCE = new LegacyComponentConverter(); - } - } catch (Exception e) { - if (BukkitUtils.PRINT_EXCEPTIONS) { - e.printStackTrace(); - } - } - } } diff --git a/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/platform/BukkitPlatform.java b/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/platform/BukkitPlatform.java index 926ed1691..7e6d14535 100644 --- a/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/platform/BukkitPlatform.java +++ b/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/platform/BukkitPlatform.java @@ -1,5 +1,6 @@ package me.neznamy.tab.platforms.bukkit.platform; +import com.google.common.collect.Lists; import lombok.Getter; import lombok.SneakyThrows; import me.clip.placeholderapi.PlaceholderAPI; @@ -9,13 +10,18 @@ import me.neznamy.tab.platforms.bukkit.bossbar.ViaBossBar; import me.neznamy.tab.platforms.bukkit.features.BukkitTabExpansion; import me.neznamy.tab.platforms.bukkit.features.PerWorldPlayerList; -import me.neznamy.tab.platforms.bukkit.header.HeaderFooter; +import me.neznamy.tab.platforms.bukkit.header.*; import me.neznamy.tab.platforms.bukkit.hook.BukkitPremiumVanishHook; import me.neznamy.tab.platforms.bukkit.nms.BukkitReflection; import me.neznamy.tab.platforms.bukkit.nms.PingRetriever; import me.neznamy.tab.platforms.bukkit.nms.converter.ComponentConverter; -import me.neznamy.tab.platforms.bukkit.scoreboard.ScoreboardLoader; -import me.neznamy.tab.platforms.bukkit.tablist.TabListBase; +import me.neznamy.tab.platforms.bukkit.nms.converter.LegacyComponentConverter; +import me.neznamy.tab.platforms.bukkit.nms.converter.ModerateComponentConverter; +import me.neznamy.tab.platforms.bukkit.nms.converter.ModernComponentConverter; +import me.neznamy.tab.platforms.bukkit.scoreboard.BukkitScoreboard; +import me.neznamy.tab.platforms.bukkit.scoreboard.PaperScoreboard; +import me.neznamy.tab.platforms.bukkit.scoreboard.packet.PacketScoreboard; +import me.neznamy.tab.platforms.bukkit.tablist.*; import me.neznamy.tab.shared.GroupManager; import me.neznamy.tab.shared.ProtocolVersion; import me.neznamy.tab.shared.TAB; @@ -35,8 +41,10 @@ import me.neznamy.tab.shared.platform.TabPlayer; import me.neznamy.tab.shared.platform.impl.AdventureBossBar; import me.neznamy.tab.shared.platform.impl.DummyBossBar; +import me.neznamy.tab.shared.platform.impl.DummyScoreboard; import me.neznamy.tab.shared.util.PerformanceUtil; import me.neznamy.tab.shared.util.ReflectionUtils; +import me.neznamy.tab.shared.util.function.FunctionWithException; import net.kyori.adventure.audience.Audience; import net.milkbowl.vault.chat.Chat; import net.milkbowl.vault.permission.Permission; @@ -52,6 +60,8 @@ import org.jetbrains.annotations.Nullable; import java.io.File; +import java.util.List; +import java.util.Objects; /** * Implementation of Platform interface for Bukkit platform @@ -79,6 +89,23 @@ public class BukkitPlatform implements BackendPlatform { /** Detection for presence of Paper's MSPT getter */ private final boolean paperMspt = ReflectionUtils.methodExists(Bukkit.class, "getAverageTickTime"); + /** Component converter from TAB to minecraft components */ + @Nullable + private final ComponentConverter componentConverter = findComponentConverter(); + + /** Provider for scoreboard implementation */ + @NotNull + private final FunctionWithException scoreboardProvider = findScoreboardProvider(); + + /** Provider for tablist implementation */ + @NotNull + private final FunctionWithException tablistProvider = findTablistProvider(); + + /** Header/footer implementation */ + @Getter + @NotNull + private final HeaderFooter headerFooter = findHeaderFooter(); + /** * Constructs new instance with given plugin. * @@ -98,17 +125,123 @@ public BukkitPlatform(@NotNull JavaPlugin plugin) { new BukkitPremiumVanishHook().register(); } PingRetriever.tryLoad(); - ComponentConverter.tryLoad(); - ScoreboardLoader.findInstance(); - TabListBase.findInstance(); if (BukkitReflection.getMinorVersion() >= 8) { - HeaderFooter.findInstance(); BukkitPipelineInjector.tryLoad(); } BukkitUtils.sendCompatibilityMessage(); Bukkit.getConsoleSender().sendMessage("[TAB] §7Loaded NMS hook in " + (System.currentTimeMillis()-time) + "ms"); } + @NotNull + private FunctionWithException findScoreboardProvider() { + try { + if (BukkitReflection.getMinorVersion() >= 7) Objects.requireNonNull(componentConverter); + PacketScoreboard.load(); + return PacketScoreboard::new; + } catch (Exception e) { + if (PaperScoreboard.isAvailable()) { + BukkitUtils.compatibilityError(e, "Scoreboards", "Paper API", "Compatibility with other plugins being reduced"); + return PaperScoreboard::new; + } else if (BukkitScoreboard.isAvailable()) { + List missingFeatures = Lists.newArrayList( + "Compatibility with other plugins being reduced", + "Features receiving new artificial character limits" + ); + if (BukkitReflection.is1_20_3Plus()) { + missingFeatures.add("1.20.3+ visuals not working due to lack of API"); // soontm? + } + BukkitUtils.compatibilityError(e, "Scoreboards", "Bukkit API", missingFeatures.toArray(new String[0])); + return BukkitScoreboard::new; + } else if (BukkitReflection.getMinorVersion() >= 5) { + BukkitUtils.compatibilityError(e, "Scoreboards", null, + "Scoreboard feature will not work", + "Belowname feature will not work", + "Player objective feature will not work", + "Scoreboard teams feature will not work (nametags & sorting)"); + } + } + return DummyScoreboard::new; + } + + @NotNull + private FunctionWithException findTablistProvider() { + try { + if (ReflectionUtils.classExists("net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket")) { + // 1.19.3+ + Objects.requireNonNull(componentConverter); + PacketTabList1193.loadNew(); + return PacketTabList1193::new; + } else if (BukkitReflection.getMinorVersion() >= 8) { + // 1.8 - 1.19.2 + Objects.requireNonNull(componentConverter); + PacketTabList18.load(); + return PacketTabList18::new; + } else { + // 1.7.10 and lower + PacketTabList17.load(); + return PacketTabList17::new; + } + } catch (Exception e) { + BukkitUtils.compatibilityError(e, "tablist entry management", "Bukkit API", + "Layout feature will not work", + "Prevent-spectator-effect feature will not work", + "Ping spoof feature will not work", + "Tablist formatting missing anti-override", + "Tablist formatting not supporting relational placeholders"); + return BukkitTabList::new; + } + } + + @NotNull + private HeaderFooter findHeaderFooter() { + if (BukkitReflection.getMinorVersion() >= 8) { + try { + Objects.requireNonNull(componentConverter); + return new PacketHeaderFooter(); + } catch (Exception e) { + if (PaperHeaderFooter.isAvailable()) return new PaperHeaderFooter(); + if (BukkitHeaderFooter.isAvailable()) { + BukkitUtils.compatibilityError(e, "sending Header/Footer", "Bukkit API", + "Header/Footer having drastically increased CPU usage", + "Header/Footer not supporting fonts (1.16+)"); + return new BukkitHeaderFooter(); + } else { + BukkitUtils.compatibilityError(e, "sending Header/Footer", null, + "Header/Footer feature not working"); + } + } + } + return new DummyHeaderFooter(); + } + + /** + * Attempts to load component converter. + * + * @return Instance or {@code null} if not available + */ + @Nullable + public static ComponentConverter findComponentConverter() { + try { + if (BukkitReflection.getMinorVersion() >= 19) { + // 1.19+ + return new ModernComponentConverter(); + } else if (BukkitReflection.getMinorVersion() >= 16) { + // 1.16 - 1.18.2 + return new ModerateComponentConverter(); + } else { + // 1.7 - 1.15.2 + return new LegacyComponentConverter(); + } + } catch (Exception e) { + Bukkit.getConsoleSender().sendMessage("§c[TAB] Failed to initialize converter from TAB components to Minecraft components. " + + "This will negatively impact most features, see below."); + if (BukkitUtils.PRINT_EXCEPTIONS) { + e.printStackTrace(); + } + return null; + } + } + @Override public void loadPlayers() { for (Player p : BukkitUtils.getOnlinePlayers()) { @@ -254,8 +387,8 @@ public File getDataFolder() { @Override @NotNull public Object convertComponent(@NotNull TabComponent component) { - if (ComponentConverter.INSTANCE != null) { - return ComponentConverter.INSTANCE.convert(component); + if (componentConverter != null) { + return componentConverter.convert(component); } else { return component; } @@ -265,7 +398,7 @@ public Object convertComponent(@NotNull TabComponent component) { @NotNull @SneakyThrows public Scoreboard createScoreboard(@NotNull TabPlayer player) { - return ScoreboardLoader.getInstance().apply((BukkitTabPlayer) player); + return scoreboardProvider.apply((BukkitTabPlayer) player); } @Override @@ -288,7 +421,7 @@ public BossBar createBossBar(@NotNull TabPlayer player) { @NotNull @SneakyThrows public TabList createTabList(@NotNull TabPlayer player) { - return TabListBase.getInstance().apply((BukkitTabPlayer) player); + return tablistProvider.apply((BukkitTabPlayer) player); } @Override diff --git a/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/scoreboard/ScoreboardLoader.java b/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/scoreboard/ScoreboardLoader.java deleted file mode 100644 index a35958a56..000000000 --- a/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/scoreboard/ScoreboardLoader.java +++ /dev/null @@ -1,55 +0,0 @@ -package me.neznamy.tab.platforms.bukkit.scoreboard; - -import com.google.common.collect.Lists; -import lombok.Getter; -import lombok.Setter; -import me.neznamy.tab.platforms.bukkit.BukkitTabPlayer; -import me.neznamy.tab.platforms.bukkit.BukkitUtils; -import me.neznamy.tab.platforms.bukkit.nms.BukkitReflection; -import me.neznamy.tab.platforms.bukkit.scoreboard.packet.PacketScoreboard; -import me.neznamy.tab.shared.platform.Scoreboard; -import me.neznamy.tab.shared.platform.impl.DummyScoreboard; -import me.neznamy.tab.shared.util.function.FunctionWithException; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -/** - * Loader finding the best available Scoreboard implementation. - */ -public class ScoreboardLoader { - - /** Instance function */ - @Getter - @Setter - @NotNull - private static FunctionWithException instance = DummyScoreboard::new; - - /** - * Finds the best available instance for current server software. - */ - public static void findInstance() { - if (PacketScoreboard.isAvailable()) { - instance = PacketScoreboard::new; - } else if (PaperScoreboard.isAvailable()) { - instance = PaperScoreboard::new; - BukkitUtils.compatibilityError(PacketScoreboard.getException(), "Scoreboards", "Paper API", "Compatibility with other plugins being reduced"); - } else if (BukkitScoreboard.isAvailable()) { - instance = BukkitScoreboard::new; - List missingFeatures = Lists.newArrayList( - "Compatibility with other plugins being reduced", - "Features receiving new artificial character limits" - ); - if (BukkitReflection.is1_20_3Plus()) { - missingFeatures.add("1.20.3+ visuals not working due to lack of API"); // soontm? - } - BukkitUtils.compatibilityError(PacketScoreboard.getException(), "Scoreboards", "Bukkit API", missingFeatures.toArray(new String[0])); - } else { - BukkitUtils.compatibilityError(PacketScoreboard.getException(), "Scoreboards", null, - "Scoreboard feature will not work", - "Belowname feature will not work", - "Player objective feature will not work", - "Scoreboard teams feature will not work (nametags & sorting)"); - } - } -} diff --git a/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/scoreboard/packet/PacketScoreboard.java b/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/scoreboard/packet/PacketScoreboard.java index 9507ec415..b3e010ff5 100644 --- a/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/scoreboard/packet/PacketScoreboard.java +++ b/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/scoreboard/packet/PacketScoreboard.java @@ -7,7 +7,6 @@ import me.neznamy.tab.platforms.bukkit.BukkitTabPlayer; import me.neznamy.tab.platforms.bukkit.nms.BukkitReflection; import me.neznamy.tab.platforms.bukkit.nms.PacketSender; -import me.neznamy.tab.platforms.bukkit.nms.converter.ComponentConverter; import me.neznamy.tab.shared.Limitations; import me.neznamy.tab.shared.TAB; import me.neznamy.tab.shared.platform.decorators.SafeScoreboard; @@ -28,12 +27,6 @@ */ public class PacketScoreboard extends SafeScoreboard { - @Getter - private static boolean available; - - @Getter - private static Exception exception; - static Class Component; static Class Scoreboard; static Class ScoreboardObjective; @@ -57,60 +50,54 @@ public class PacketScoreboard extends SafeScoreboard { @Getter private static DisplayPacketData displayPacketData; private static PacketSender packetSender; - static { - try { - int minorVersion = BukkitReflection.getMinorVersion(); - Scoreboard = BukkitReflection.getClass("world.scores.Scoreboard", "Scoreboard"); - ScoreboardObjective = BukkitReflection.getClass("world.scores.Objective", "world.scores.ScoreboardObjective", "ScoreboardObjective"); - Class IScoreboardCriteria = BukkitReflection.getClass( - "world.scores.criteria.ObjectiveCriteria", // Mojang mapped - "world.scores.criteria.IScoreboardCriteria", // Bukkit 1.17.+ - "IScoreboardCriteria", // 1.5.1 - 1.16.5 - "IObjective" // 1.5.0 - ); - ObjectivePacketClass = BukkitReflection.getClass( - "network.protocol.game.ClientboundSetObjectivePacket", // Mojang mapped - "network.protocol.game.PacketPlayOutScoreboardObjective", // Bukkit 1.17+ - "PacketPlayOutScoreboardObjective", // 1.7 - 1.16.5 - "Packet206SetScoreboardObjective" // 1.5 - 1.6.4 - ); - emptyScoreboard = Scoreboard.getConstructor().newInstance(); - Objective_OBJECTIVE_NAME = ReflectionUtils.getFields(ObjectivePacketClass, String.class).get(0); - List list = ReflectionUtils.getFields(ObjectivePacketClass, int.class); - Objective_METHOD = list.get(list.size()-1); - newObjectivePacket = ObjectivePacketClass.getConstructor(ScoreboardObjective, int.class); - IScoreboardCriteria_dummy = ReflectionUtils.getFields(IScoreboardCriteria, IScoreboardCriteria).get(0).get(null); - newScoreboardObjective = ReflectionUtils.getOnlyConstructor(ScoreboardObjective); - if (minorVersion >= 7) { - Component = BukkitReflection.getClass("network.chat.Component", "network.chat.IChatBaseComponent", "IChatBaseComponent"); - if (ComponentConverter.INSTANCE == null) throw new IllegalStateException("Component converter is not available"); - } - if (minorVersion >= 8) { - Class EnumScoreboardHealthDisplay = BukkitReflection.getClass( - "world.scores.criteria.ObjectiveCriteria$RenderType", - "world.scores.criteria.IScoreboardCriteria$EnumScoreboardHealthDisplay", - "IScoreboardCriteria$EnumScoreboardHealthDisplay", - "EnumScoreboardHealthDisplay"); - healthDisplays = (Enum[]) EnumScoreboardHealthDisplay.getMethod("values").invoke(null); - if (minorVersion < 13) { - Objective_RENDER_TYPE = ReflectionUtils.getOnlyField(ObjectivePacketClass, EnumScoreboardHealthDisplay); - } - } + public static void load() throws ReflectiveOperationException { + int minorVersion = BukkitReflection.getMinorVersion(); + Scoreboard = BukkitReflection.getClass("world.scores.Scoreboard", "Scoreboard"); + ScoreboardObjective = BukkitReflection.getClass("world.scores.Objective", "world.scores.ScoreboardObjective", "ScoreboardObjective"); + Class IScoreboardCriteria = BukkitReflection.getClass( + "world.scores.criteria.ObjectiveCriteria", // Mojang mapped + "world.scores.criteria.IScoreboardCriteria", // Bukkit 1.17.+ + "IScoreboardCriteria", // 1.5.1 - 1.16.5 + "IObjective" // 1.5.0 + ); + ObjectivePacketClass = BukkitReflection.getClass( + "network.protocol.game.ClientboundSetObjectivePacket", // Mojang mapped + "network.protocol.game.PacketPlayOutScoreboardObjective", // Bukkit 1.17+ + "PacketPlayOutScoreboardObjective", // 1.7 - 1.16.5 + "Packet206SetScoreboardObjective" // 1.5 - 1.6.4 + ); + emptyScoreboard = Scoreboard.getConstructor().newInstance(); + Objective_OBJECTIVE_NAME = ReflectionUtils.getFields(ObjectivePacketClass, String.class).get(0); + List list = ReflectionUtils.getFields(ObjectivePacketClass, int.class); + Objective_METHOD = list.get(list.size()-1); + newObjectivePacket = ObjectivePacketClass.getConstructor(ScoreboardObjective, int.class); + IScoreboardCriteria_dummy = ReflectionUtils.getFields(IScoreboardCriteria, IScoreboardCriteria).get(0).get(null); + newScoreboardObjective = ReflectionUtils.getOnlyConstructor(ScoreboardObjective); + if (minorVersion >= 7) { + Component = BukkitReflection.getClass("network.chat.Component", "network.chat.IChatBaseComponent", "IChatBaseComponent"); + } + if (minorVersion >= 8) { + Class EnumScoreboardHealthDisplay = BukkitReflection.getClass( + "world.scores.criteria.ObjectiveCriteria$RenderType", + "world.scores.criteria.IScoreboardCriteria$EnumScoreboardHealthDisplay", + "IScoreboardCriteria$EnumScoreboardHealthDisplay", + "EnumScoreboardHealthDisplay"); + healthDisplays = (Enum[]) EnumScoreboardHealthDisplay.getMethod("values").invoke(null); if (minorVersion < 13) { - ScoreboardObjective_setDisplayName = ReflectionUtils.getOnlyMethod(ScoreboardObjective, void.class, String.class); - } - if (BukkitReflection.is1_20_3Plus()) { - NumberFormat = BukkitReflection.getClass("network.chat.numbers.NumberFormat"); - newFixedFormat = BukkitReflection.getClass("network.chat.numbers.FixedFormat").getConstructor(Component); + Objective_RENDER_TYPE = ReflectionUtils.getOnlyField(ObjectivePacketClass, EnumScoreboardHealthDisplay); } - scorePacketData = new ScorePacketData(); - teamPacketData = new TeamPacketData(); - displayPacketData = new DisplayPacketData(); - packetSender = new PacketSender(); - available = true; - } catch (Exception e) { - exception = e; } + if (minorVersion < 13) { + ScoreboardObjective_setDisplayName = ReflectionUtils.getOnlyMethod(ScoreboardObjective, void.class, String.class); + } + if (BukkitReflection.is1_20_3Plus()) { + NumberFormat = BukkitReflection.getClass("network.chat.numbers.NumberFormat"); + newFixedFormat = BukkitReflection.getClass("network.chat.numbers.FixedFormat").getConstructor(Component); + } + scorePacketData = new ScorePacketData(); + teamPacketData = new TeamPacketData(); + displayPacketData = new DisplayPacketData(); + packetSender = new PacketSender(); } /** diff --git a/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/tablist/PacketTabList18.java b/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/tablist/PacketTabList18.java index 1ce13fc5a..61f521d7c 100644 --- a/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/tablist/PacketTabList18.java +++ b/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/tablist/PacketTabList18.java @@ -8,7 +8,6 @@ import me.neznamy.chat.component.TabComponent; import me.neznamy.tab.platforms.bukkit.BukkitTabPlayer; import me.neznamy.tab.platforms.bukkit.BukkitUtils; -import me.neznamy.tab.platforms.bukkit.nms.converter.ComponentConverter; import me.neznamy.tab.platforms.bukkit.nms.BukkitReflection; import me.neznamy.tab.platforms.bukkit.nms.PacketSender; import me.neznamy.tab.shared.TAB; @@ -101,7 +100,6 @@ protected static void loadSharedContent(Class infoData, Class gameMode) Enum.valueOf(gameMode, "SPECTATOR") }; packetSender = new PacketSender(); - if (ComponentConverter.INSTANCE == null) throw new IllegalStateException("Component converter is not available"); try { skinData = new SkinData(); } catch (Exception e) { diff --git a/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/tablist/TabListBase.java b/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/tablist/TabListBase.java index 58b80a744..4f81c1f23 100644 --- a/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/tablist/TabListBase.java +++ b/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/tablist/TabListBase.java @@ -1,16 +1,9 @@ package me.neznamy.tab.platforms.bukkit.tablist; -import lombok.Getter; import lombok.NonNull; -import lombok.Setter; import me.neznamy.chat.component.TabComponent; import me.neznamy.tab.platforms.bukkit.BukkitTabPlayer; -import me.neznamy.tab.platforms.bukkit.BukkitUtils; -import me.neznamy.tab.platforms.bukkit.header.HeaderFooter; -import me.neznamy.tab.platforms.bukkit.nms.BukkitReflection; import me.neznamy.tab.shared.platform.decorators.TrackedTabList; -import me.neznamy.tab.shared.util.ReflectionUtils; -import me.neznamy.tab.shared.util.function.FunctionWithException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -21,11 +14,6 @@ */ public abstract class TabListBase extends TrackedTabList { - /** Instance function */ - @Getter - @Setter - private static FunctionWithException instance; - @Nullable protected static SkinData skinData; @@ -39,35 +27,9 @@ protected TabListBase(@NotNull BukkitTabPlayer player) { super(player); } - /** - * Finds the best available instance for current server software. - */ - public static void findInstance() { - try { - if (ReflectionUtils.classExists("net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket")) { - PacketTabList1193.loadNew(); - instance = PacketTabList1193::new; - } else if (BukkitReflection.getMinorVersion() >= 8) { - PacketTabList18.load(); - instance = PacketTabList18::new; - } else { - PacketTabList17.load(); - instance = PacketTabList17::new; - } - } catch (Exception e) { - BukkitUtils.compatibilityError(e, "tablist entry management", "Bukkit API", - "Layout feature will not work", - "Prevent-spectator-effect feature will not work", - "Ping spoof feature will not work", - "Tablist formatting missing anti-override", - "Tablist formatting not supporting relational placeholders"); - instance = BukkitTabList::new; - } - } - @Override public void setPlayerListHeaderFooter(@NonNull TabComponent header, @NonNull TabComponent footer) { - if (HeaderFooter.getInstance() != null) HeaderFooter.getInstance().set(player, header, footer); + player.getPlatform().getHeaderFooter().set(player, header, footer); } @Override