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