diff --git a/README.md b/README.md index c036fc1..b3843ad 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,9 @@ This project is divided in several modules: - `sidebar-v_1_20_R2` provides support for 1.20.2 (R2) - `sidebar-v_1_20_R3` provides support for 1.20.3 (R3) - `sidebar-v_1_20_R4` provides support for 1.20.4 (R4). Requires `sidebar-v_1_20_R3`. -- `sidebar-v_1_21_R1` provides support for 1.21.1 (R1). Requires `sidebar-cmn1`. +- `sidebar-v_1_21_R1` provides support for 1.21 and 1.21.1 (R1). Requires `sidebar-cmn1`. +- `sidebar-v_1_21_R2` provides support for 1.21.3 (R2). Requires `sidebar-cmn1`. +- `sidebar-v_1_21_R3` provides support for 1.21.4 (R3). Requires `sidebar-cmn1`. ### IMPORTANT It is really important to call Sidebar#remove(player) when a player leaves the server to avoid memory leaks. diff --git a/pom.xml b/pom.xml index 7bc8aa4..6ed6368 100644 --- a/pom.xml +++ b/pom.xml @@ -7,9 +7,11 @@ com.andrei1058.spigot.sidebar sidebar-pom pom - 25.2.1-SNAPSHOT + 25.2.2-SNAPSHOT sidebar-base + sidebar-v1_21_R3 + sidebar-v1_21_R2 sidebar-v1_21_R1 sidebar-v1_20_R4 sidebar-v1_20_R3 diff --git a/sidebar-base/pom.xml b/sidebar-base/pom.xml index faa2152..35d3b1b 100644 --- a/sidebar-base/pom.xml +++ b/sidebar-base/pom.xml @@ -5,7 +5,7 @@ sidebar-pom com.andrei1058.spigot.sidebar - 25.2.1-SNAPSHOT + 25.2.2-SNAPSHOT 4.0.0 diff --git a/sidebar-base/src/main/java/com/andrei1058/spigot/sidebar/PAPIAdapter.java b/sidebar-base/src/main/java/com/andrei1058/spigot/sidebar/PAPIAdapter.java index aedcd08..d3caca8 100644 --- a/sidebar-base/src/main/java/com/andrei1058/spigot/sidebar/PAPIAdapter.java +++ b/sidebar-base/src/main/java/com/andrei1058/spigot/sidebar/PAPIAdapter.java @@ -8,6 +8,9 @@ import java.util.regex.Pattern; public class PAPIAdapter implements PAPISupport { + + public PAPIAdapter() {} + @Override public String replacePlaceholders(Player p, String s) { return PlaceholderAPI.setPlaceholders(p, s); diff --git a/sidebar-cmn1/pom.xml b/sidebar-cmn1/pom.xml index bf5f25b..e01a7f0 100644 --- a/sidebar-cmn1/pom.xml +++ b/sidebar-cmn1/pom.xml @@ -6,7 +6,7 @@ com.andrei1058.spigot.sidebar sidebar-pom - 25.2.1-SNAPSHOT + 25.2.2-SNAPSHOT sidebar-cmn1 @@ -40,24 +40,4 @@ provided - - - - - org.apache.maven.plugins - maven-compiler-plugin - - 20 - 20 - - - - org.apache.maven.plugins - maven-javadoc-plugin - - true - - - - \ No newline at end of file diff --git a/sidebar-v1_12_R1/pom.xml b/sidebar-v1_12_R1/pom.xml index 318a733..66f4bf4 100644 --- a/sidebar-v1_12_R1/pom.xml +++ b/sidebar-v1_12_R1/pom.xml @@ -5,7 +5,7 @@ sidebar-pom com.andrei1058.spigot.sidebar - 25.2.1-SNAPSHOT + 25.2.2-SNAPSHOT 4.0.0 diff --git a/sidebar-v1_16_R3/pom.xml b/sidebar-v1_16_R3/pom.xml index 5cfa2fc..00ddbad 100644 --- a/sidebar-v1_16_R3/pom.xml +++ b/sidebar-v1_16_R3/pom.xml @@ -5,7 +5,7 @@ sidebar-pom com.andrei1058.spigot.sidebar - 25.2.1-SNAPSHOT + 25.2.2-SNAPSHOT 4.0.0 diff --git a/sidebar-v1_17_R1/pom.xml b/sidebar-v1_17_R1/pom.xml index f40da2d..1f89053 100644 --- a/sidebar-v1_17_R1/pom.xml +++ b/sidebar-v1_17_R1/pom.xml @@ -5,7 +5,7 @@ sidebar-pom com.andrei1058.spigot.sidebar - 25.2.1-SNAPSHOT + 25.2.2-SNAPSHOT 4.0.0 diff --git a/sidebar-v1_18_R2/pom.xml b/sidebar-v1_18_R2/pom.xml index 084f4af..da71b32 100644 --- a/sidebar-v1_18_R2/pom.xml +++ b/sidebar-v1_18_R2/pom.xml @@ -5,7 +5,7 @@ sidebar-pom com.andrei1058.spigot.sidebar - 25.2.1-SNAPSHOT + 25.2.2-SNAPSHOT 4.0.0 diff --git a/sidebar-v1_19_R2/pom.xml b/sidebar-v1_19_R2/pom.xml index f105f7c..9f5d9cb 100644 --- a/sidebar-v1_19_R2/pom.xml +++ b/sidebar-v1_19_R2/pom.xml @@ -5,7 +5,7 @@ sidebar-pom com.andrei1058.spigot.sidebar - 25.2.1-SNAPSHOT + 25.2.2-SNAPSHOT 4.0.0 diff --git a/sidebar-v1_19_R3/pom.xml b/sidebar-v1_19_R3/pom.xml index 52d1c5e..373e756 100644 --- a/sidebar-v1_19_R3/pom.xml +++ b/sidebar-v1_19_R3/pom.xml @@ -5,7 +5,7 @@ sidebar-pom com.andrei1058.spigot.sidebar - 25.2.1-SNAPSHOT + 25.2.2-SNAPSHOT 4.0.0 diff --git a/sidebar-v1_20_R1/pom.xml b/sidebar-v1_20_R1/pom.xml index 1d0de9f..846b61b 100644 --- a/sidebar-v1_20_R1/pom.xml +++ b/sidebar-v1_20_R1/pom.xml @@ -5,7 +5,7 @@ sidebar-pom com.andrei1058.spigot.sidebar - 25.2.1-SNAPSHOT + 25.2.2-SNAPSHOT 4.0.0 diff --git a/sidebar-v1_20_R2/pom.xml b/sidebar-v1_20_R2/pom.xml index fafd146..4677e62 100644 --- a/sidebar-v1_20_R2/pom.xml +++ b/sidebar-v1_20_R2/pom.xml @@ -5,7 +5,7 @@ sidebar-pom com.andrei1058.spigot.sidebar - 25.2.1-SNAPSHOT + 25.2.2-SNAPSHOT 4.0.0 diff --git a/sidebar-v1_20_R3/pom.xml b/sidebar-v1_20_R3/pom.xml index e3f3d80..d18573f 100644 --- a/sidebar-v1_20_R3/pom.xml +++ b/sidebar-v1_20_R3/pom.xml @@ -5,7 +5,7 @@ sidebar-pom com.andrei1058.spigot.sidebar - 25.2.1-SNAPSHOT + 25.2.2-SNAPSHOT 4.0.0 diff --git a/sidebar-v1_20_R4/pom.xml b/sidebar-v1_20_R4/pom.xml index a8ee94b..cde30c7 100644 --- a/sidebar-v1_20_R4/pom.xml +++ b/sidebar-v1_20_R4/pom.xml @@ -5,7 +5,7 @@ sidebar-pom com.andrei1058.spigot.sidebar - 25.2.1-SNAPSHOT + 25.2.2-SNAPSHOT 4.0.0 diff --git a/sidebar-v1_21_R1/pom.xml b/sidebar-v1_21_R1/pom.xml index 1aff02b..dd1ddfb 100644 --- a/sidebar-v1_21_R1/pom.xml +++ b/sidebar-v1_21_R1/pom.xml @@ -5,7 +5,7 @@ sidebar-pom com.andrei1058.spigot.sidebar - 25.2.1-SNAPSHOT + 25.2.2-SNAPSHOT 4.0.0 diff --git a/sidebar-v1_21_R1/src/main/java/com/andrei1058/spigot/sidebar/v1_21_R1/PlayerListImpl.java b/sidebar-v1_21_R1/src/main/java/com/andrei1058/spigot/sidebar/v1_21_R1/PlayerListImpl.java index fed800b..711e5c9 100644 --- a/sidebar-v1_21_R1/src/main/java/com/andrei1058/spigot/sidebar/v1_21_R1/PlayerListImpl.java +++ b/sidebar-v1_21_R1/src/main/java/com/andrei1058/spigot/sidebar/v1_21_R1/PlayerListImpl.java @@ -2,11 +2,16 @@ import com.andrei1058.spigot.sidebar.*; import dev.andrei1058.spigot.sidebar.cmn1.PlayerListImplCmn1; +import net.minecraft.network.chat.IChatBaseComponent; +import net.minecraft.network.chat.IChatMutableComponent; import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.game.PacketPlayOutScoreboardTeam; import net.minecraft.world.scores.ScoreboardTeam; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; import org.bukkit.craftbukkit.v1_21_R1.entity.CraftPlayer; import org.bukkit.entity.Player; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -65,7 +70,7 @@ public void sendCreateToPlayer(Player player) { public void sendUserCreateToReceivers(@NotNull Player player) { // send 3: add entities to team PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeam = PacketPlayOutScoreboardTeam.a( - this, player.getName(), (PacketPlayOutScoreboardTeam.a) cachedScoreboardActionA); + this, player.getName(), cachedScoreboardActionA); handle.getSidebar().getReceivers().forEach( r -> sendPacket(r, packetPlayOutScoreboardTeam) ); @@ -150,13 +155,25 @@ private static Object getScoreboardAction(String action) { if (action.equals(name)) { return obj; } - } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) { - //Bukkit.getConsoleSender().sendMessage(ChatColor.RED+"Could not find ENUM"); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) { } } - } catch (Exception exception) { -// exception.printStackTrace(); + } catch (Exception ignored) { } throw new RuntimeException("Something went wrong... please report this to SidebarLib by andrei1058"); } + + public @NotNull IChatBaseComponent e() { + return handle.getPrefixComp(); + } + + public @NotNull IChatBaseComponent f() { + return handle.getSuffixComp(); + } + + @Contract(value = "_ -> new", pure = true) + @Override + public @NotNull IChatMutableComponent d(IChatBaseComponent var0) { + return IChatBaseComponent.b(handle.getPrefixComp().toString() + var0.getString() + handle.getSuffixComp().toString()); + } } diff --git a/sidebar-v1_21_R1/src/main/java/com/andrei1058/spigot/sidebar/v1_21_R1/ProviderImpl.java b/sidebar-v1_21_R1/src/main/java/com/andrei1058/spigot/sidebar/v1_21_R1/ProviderImpl.java index 72a05fb..09af5d2 100644 --- a/sidebar-v1_21_R1/src/main/java/com/andrei1058/spigot/sidebar/v1_21_R1/ProviderImpl.java +++ b/sidebar-v1_21_R1/src/main/java/com/andrei1058/spigot/sidebar/v1_21_R1/ProviderImpl.java @@ -37,8 +37,8 @@ public ScoreLine createScoreLine(WrappedSidebar sidebar, SidebarLine line, int s public void sendScore(@NotNull WrappedSidebar sidebar, String playerName, int score) { if (sidebar.getHealthObjective() == null) return; PacketPlayOutScoreboardScore packetPlayOutScoreboardScore = new PacketPlayOutScoreboardScore( - sidebar.getHealthObjective().getName(), playerName, + sidebar.getHealthObjective().getName(), score, Optional.empty(), Optional.empty() diff --git a/sidebar-v1_21_R1/src/main/java/com/andrei1058/spigot/sidebar/v1_21_R1/SidebarImpl.java b/sidebar-v1_21_R1/src/main/java/com/andrei1058/spigot/sidebar/v1_21_R1/SidebarImpl.java index dbc512c..4b9dfc3 100644 --- a/sidebar-v1_21_R1/src/main/java/com/andrei1058/spigot/sidebar/v1_21_R1/SidebarImpl.java +++ b/sidebar-v1_21_R1/src/main/java/com/andrei1058/spigot/sidebar/v1_21_R1/SidebarImpl.java @@ -40,7 +40,7 @@ public SidebarObjective createObjective(String name, IScoreboardCriteria iScoreb protected class SidebarObjectiveImpl extends ScoreboardObjective implements SidebarObjective { private SidebarLine displayName; - private IChatMutableComponent displayNameComp = IChatBaseComponent.b(" "); + private IChatMutableComponent displayNameComp = IChatBaseComponent.b(""); private final DisplaySlot type; public SidebarObjectiveImpl(String name, IScoreboardCriteria criteria, SidebarLine displayName, int type) { @@ -71,7 +71,7 @@ public void sendRemove(Player player) { @Override public String getName() { - return this.b(); + return super.b(); } @Override @@ -227,6 +227,7 @@ public void sendCreate(Player player) { @Override public void sendRemove(Player player) { PlayerConnection conn = ((CraftPlayer) player).getHandle().c; + // var1=1 means remove PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeam = PacketPlayOutScoreboardTeam.a(team); var resetScore = new ClientboundResetScorePacket(team.b(), getSidebarObjective().getName()); conn.b(resetScore); @@ -241,6 +242,7 @@ public void sendRemoveToAllReceivers() { } public void sendUpdate(Player player) { + // false=2 is for update packet, true=0 for create PacketPlayOutScoreboardTeam packetTeamUpdate = PacketPlayOutScoreboardTeam.a(team, false); ((CraftPlayer) player).getHandle().c.b(packetTeamUpdate); } @@ -280,6 +282,7 @@ public void setSuffix(@NotNull String secondPart) { } public void sendUpdateToAllReceivers() { + // false=2 is for update packet, true=0 for create PacketPlayOutScoreboardTeam packetTeamUpdate = PacketPlayOutScoreboardTeam.a(team, false); getReceivers().forEach(r -> ((CraftPlayer) r).getHandle().c.b(packetTeamUpdate)); } diff --git a/sidebar-v1_21_R2/pom.xml b/sidebar-v1_21_R2/pom.xml new file mode 100644 index 0000000..c86cc31 --- /dev/null +++ b/sidebar-v1_21_R2/pom.xml @@ -0,0 +1,61 @@ + + + + sidebar-pom + com.andrei1058.spigot.sidebar + 25.2.2-SNAPSHOT + + 4.0.0 + + sidebar-v1_21_R2 + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 20 + 20 + + + + org.apache.maven.plugins + maven-javadoc-plugin + + true + + + + + + + + nms + https://repo.codemc.io/repository/nms/ + + + + + + com.andrei1058.spigot.sidebar + sidebar-base + ${project.version} + provided + + + org.spigotmc + spigot + 1.21.3-R0.1-SNAPSHOT + provided + + + com.andrei1058.spigot.sidebar + sidebar-cmn1 + ${project.version} + compile + + + \ No newline at end of file diff --git a/sidebar-v1_21_R2/src/main/java/com/andrei1058/spigot/sidebar/v1_21_R2/PlayerListImpl.java b/sidebar-v1_21_R2/src/main/java/com/andrei1058/spigot/sidebar/v1_21_R2/PlayerListImpl.java new file mode 100644 index 0000000..889bbd9 --- /dev/null +++ b/sidebar-v1_21_R2/src/main/java/com/andrei1058/spigot/sidebar/v1_21_R2/PlayerListImpl.java @@ -0,0 +1,177 @@ +package com.andrei1058.spigot.sidebar.v1_21_R2; + +import com.andrei1058.spigot.sidebar.*; +import dev.andrei1058.spigot.sidebar.cmn1.PlayerListImplCmn1; +import net.minecraft.network.chat.IChatBaseComponent; +import net.minecraft.network.chat.IChatMutableComponent; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.PacketPlayOutScoreboardTeam; +import net.minecraft.world.scores.ScoreboardTeam; +import org.bukkit.craftbukkit.v1_21_R2.entity.CraftPlayer; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Collection; + +@SuppressWarnings("unused") +public class PlayerListImpl extends ScoreboardTeam implements VersionedTabGroup { + + private static PacketPlayOutScoreboardTeam.a cachedScoreboardActionA; + private static PacketPlayOutScoreboardTeam.a cachedScoreboardActionB; + + private final PlayerListImplCmn1 handle; + + public PlayerListImpl( + @NotNull WrappedSidebar sidebar, + String identifier, + SidebarLine prefix, + SidebarLine suffix, + PlayerTab.PushingRule pushingRule, + PlayerTab.NameTagVisibility nameTagVisibility, + @Nullable Collection placeholders + ) { + super(null, identifier); + handle = new PlayerListImplCmn1( + sidebar, + identifier, + prefix, + suffix, + pushingRule, + nameTagVisibility, + placeholders + ); + + if (null == cachedScoreboardActionA) { + cachedScoreboardActionA = (PacketPlayOutScoreboardTeam.a) getScoreboardAction("ADD"); + if (null == cachedScoreboardActionA){ + cachedScoreboardActionA = (PacketPlayOutScoreboardTeam.a) getScoreboardAction("a"); + } + } + if (null == cachedScoreboardActionB) { + cachedScoreboardActionB = (PacketPlayOutScoreboardTeam.a) getScoreboardAction("REMOVE"); + if (null == cachedScoreboardActionB) { + cachedScoreboardActionB = (PacketPlayOutScoreboardTeam.a) getScoreboardAction("b"); + } + } + } + + @Override + public void sendCreateToPlayer(Player player) { + sendPacket(player, PacketPlayOutScoreboardTeam.a(this, true)); + } + + @Override + public void sendUserCreateToReceivers(@NotNull Player player) { + // send 3: add entities to team + PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeam = PacketPlayOutScoreboardTeam.a( + this, player.getName(), cachedScoreboardActionA); + handle.getSidebar().getReceivers().forEach( + r -> sendPacket(r, packetPlayOutScoreboardTeam) + ); + } + + @Override + public void sendUpdateToReceivers() { + PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeam = PacketPlayOutScoreboardTeam.a(this, false); + handle.getSidebar().getReceivers().forEach(r -> sendPacket(r, packetPlayOutScoreboardTeam)); + } + + @Override + public void sendRemoveToReceivers() { + PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeam = PacketPlayOutScoreboardTeam.a(this); + handle.getSidebar().getReceivers().forEach(r -> sendPacket(r, packetPlayOutScoreboardTeam)); + } + + @Override + public boolean refreshContent() { + return handle.refreshContent(); + } + + private void sendPacket(Player player, Packet packet) { + ((CraftPlayer) player).getHandle().f.b(packet); + } + + @Override + public void add(@NotNull Player player) { + PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeam = PacketPlayOutScoreboardTeam.a( + this, player.getName(), cachedScoreboardActionA + ); + handle.getSidebar().getReceivers().forEach(r -> sendPacket(r, packetPlayOutScoreboardTeam)); + } + + @Override + public void remove(@NotNull Player player) { + // send 4: remove entities from team + PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeam = PacketPlayOutScoreboardTeam.a( + this, player.getName(), cachedScoreboardActionB + ); + handle.getSidebar().getReceivers().forEach(r -> sendPacket(r, packetPlayOutScoreboardTeam)); + } + + @Override + public void setSubject(@Nullable Player player) { + this.handle.setPapiSubject(player); + } + + @Override + public @Nullable Player getSubject() { + return this.handle.getPapiSubject(); + } + + @Override + public void setPushingRule(@NotNull PushingRule rule) { + this.handle.setPushingRule(this.handle.toNmsPushing(rule)); + if (null != this.handle.getId()) { + sendUpdateToReceivers(); + } + } + + @Override + public void setNameTagVisibility(@NotNull NameTagVisibility nameTagVisibility) { + this.handle.setNameTagVisibility(this.handle.toNmsTagVisibility(nameTagVisibility)); + if (null != this.handle.getId()){ + sendUpdateToReceivers(); + } + } + + @Override + public String getIdentifier() { + return handle.getId(); + } + + private static Object getScoreboardAction(String action) { + try { + Class cls = Class.forName("net.minecraft.network.protocol.game.PacketPlayOutScoreboardTeam$a"); + for (Object obj : cls.getEnumConstants()) { + try { + Method m = cls.getMethod("name"); + String name = (String) m.invoke(obj); + if (action.equals(name)) { + return obj; + } + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) { + } + } + } catch (Exception ignored) { + } + throw new RuntimeException("Something went wrong... please report this to SidebarLib by andrei1058"); + } + + public @NotNull IChatBaseComponent e() { + return handle.getPrefixComp(); + } + + public @NotNull IChatBaseComponent f() { + return handle.getSuffixComp(); + } + + @Contract(value = "_ -> new", pure = true) + @Override + public @NotNull IChatMutableComponent d(IChatBaseComponent var0) { + return IChatBaseComponent.b(handle.getPrefixComp().toString() + var0.getString() + handle.getSuffixComp().toString()); + } +} diff --git a/sidebar-v1_21_R2/src/main/java/com/andrei1058/spigot/sidebar/v1_21_R2/ProviderImpl.java b/sidebar-v1_21_R2/src/main/java/com/andrei1058/spigot/sidebar/v1_21_R2/ProviderImpl.java new file mode 100644 index 0000000..840c33d --- /dev/null +++ b/sidebar-v1_21_R2/src/main/java/com/andrei1058/spigot/sidebar/v1_21_R2/ProviderImpl.java @@ -0,0 +1,66 @@ +package com.andrei1058.spigot.sidebar.v1_21_R2; + +import com.andrei1058.spigot.sidebar.*; +import net.minecraft.network.chat.IChatBaseComponent; +import net.minecraft.network.protocol.game.PacketPlayOutPlayerListHeaderFooter; +import net.minecraft.network.protocol.game.PacketPlayOutScoreboardScore; +import net.minecraft.server.network.PlayerConnection; +import net.minecraft.world.scores.criteria.IScoreboardCriteria; +import org.bukkit.craftbukkit.v1_21_R2.entity.CraftPlayer; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; +import java.util.Optional; + +@SuppressWarnings("unused") +public class ProviderImpl extends SidebarProvider { + private static SidebarProvider instance; + + @Override + public Sidebar createSidebar(SidebarLine title, Collection lines, Collection placeholderProviders) { + return new SidebarImpl(title, lines, placeholderProviders); + } + + @Override + public SidebarObjective createObjective(@NotNull WrappedSidebar sidebar, String name, boolean health, SidebarLine title, int type) { + return ((SidebarImpl)sidebar).createObjective(name, health ? IScoreboardCriteria.f : IScoreboardCriteria.b, title, type); + } + + @Override + public ScoreLine createScoreLine(WrappedSidebar sidebar, SidebarLine line, int score, String color) { + return ((SidebarImpl)sidebar).createScore(line, score, color); + } + + @Override + public void sendScore(@NotNull WrappedSidebar sidebar, String playerName, int score) { + if (sidebar.getHealthObjective() == null) return; + PacketPlayOutScoreboardScore packetPlayOutScoreboardScore = new PacketPlayOutScoreboardScore( + playerName, + sidebar.getHealthObjective().getName(), + score, + Optional.empty(), + Optional.empty() + ); + for (Player player : sidebar.getReceivers()) { + PlayerConnection playerConnection = ((CraftPlayer) player).getHandle().f; + playerConnection.b(packetPlayOutScoreboardScore); + } + } + + @Override + public VersionedTabGroup createPlayerTab(WrappedSidebar sidebar, String identifier, SidebarLine prefix, SidebarLine suffix, PlayerTab.PushingRule pushingRule, PlayerTab.NameTagVisibility nameTagVisibility, @Nullable Collection placeholders) { + return new PlayerListImpl(sidebar, identifier, prefix, suffix, pushingRule, nameTagVisibility, placeholders); + } + + @Override + public void sendHeaderFooter(Player player, String header, String footer) { + PacketPlayOutPlayerListHeaderFooter packet = new PacketPlayOutPlayerListHeaderFooter(IChatBaseComponent.b(header), IChatBaseComponent.b(footer)); + ((CraftPlayer)player).getHandle().f.b(packet); + } + + public static SidebarProvider getInstance() { + return null == instance ? instance = new ProviderImpl() : instance; + } +} diff --git a/sidebar-v1_21_R2/src/main/java/com/andrei1058/spigot/sidebar/v1_21_R2/SidebarImpl.java b/sidebar-v1_21_R2/src/main/java/com/andrei1058/spigot/sidebar/v1_21_R2/SidebarImpl.java new file mode 100644 index 0000000..f804701 --- /dev/null +++ b/sidebar-v1_21_R2/src/main/java/com/andrei1058/spigot/sidebar/v1_21_R2/SidebarImpl.java @@ -0,0 +1,362 @@ +package com.andrei1058.spigot.sidebar.v1_21_R2; + +import com.andrei1058.spigot.sidebar.*; +import net.md_5.bungee.api.ChatColor; +import net.minecraft.EnumChatFormat; +import net.minecraft.network.chat.IChatBaseComponent; +import net.minecraft.network.chat.IChatMutableComponent; +import net.minecraft.network.chat.numbers.FixedFormat; +import net.minecraft.network.protocol.game.*; +import net.minecraft.server.network.PlayerConnection; +import net.minecraft.world.scores.DisplaySlot; +import net.minecraft.world.scores.ScoreboardObjective; +import net.minecraft.world.scores.ScoreboardScore; +import net.minecraft.world.scores.ScoreboardTeam; +import net.minecraft.world.scores.criteria.IScoreboardCriteria; +import org.bukkit.craftbukkit.v1_21_R2.entity.CraftPlayer; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; +import java.util.Optional; + +@SuppressWarnings("unused") +public class SidebarImpl extends WrappedSidebar { + + public SidebarImpl(@NotNull SidebarLine title, @NotNull Collection lines, Collection placeholderProvider) { + super(title, lines, placeholderProvider); + } + + public ScoreLine createScore(SidebarLine line, int score, String color) { + return new SidebarImpl.ScoreLineImpl(line, score, color); + } + + public SidebarObjective createObjective(String name, IScoreboardCriteria iScoreboardCriteria, SidebarLine title, int type) { + return new SidebarObjectiveImpl(name, iScoreboardCriteria, title, type); + } + + protected class SidebarObjectiveImpl extends ScoreboardObjective implements SidebarObjective { + + private SidebarLine displayName; + private IChatMutableComponent displayNameComp = IChatBaseComponent.b(""); + private final DisplaySlot type; + + public SidebarObjectiveImpl(String name, IScoreboardCriteria criteria, SidebarLine displayName, int type) { + super(null, name, criteria, IChatBaseComponent.b(name), IScoreboardCriteria.EnumScoreboardHealthDisplay.a, false, null); + this.displayName = displayName; + this.type = DisplaySlot.values()[type]; + } + + @Override + public void setTitle(SidebarLine title) { + this.displayName = title; + } + + @Override + public SidebarLine getTitle() { + return displayName; + } + + @Override + public void sendCreate(Player player) { + this.sendCreate(((CraftPlayer) player).getHandle().f); + } + + @Override + public void sendRemove(Player player) { + this.sendRemove(((CraftPlayer) player).getHandle().f); + } + + @Override + public String getName() { + return super.b(); + } + + @Override + public boolean refreshTitle() { + var newTitle = displayName.getTrimReplacePlaceholders( + getReceivers().isEmpty() ? null : getReceivers().getFirst(), + 256, + getPlaceholders() + ); + + if (newTitle.equals(displayNameComp.getString())) { + return false; + } + this.displayNameComp = IChatBaseComponent.b(newTitle); + return true; + } + + @Override + public IChatBaseComponent d() { + return displayNameComp; + } + + @Override + public void a(IChatBaseComponent var0) { + } + + @Override + public IChatBaseComponent g() { + return IChatBaseComponent.b((this.d().toString())); + + } + + @Override + public void a(IScoreboardCriteria.EnumScoreboardHealthDisplay var0) { + } + + private void sendCreate(@NotNull PlayerConnection playerConnection) { + var packetPlayOutScoreboardObjective = new PacketPlayOutScoreboardObjective(this, 0); + playerConnection.b(packetPlayOutScoreboardObjective); + var packetPlayOutScoreboardDisplayObjective = new PacketPlayOutScoreboardDisplayObjective(type, this); + playerConnection.b(packetPlayOutScoreboardDisplayObjective); + + if (b().equalsIgnoreCase("health")) { + var packetPlayOutScoreboardDisplayObjective2 = new PacketPlayOutScoreboardDisplayObjective(DisplaySlot.a, this); + playerConnection.b(packetPlayOutScoreboardDisplayObjective2); + } + } + + // must be called when updating the name + public void sendUpdate() { + PacketPlayOutScoreboardObjective packetPlayOutScoreboardObjective = new PacketPlayOutScoreboardObjective(this, 2); + getReceivers().forEach(player -> ((CraftPlayer) player).getHandle().f.b(packetPlayOutScoreboardObjective)); + } + + public void sendRemove(@NotNull PlayerConnection playerConnection) { + PacketPlayOutScoreboardObjective packetPlayOutScoreboardObjective = new PacketPlayOutScoreboardObjective(this, 1); + playerConnection.b(packetPlayOutScoreboardObjective); + } + } + + + public class ScoreLineImpl extends ScoreboardScore implements ScoreLine, Comparable { + + private int score; + private IChatMutableComponent prefix = IChatBaseComponent.b(" "), suffix = IChatBaseComponent.b(" "); + private final TeamLine team; + private SidebarLine text; + private final String color; + + public ScoreLineImpl(@NotNull SidebarLine text, int score, @NotNull String color) { +// super(null, (ScoreboardObjective) getSidebarObjective(), color); + this.score = score; + this.text = text; + this.team = new TeamLine(color); + this.color = color; + } + + @Override + public void a(int score) { + this.score = score; + PacketPlayOutScoreboardScore packetPlayOutScoreboardScore = new PacketPlayOutScoreboardScore( + getColor(), + getSidebarObjective().getName(), + score, + Optional.empty(), + Optional.of(new FixedFormat(IChatBaseComponent.b(text.getTrimReplacePlaceholdersScore( + getReceivers().isEmpty() ? null : getReceivers().getFirst(), + null, + getPlaceholders() + )))) + ); + getReceivers().forEach(r -> ((CraftPlayer) r).getHandle().f.b(packetPlayOutScoreboardScore)); + } + + @Override + public SidebarLine getLine() { + return text; + } + + @Override + public void setLine(SidebarLine line) { + this.text = line; + } + + @Override + public int getScoreAmount() { + return score; + } + + @Override + public void setScoreAmount(int score) { + this.a(score); + } + + @Override + public void sendCreateToAllReceivers() { + PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeam = PacketPlayOutScoreboardTeam.a(team, true); + getReceivers().forEach(p -> ((CraftPlayer) p).getHandle().f.b(packetPlayOutScoreboardTeam)); + PacketPlayOutScoreboardScore packetPlayOutScoreboardScore = new PacketPlayOutScoreboardScore( + this.getColor(), + getSidebarObjective().getName(), + this.getScoreAmount(), + Optional.empty(), + Optional.of(new FixedFormat(IChatBaseComponent.b(text.getTrimReplacePlaceholdersScore( + getReceivers().isEmpty() ? null : getReceivers().getFirst(), + null, + getPlaceholders() + )))) + ); + getReceivers().forEach(p -> ((CraftPlayer) p).getHandle().f.b(packetPlayOutScoreboardScore)); + } + + @Override + public void sendCreate(Player player) { + PlayerConnection conn = ((CraftPlayer) player).getHandle().f; + PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeam = PacketPlayOutScoreboardTeam.a(team, true); + conn.b(packetPlayOutScoreboardTeam); + + PacketPlayOutScoreboardScore packetPlayOutScoreboardScore = new PacketPlayOutScoreboardScore( + this.getColor(), + getSidebarObjective().getName(), + this.getScoreAmount(), + Optional.empty(), + Optional.of(new FixedFormat(IChatBaseComponent.b(text.getTrimReplacePlaceholdersScore( + getReceivers().isEmpty() ? null : getReceivers().getFirst(), + null, + getPlaceholders() + )))) + ); + conn.b(packetPlayOutScoreboardScore); + } + + @Override + public void sendRemove(Player player) { + PlayerConnection conn = ((CraftPlayer) player).getHandle().f; + // var1=1 means remove + PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeam = PacketPlayOutScoreboardTeam.a(team); + var resetScore = new ClientboundResetScorePacket(team.b(), getSidebarObjective().getName()); + conn.b(resetScore); + conn.b(packetPlayOutScoreboardTeam); + } + + public void sendRemoveToAllReceivers() { + PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeam = PacketPlayOutScoreboardTeam.a(team); + var resetScore = new ClientboundResetScorePacket(team.b(), getSidebarObjective().getName()); + getReceivers().forEach(p -> ((CraftPlayer) p).getHandle().f.b(resetScore)); + getReceivers().forEach(p -> ((CraftPlayer) p).getHandle().f.b(packetPlayOutScoreboardTeam)); + } + + public void sendUpdate(Player player) { + // false=2 is for update packet, true=0 for create + PacketPlayOutScoreboardTeam packetTeamUpdate = PacketPlayOutScoreboardTeam.a(team, false); + ((CraftPlayer) player).getHandle().f.b(packetTeamUpdate); + } + + @Contract(pure = true) + public boolean setContent(@NotNull SidebarLine line) { + var oldPrefix = this.prefix; + var oldSuffix = this.suffix; + String content = line.getTrimReplacePlaceholders( + getReceivers().isEmpty() ? null : getReceivers().getFirst(), + null, + getPlaceholders() + ); + + if (content.length() > 256) { + this.prefix = IChatBaseComponent.b(content.substring(0, 256)); + if (this.prefix.getString().charAt(255) == ChatColor.COLOR_CHAR) { + this.prefix = IChatBaseComponent.b(content.substring(0, 255)); + setSuffix(content.substring(255)); + } else { + setSuffix(content.substring(256)); + } + } else { + this.prefix = IChatBaseComponent.b(content); + this.suffix = IChatBaseComponent.b(""); + } + return !oldPrefix.equals(this.prefix) || !oldSuffix.equals(this.suffix); + } + + public void setSuffix(@NotNull String secondPart) { + if (secondPart.isEmpty()) { + this.suffix = IChatBaseComponent.b(""); + return; + } + secondPart = org.bukkit.ChatColor.getLastColors(this.prefix.getString()) + secondPart; + this.suffix = IChatBaseComponent.b(secondPart.length() > 256 ? secondPart.substring(0, 256) : secondPart); + } + + public void sendUpdateToAllReceivers() { + // false=2 is for update packet, true=0 for create + PacketPlayOutScoreboardTeam packetTeamUpdate = PacketPlayOutScoreboardTeam.a(team, false); + getReceivers().forEach(r -> ((CraftPlayer) r).getHandle().f.b(packetTeamUpdate)); + } + + public int compareTo(@NotNull ScoreLine o) { + return Integer.compare(score, o.getScoreAmount()); + } + + @Override + public int a() { + return score; + } + + public String getColor() { + return color.charAt(0) == ChatColor.COLOR_CHAR ? color : ChatColor.COLOR_CHAR + color; + } + + @Override + public boolean refreshContent() { + return setContent(getLine()); + } + + private class TeamLine extends ScoreboardTeam { + + public TeamLine(String color) { + super(null, color); + g().add(color); + } + + @Contract(value = " -> new", pure = true) + @Override + public @NotNull IChatBaseComponent e() { + return prefix; + } + + @Override + public void b(@Nullable IChatBaseComponent var0) { + } + + @Override + public void c(@Nullable IChatBaseComponent var0) { + } + + @Contract(value = " -> new", pure = true) + @Override + public @NotNull IChatBaseComponent f() { + return suffix; + } + + @Override + public void a(boolean var0) { + } + + @Override + public void b(boolean var0) { + } + + @Override + public void a(EnumNameTagVisibility var0) { + } + + @Override + public void a(EnumTeamPush var0) { + } + + @Override + public void a(EnumChatFormat var0) { + } + + @Contract(value = "_ -> new", pure = true) + @Override + public @NotNull IChatMutableComponent d(IChatBaseComponent var0) { + return IChatBaseComponent.b(prefix.getString() + var0.getString() + suffix.getString()); + } + } + } +} diff --git a/sidebar-v1_21_R3/pom.xml b/sidebar-v1_21_R3/pom.xml new file mode 100644 index 0000000..31e6fdb --- /dev/null +++ b/sidebar-v1_21_R3/pom.xml @@ -0,0 +1,61 @@ + + + + sidebar-pom + com.andrei1058.spigot.sidebar + 25.2.2-SNAPSHOT + + 4.0.0 + + sidebar-v1_21_R3 + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 20 + 20 + + + + org.apache.maven.plugins + maven-javadoc-plugin + + true + + + + + + + + nms + https://repo.codemc.io/repository/nms/ + + + + + + com.andrei1058.spigot.sidebar + sidebar-base + ${project.version} + provided + + + org.spigotmc + spigot + 1.21.4-R0.1-SNAPSHOT + provided + + + com.andrei1058.spigot.sidebar + sidebar-cmn1 + ${project.version} + compile + + + \ No newline at end of file diff --git a/sidebar-v1_21_R3/src/main/java/com/andrei1058/spigot/sidebar/v1_21_R3/PlayerListImpl.java b/sidebar-v1_21_R3/src/main/java/com/andrei1058/spigot/sidebar/v1_21_R3/PlayerListImpl.java new file mode 100644 index 0000000..96b7e3f --- /dev/null +++ b/sidebar-v1_21_R3/src/main/java/com/andrei1058/spigot/sidebar/v1_21_R3/PlayerListImpl.java @@ -0,0 +1,177 @@ +package com.andrei1058.spigot.sidebar.v1_21_R3; + +import com.andrei1058.spigot.sidebar.*; +import dev.andrei1058.spigot.sidebar.cmn1.PlayerListImplCmn1; +import net.minecraft.network.chat.IChatBaseComponent; +import net.minecraft.network.chat.IChatMutableComponent; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.PacketPlayOutScoreboardTeam; +import net.minecraft.world.scores.ScoreboardTeam; +import org.bukkit.craftbukkit.v1_21_R3.entity.CraftPlayer; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Collection; + +@SuppressWarnings("unused") +public class PlayerListImpl extends ScoreboardTeam implements VersionedTabGroup { + + private static PacketPlayOutScoreboardTeam.a cachedScoreboardActionA; + private static PacketPlayOutScoreboardTeam.a cachedScoreboardActionB; + + private final PlayerListImplCmn1 handle; + + public PlayerListImpl( + @NotNull WrappedSidebar sidebar, + String identifier, + SidebarLine prefix, + SidebarLine suffix, + PlayerTab.PushingRule pushingRule, + PlayerTab.NameTagVisibility nameTagVisibility, + @Nullable Collection placeholders + ) { + super(null, identifier); + handle = new PlayerListImplCmn1( + sidebar, + identifier, + prefix, + suffix, + pushingRule, + nameTagVisibility, + placeholders + ); + + if (null == cachedScoreboardActionA) { + cachedScoreboardActionA = (PacketPlayOutScoreboardTeam.a) getScoreboardAction("ADD"); + if (null == cachedScoreboardActionA){ + cachedScoreboardActionA = (PacketPlayOutScoreboardTeam.a) getScoreboardAction("a"); + } + } + if (null == cachedScoreboardActionB) { + cachedScoreboardActionB = (PacketPlayOutScoreboardTeam.a) getScoreboardAction("REMOVE"); + if (null == cachedScoreboardActionB) { + cachedScoreboardActionB = (PacketPlayOutScoreboardTeam.a) getScoreboardAction("b"); + } + } + } + + @Override + public void sendCreateToPlayer(Player player) { + sendPacket(player, PacketPlayOutScoreboardTeam.a(this, true)); + } + + @Override + public void sendUserCreateToReceivers(@NotNull Player player) { + // send 3: add entities to team + PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeam = PacketPlayOutScoreboardTeam.a( + this, player.getName(), cachedScoreboardActionA); + handle.getSidebar().getReceivers().forEach( + r -> sendPacket(r, packetPlayOutScoreboardTeam) + ); + } + + @Override + public void sendUpdateToReceivers() { + PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeam = PacketPlayOutScoreboardTeam.a(this, false); + handle.getSidebar().getReceivers().forEach(r -> sendPacket(r, packetPlayOutScoreboardTeam)); + } + + @Override + public void sendRemoveToReceivers() { + PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeam = PacketPlayOutScoreboardTeam.a(this); + handle.getSidebar().getReceivers().forEach(r -> sendPacket(r, packetPlayOutScoreboardTeam)); + } + + @Override + public boolean refreshContent() { + return handle.refreshContent(); + } + + private void sendPacket(Player player, Packet packet) { + ((CraftPlayer) player).getHandle().f.b(packet); + } + + @Override + public void add(@NotNull Player player) { + PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeam = PacketPlayOutScoreboardTeam.a( + this, player.getName(), cachedScoreboardActionA + ); + handle.getSidebar().getReceivers().forEach(r -> sendPacket(r, packetPlayOutScoreboardTeam)); + } + + @Override + public void remove(@NotNull Player player) { + // send 4: remove entities from team + PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeam = PacketPlayOutScoreboardTeam.a( + this, player.getName(), cachedScoreboardActionB + ); + handle.getSidebar().getReceivers().forEach(r -> sendPacket(r, packetPlayOutScoreboardTeam)); + } + + @Override + public void setSubject(@Nullable Player player) { + this.handle.setPapiSubject(player); + } + + @Override + public @Nullable Player getSubject() { + return this.handle.getPapiSubject(); + } + + @Override + public void setPushingRule(@NotNull PushingRule rule) { + this.handle.setPushingRule(this.handle.toNmsPushing(rule)); + if (null != this.handle.getId()) { + sendUpdateToReceivers(); + } + } + + @Override + public void setNameTagVisibility(@NotNull NameTagVisibility nameTagVisibility) { + this.handle.setNameTagVisibility(this.handle.toNmsTagVisibility(nameTagVisibility)); + if (null != this.handle.getId()){ + sendUpdateToReceivers(); + } + } + + @Override + public String getIdentifier() { + return handle.getId(); + } + + private static Object getScoreboardAction(String action) { + try { + Class cls = Class.forName("net.minecraft.network.protocol.game.PacketPlayOutScoreboardTeam$a"); + for (Object obj : cls.getEnumConstants()) { + try { + Method m = cls.getMethod("name"); + String name = (String) m.invoke(obj); + if (action.equals(name)) { + return obj; + } + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) { + } + } + } catch (Exception ignored) { + } + throw new RuntimeException("Something went wrong... please report this to SidebarLib by andrei1058"); + } + + public @NotNull IChatBaseComponent e() { + return handle.getPrefixComp(); + } + + public @NotNull IChatBaseComponent f() { + return handle.getSuffixComp(); + } + + @Contract(value = "_ -> new", pure = true) + @Override + public @NotNull IChatMutableComponent d(IChatBaseComponent var0) { + return IChatBaseComponent.b(handle.getPrefixComp().toString() + var0.getString() + handle.getSuffixComp().toString()); + } +} diff --git a/sidebar-v1_21_R3/src/main/java/com/andrei1058/spigot/sidebar/v1_21_R3/ProviderImpl.java b/sidebar-v1_21_R3/src/main/java/com/andrei1058/spigot/sidebar/v1_21_R3/ProviderImpl.java new file mode 100644 index 0000000..2e3766e --- /dev/null +++ b/sidebar-v1_21_R3/src/main/java/com/andrei1058/spigot/sidebar/v1_21_R3/ProviderImpl.java @@ -0,0 +1,66 @@ +package com.andrei1058.spigot.sidebar.v1_21_R3; + +import com.andrei1058.spigot.sidebar.*; +import net.minecraft.network.chat.IChatBaseComponent; +import net.minecraft.network.protocol.game.PacketPlayOutPlayerListHeaderFooter; +import net.minecraft.network.protocol.game.PacketPlayOutScoreboardScore; +import net.minecraft.server.network.PlayerConnection; +import net.minecraft.world.scores.criteria.IScoreboardCriteria; +import org.bukkit.craftbukkit.v1_21_R3.entity.CraftPlayer; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; +import java.util.Optional; + +@SuppressWarnings("unused") +public class ProviderImpl extends SidebarProvider { + private static SidebarProvider instance; + + @Override + public Sidebar createSidebar(SidebarLine title, Collection lines, Collection placeholderProviders) { + return new SidebarImpl(title, lines, placeholderProviders); + } + + @Override + public SidebarObjective createObjective(@NotNull WrappedSidebar sidebar, String name, boolean health, SidebarLine title, int type) { + return ((SidebarImpl)sidebar).createObjective(name, health ? IScoreboardCriteria.f : IScoreboardCriteria.b, title, type); + } + + @Override + public ScoreLine createScoreLine(WrappedSidebar sidebar, SidebarLine line, int score, String color) { + return ((SidebarImpl)sidebar).createScore(line, score, color); + } + + @Override + public void sendScore(@NotNull WrappedSidebar sidebar, String playerName, int score) { + if (sidebar.getHealthObjective() == null) return; + PacketPlayOutScoreboardScore packetPlayOutScoreboardScore = new PacketPlayOutScoreboardScore( + playerName, + sidebar.getHealthObjective().getName(), + score, + Optional.empty(), + Optional.empty() + ); + for (Player player : sidebar.getReceivers()) { + PlayerConnection playerConnection = ((CraftPlayer) player).getHandle().f; + playerConnection.b(packetPlayOutScoreboardScore); + } + } + + @Override + public VersionedTabGroup createPlayerTab(WrappedSidebar sidebar, String identifier, SidebarLine prefix, SidebarLine suffix, PlayerTab.PushingRule pushingRule, PlayerTab.NameTagVisibility nameTagVisibility, @Nullable Collection placeholders) { + return new PlayerListImpl(sidebar, identifier, prefix, suffix, pushingRule, nameTagVisibility, placeholders); + } + + @Override + public void sendHeaderFooter(Player player, String header, String footer) { + PacketPlayOutPlayerListHeaderFooter packet = new PacketPlayOutPlayerListHeaderFooter(IChatBaseComponent.b(header), IChatBaseComponent.b(footer)); + ((CraftPlayer)player).getHandle().f.b(packet); + } + + public static SidebarProvider getInstance() { + return null == instance ? instance = new ProviderImpl() : instance; + } +} diff --git a/sidebar-v1_21_R3/src/main/java/com/andrei1058/spigot/sidebar/v1_21_R3/SidebarImpl.java b/sidebar-v1_21_R3/src/main/java/com/andrei1058/spigot/sidebar/v1_21_R3/SidebarImpl.java new file mode 100644 index 0000000..cd88882 --- /dev/null +++ b/sidebar-v1_21_R3/src/main/java/com/andrei1058/spigot/sidebar/v1_21_R3/SidebarImpl.java @@ -0,0 +1,362 @@ +package com.andrei1058.spigot.sidebar.v1_21_R3; + +import com.andrei1058.spigot.sidebar.*; +import net.md_5.bungee.api.ChatColor; +import net.minecraft.EnumChatFormat; +import net.minecraft.network.chat.IChatBaseComponent; +import net.minecraft.network.chat.IChatMutableComponent; +import net.minecraft.network.chat.numbers.FixedFormat; +import net.minecraft.network.protocol.game.*; +import net.minecraft.server.network.PlayerConnection; +import net.minecraft.world.scores.DisplaySlot; +import net.minecraft.world.scores.ScoreboardObjective; +import net.minecraft.world.scores.ScoreboardScore; +import net.minecraft.world.scores.ScoreboardTeam; +import net.minecraft.world.scores.criteria.IScoreboardCriteria; +import org.bukkit.craftbukkit.v1_21_R3.entity.CraftPlayer; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; +import java.util.Optional; + +@SuppressWarnings("unused") +public class SidebarImpl extends WrappedSidebar { + + public SidebarImpl(@NotNull SidebarLine title, @NotNull Collection lines, Collection placeholderProvider) { + super(title, lines, placeholderProvider); + } + + public ScoreLine createScore(SidebarLine line, int score, String color) { + return new SidebarImpl.ScoreLineImpl(line, score, color); + } + + public SidebarObjective createObjective(String name, IScoreboardCriteria iScoreboardCriteria, SidebarLine title, int type) { + return new SidebarObjectiveImpl(name, iScoreboardCriteria, title, type); + } + + protected class SidebarObjectiveImpl extends ScoreboardObjective implements SidebarObjective { + + private SidebarLine displayName; + private IChatMutableComponent displayNameComp = IChatBaseComponent.b(""); + private final DisplaySlot type; + + public SidebarObjectiveImpl(String name, IScoreboardCriteria criteria, SidebarLine displayName, int type) { + super(null, name, criteria, IChatBaseComponent.b(name), IScoreboardCriteria.EnumScoreboardHealthDisplay.a, false, null); + this.displayName = displayName; + this.type = DisplaySlot.values()[type]; + } + + @Override + public void setTitle(SidebarLine title) { + this.displayName = title; + } + + @Override + public SidebarLine getTitle() { + return displayName; + } + + @Override + public void sendCreate(Player player) { + this.sendCreate(((CraftPlayer) player).getHandle().f); + } + + @Override + public void sendRemove(Player player) { + this.sendRemove(((CraftPlayer) player).getHandle().f); + } + + @Override + public String getName() { + return super.b(); + } + + @Override + public boolean refreshTitle() { + var newTitle = displayName.getTrimReplacePlaceholders( + getReceivers().isEmpty() ? null : getReceivers().getFirst(), + 256, + getPlaceholders() + ); + + if (newTitle.equals(displayNameComp.getString())) { + return false; + } + this.displayNameComp = IChatBaseComponent.b(newTitle); + return true; + } + + @Override + public IChatBaseComponent d() { + return displayNameComp; + } + + @Override + public void a(IChatBaseComponent var0) { + } + + @Override + public IChatBaseComponent g() { + return IChatBaseComponent.b((this.d().toString())); + + } + + @Override + public void a(IScoreboardCriteria.EnumScoreboardHealthDisplay var0) { + } + + private void sendCreate(@NotNull PlayerConnection playerConnection) { + var packetPlayOutScoreboardObjective = new PacketPlayOutScoreboardObjective(this, 0); + playerConnection.b(packetPlayOutScoreboardObjective); + var packetPlayOutScoreboardDisplayObjective = new PacketPlayOutScoreboardDisplayObjective(type, this); + playerConnection.b(packetPlayOutScoreboardDisplayObjective); + + if (b().equalsIgnoreCase("health")) { + var packetPlayOutScoreboardDisplayObjective2 = new PacketPlayOutScoreboardDisplayObjective(DisplaySlot.a, this); + playerConnection.b(packetPlayOutScoreboardDisplayObjective2); + } + } + + // must be called when updating the name + public void sendUpdate() { + PacketPlayOutScoreboardObjective packetPlayOutScoreboardObjective = new PacketPlayOutScoreboardObjective(this, 2); + getReceivers().forEach(player -> ((CraftPlayer) player).getHandle().f.b(packetPlayOutScoreboardObjective)); + } + + public void sendRemove(@NotNull PlayerConnection playerConnection) { + PacketPlayOutScoreboardObjective packetPlayOutScoreboardObjective = new PacketPlayOutScoreboardObjective(this, 1); + playerConnection.b(packetPlayOutScoreboardObjective); + } + } + + + public class ScoreLineImpl extends ScoreboardScore implements ScoreLine, Comparable { + + private int score; + private IChatMutableComponent prefix = IChatBaseComponent.b(" "), suffix = IChatBaseComponent.b(" "); + private final TeamLine team; + private SidebarLine text; + private final String color; + + public ScoreLineImpl(@NotNull SidebarLine text, int score, @NotNull String color) { +// super(null, (ScoreboardObjective) getSidebarObjective(), color); + this.score = score; + this.text = text; + this.team = new TeamLine(color); + this.color = color; + } + + @Override + public void a(int score) { + this.score = score; + PacketPlayOutScoreboardScore packetPlayOutScoreboardScore = new PacketPlayOutScoreboardScore( + getColor(), + getSidebarObjective().getName(), + score, + Optional.empty(), + Optional.of(new FixedFormat(IChatBaseComponent.b(text.getTrimReplacePlaceholdersScore( + getReceivers().isEmpty() ? null : getReceivers().getFirst(), + null, + getPlaceholders() + )))) + ); + getReceivers().forEach(r -> ((CraftPlayer) r).getHandle().f.b(packetPlayOutScoreboardScore)); + } + + @Override + public SidebarLine getLine() { + return text; + } + + @Override + public void setLine(SidebarLine line) { + this.text = line; + } + + @Override + public int getScoreAmount() { + return score; + } + + @Override + public void setScoreAmount(int score) { + this.a(score); + } + + @Override + public void sendCreateToAllReceivers() { + PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeam = PacketPlayOutScoreboardTeam.a(team, true); + getReceivers().forEach(p -> ((CraftPlayer) p).getHandle().f.b(packetPlayOutScoreboardTeam)); + PacketPlayOutScoreboardScore packetPlayOutScoreboardScore = new PacketPlayOutScoreboardScore( + this.getColor(), + getSidebarObjective().getName(), + this.getScoreAmount(), + Optional.empty(), + Optional.of(new FixedFormat(IChatBaseComponent.b(text.getTrimReplacePlaceholdersScore( + getReceivers().isEmpty() ? null : getReceivers().getFirst(), + null, + getPlaceholders() + )))) + ); + getReceivers().forEach(p -> ((CraftPlayer) p).getHandle().f.b(packetPlayOutScoreboardScore)); + } + + @Override + public void sendCreate(Player player) { + PlayerConnection conn = ((CraftPlayer) player).getHandle().f; + PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeam = PacketPlayOutScoreboardTeam.a(team, true); + conn.b(packetPlayOutScoreboardTeam); + + PacketPlayOutScoreboardScore packetPlayOutScoreboardScore = new PacketPlayOutScoreboardScore( + this.getColor(), + getSidebarObjective().getName(), + this.getScoreAmount(), + Optional.empty(), + Optional.of(new FixedFormat(IChatBaseComponent.b(text.getTrimReplacePlaceholdersScore( + getReceivers().isEmpty() ? null : getReceivers().getFirst(), + null, + getPlaceholders() + )))) + ); + conn.b(packetPlayOutScoreboardScore); + } + + @Override + public void sendRemove(Player player) { + PlayerConnection conn = ((CraftPlayer) player).getHandle().f; + // var1=1 means remove + PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeam = PacketPlayOutScoreboardTeam.a(team); + var resetScore = new ClientboundResetScorePacket(team.b(), getSidebarObjective().getName()); + conn.b(resetScore); + conn.b(packetPlayOutScoreboardTeam); + } + + public void sendRemoveToAllReceivers() { + PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeam = PacketPlayOutScoreboardTeam.a(team); + var resetScore = new ClientboundResetScorePacket(team.b(), getSidebarObjective().getName()); + getReceivers().forEach(p -> ((CraftPlayer) p).getHandle().f.b(resetScore)); + getReceivers().forEach(p -> ((CraftPlayer) p).getHandle().f.b(packetPlayOutScoreboardTeam)); + } + + public void sendUpdate(Player player) { + // false=2 is for update packet, true=0 for create + PacketPlayOutScoreboardTeam packetTeamUpdate = PacketPlayOutScoreboardTeam.a(team, false); + ((CraftPlayer) player).getHandle().f.b(packetTeamUpdate); + } + + @Contract(pure = true) + public boolean setContent(@NotNull SidebarLine line) { + var oldPrefix = this.prefix; + var oldSuffix = this.suffix; + String content = line.getTrimReplacePlaceholders( + getReceivers().isEmpty() ? null : getReceivers().getFirst(), + null, + getPlaceholders() + ); + + if (content.length() > 256) { + this.prefix = IChatBaseComponent.b(content.substring(0, 256)); + if (this.prefix.getString().charAt(255) == ChatColor.COLOR_CHAR) { + this.prefix = IChatBaseComponent.b(content.substring(0, 255)); + setSuffix(content.substring(255)); + } else { + setSuffix(content.substring(256)); + } + } else { + this.prefix = IChatBaseComponent.b(content); + this.suffix = IChatBaseComponent.b(""); + } + return !oldPrefix.equals(this.prefix) || !oldSuffix.equals(this.suffix); + } + + public void setSuffix(@NotNull String secondPart) { + if (secondPart.isEmpty()) { + this.suffix = IChatBaseComponent.b(""); + return; + } + secondPart = org.bukkit.ChatColor.getLastColors(this.prefix.getString()) + secondPart; + this.suffix = IChatBaseComponent.b(secondPart.length() > 256 ? secondPart.substring(0, 256) : secondPart); + } + + public void sendUpdateToAllReceivers() { + // false=2 is for update packet, true=0 for create + PacketPlayOutScoreboardTeam packetTeamUpdate = PacketPlayOutScoreboardTeam.a(team, false); + getReceivers().forEach(r -> ((CraftPlayer) r).getHandle().f.b(packetTeamUpdate)); + } + + public int compareTo(@NotNull ScoreLine o) { + return Integer.compare(score, o.getScoreAmount()); + } + + @Override + public int a() { + return score; + } + + public String getColor() { + return color.charAt(0) == ChatColor.COLOR_CHAR ? color : ChatColor.COLOR_CHAR + color; + } + + @Override + public boolean refreshContent() { + return setContent(getLine()); + } + + private class TeamLine extends ScoreboardTeam { + + public TeamLine(String color) { + super(null, color); + g().add(color); + } + + @Contract(value = " -> new", pure = true) + @Override + public @NotNull IChatBaseComponent e() { + return prefix; + } + + @Override + public void b(@Nullable IChatBaseComponent var0) { + } + + @Override + public void c(@Nullable IChatBaseComponent var0) { + } + + @Contract(value = " -> new", pure = true) + @Override + public @NotNull IChatBaseComponent f() { + return suffix; + } + + @Override + public void a(boolean var0) { + } + + @Override + public void b(boolean var0) { + } + + @Override + public void a(EnumNameTagVisibility var0) { + } + + @Override + public void a(EnumTeamPush var0) { + } + + @Override + public void a(EnumChatFormat var0) { + } + + @Contract(value = "_ -> new", pure = true) + @Override + public @NotNull IChatMutableComponent d(IChatBaseComponent var0) { + return IChatBaseComponent.b(prefix.getString() + var0.getString() + suffix.getString()); + } + } + } +} diff --git a/sidebar-v1_8_R3/pom.xml b/sidebar-v1_8_R3/pom.xml index 2b73d21..5a74fbe 100644 --- a/sidebar-v1_8_R3/pom.xml +++ b/sidebar-v1_8_R3/pom.xml @@ -5,7 +5,7 @@ sidebar-pom com.andrei1058.spigot.sidebar - 25.2.1-SNAPSHOT + 25.2.2-SNAPSHOT 4.0.0