diff --git a/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/platform/BukkitPlatform.java b/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/platform/BukkitPlatform.java
index 84f0814bc..328f31612 100644
--- a/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/platform/BukkitPlatform.java
+++ b/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/platform/BukkitPlatform.java
@@ -293,6 +293,11 @@ public TabList createTabList(@NotNull TabPlayer player) {
return TabListBase.getInstance().apply((BukkitTabPlayer) player);
}
+ @Override
+ public boolean supportsNumberFormat() {
+ return serverVersion.getNetworkId() >= ProtocolVersion.V1_20_3.getNetworkId();
+ }
+
@Override
public boolean supportsListOrder() {
return serverVersion.getNetworkId() >= ProtocolVersion.V1_21_2.getNetworkId();
diff --git a/bungeecord/src/main/java/me/neznamy/tab/platforms/bungeecord/BungeePlatform.java b/bungeecord/src/main/java/me/neznamy/tab/platforms/bungeecord/BungeePlatform.java
index 9b6214022..ca85351c1 100644
--- a/bungeecord/src/main/java/me/neznamy/tab/platforms/bungeecord/BungeePlatform.java
+++ b/bungeecord/src/main/java/me/neznamy/tab/platforms/bungeecord/BungeePlatform.java
@@ -195,6 +195,11 @@ public TabList createTabList(@NotNull TabPlayer player) {
}
}
+ @Override
+ public boolean supportsNumberFormat() {
+ return true;
+ }
+
@Override
public boolean supportsListOrder() {
return true;
diff --git a/fabric/src/main/java/me/neznamy/tab/platforms/fabric/FabricPlatform.java b/fabric/src/main/java/me/neznamy/tab/platforms/fabric/FabricPlatform.java
index 769032501..3a0cd5550 100644
--- a/fabric/src/main/java/me/neznamy/tab/platforms/fabric/FabricPlatform.java
+++ b/fabric/src/main/java/me/neznamy/tab/platforms/fabric/FabricPlatform.java
@@ -165,6 +165,11 @@ public TabList createTabList(@NotNull TabPlayer player) {
return new FabricTabList((FabricTabPlayer) player);
}
+ @Override
+ public boolean supportsNumberFormat() {
+ return serverVersion.getNetworkId() >= ProtocolVersion.V1_20_3.getNetworkId();
+ }
+
@Override
public boolean supportsListOrder() {
return serverVersion.getNetworkId() >= ProtocolVersion.V1_21_2.getNetworkId();
diff --git a/shared/src/main/java/me/neznamy/tab/shared/features/scoreboard/ScoreboardConfiguration.java b/shared/src/main/java/me/neznamy/tab/shared/features/scoreboard/ScoreboardConfiguration.java
index 27d400d04..3b8d1d128 100644
--- a/shared/src/main/java/me/neznamy/tab/shared/features/scoreboard/ScoreboardConfiguration.java
+++ b/shared/src/main/java/me/neznamy/tab/shared/features/scoreboard/ScoreboardConfiguration.java
@@ -2,6 +2,7 @@
import lombok.Getter;
import lombok.RequiredArgsConstructor;
+import me.neznamy.tab.shared.TAB;
import me.neznamy.tab.shared.config.file.ConfigurationSection;
import me.neznamy.tab.shared.features.PlaceholderManagerImpl;
import org.jetbrains.annotations.NotNull;
@@ -120,6 +121,19 @@ public static ScoreboardDefinition fromSection(@NotNull String name, @NotNull Co
name, lines.size(), alwaysVisibleLines));
}
+ // Check if using NumberFormat on <1.20.3 server
+ boolean found = false;
+ for (String line : lines) {
+ if (line.contains("||")) {
+ found = true;
+ break;
+ }
+ }
+ if (found && !TAB.getInstance().getPlatform().supportsNumberFormat()) {
+ section.startupWarn("Scoreboard \"" + name + "\" is using right-side text alignment (using ||) in the lines, however, your server does not " +
+ "support this feature. It was added into the game in version 1.20.3. Any text defined after || in lines will not be displayed.");
+ }
+
return new ScoreboardDefinition(
section.getString("display-condition"),
section.getString("title", "
"),
diff --git a/shared/src/main/java/me/neznamy/tab/shared/features/scoreboard/ScoreboardImpl.java b/shared/src/main/java/me/neznamy/tab/shared/features/scoreboard/ScoreboardImpl.java
index 67283dd59..f6f4a6ea0 100644
--- a/shared/src/main/java/me/neznamy/tab/shared/features/scoreboard/ScoreboardImpl.java
+++ b/shared/src/main/java/me/neznamy/tab/shared/features/scoreboard/ScoreboardImpl.java
@@ -4,6 +4,7 @@
import lombok.NonNull;
import me.neznamy.tab.api.scoreboard.Line;
import me.neznamy.tab.shared.Property;
+import me.neznamy.tab.shared.ProtocolVersion;
import me.neznamy.tab.shared.TAB;
import me.neznamy.tab.shared.TabConstants;
import me.neznamy.tab.shared.chat.SimpleComponent;
@@ -43,6 +44,8 @@ public class ScoreboardImpl extends RefreshableFeature implements me.neznamy.tab
//lines of scoreboard
private final List lines = new ArrayList<>();
+ private boolean containsNumberFormat;
+
//players currently seeing this scoreboard
private final Set players = Collections.newSetFromMap(new WeakHashMap<>());
@@ -83,6 +86,7 @@ public ScoreboardImpl(@NonNull ScoreboardManagerImpl manager, @NonNull String na
for (int i = 0; i< definition.getLines().size(); i++) {
String line = definition.getLines().get(i);
if (line == null) line = "";
+ if (line.contains("||")) containsNumberFormat = true;
ScoreboardLine score;
if (dynamicLinesOnly) {
score = new StableDynamicLine(this, i+1, line);
@@ -149,6 +153,11 @@ public void addPlayer(@NonNull TabPlayer p) {
p.scoreboardData.activeScoreboard = this;
recalculateScores(p);
TAB.getInstance().getPlaceholderManager().getTabExpansion().setScoreboardName(p, name);
+ if (containsNumberFormat && p.getVersion().getNetworkId() < ProtocolVersion.V1_20_3.getNetworkId()) {
+ TAB.getInstance().getConfigHelper().runtime().error("Scoreboard \"" + name + "\" contains right-side text alignment (using ||), however, this feature " +
+ "was added in 1.20.3, but player \"" + p.getName() + "\" is using version " + p.getVersion().getFriendlyName() + ". Right-side text " +
+ "will not be visible for them.");
+ }
}
/**
diff --git a/shared/src/main/java/me/neznamy/tab/shared/platform/Platform.java b/shared/src/main/java/me/neznamy/tab/shared/platform/Platform.java
index ed12a52d9..095f3c3dc 100644
--- a/shared/src/main/java/me/neznamy/tab/shared/platform/Platform.java
+++ b/shared/src/main/java/me/neznamy/tab/shared/platform/Platform.java
@@ -173,6 +173,14 @@ public interface Platform {
@NotNull
TabList createTabList(@NotNull TabPlayer player);
+ /**
+ * Returns {@code true} if server is able to use {@code NumberFormat} scoreboard feature (1.20.3+). Returns {@code false}
+ * if server is running below this version (backend) or server API does not support it yet.
+ *
+ * @return {@code true} if server is able to use {@code NumberFormat} scoreboard feature, {@code false} if not
+ */
+ boolean supportsNumberFormat();
+
/**
* Returns {@code true} if server is able to use {@code listOrder} field in tablist (1.21.2+). Returns {@code false}
* if server is running below this version (backend) or server API does not support it yet.
diff --git a/sponge7/src/main/java/me/neznamy/tab/platforms/sponge7/SpongePlatform.java b/sponge7/src/main/java/me/neznamy/tab/platforms/sponge7/SpongePlatform.java
index 32fb0d92d..3f3b0f0b8 100644
--- a/sponge7/src/main/java/me/neznamy/tab/platforms/sponge7/SpongePlatform.java
+++ b/sponge7/src/main/java/me/neznamy/tab/platforms/sponge7/SpongePlatform.java
@@ -136,6 +136,11 @@ public TabList createTabList(@NotNull TabPlayer player) {
return new SpongeTabList((SpongeTabPlayer) player);
}
+ @Override
+ public boolean supportsNumberFormat() {
+ return false; // Sponge 7 only goes up to 1.12.2
+ }
+
@Override
public boolean supportsListOrder() {
return false; // Sponge 7 only goes up to 1.12.2
diff --git a/sponge8/src/main/java/me/neznamy/tab/platforms/sponge8/SpongePlatform.java b/sponge8/src/main/java/me/neznamy/tab/platforms/sponge8/SpongePlatform.java
index 1902b4e6a..b50cf7fb2 100644
--- a/sponge8/src/main/java/me/neznamy/tab/platforms/sponge8/SpongePlatform.java
+++ b/sponge8/src/main/java/me/neznamy/tab/platforms/sponge8/SpongePlatform.java
@@ -135,6 +135,11 @@ public TabList createTabList(@NotNull TabPlayer player) {
return new SpongeTabList((SpongeTabPlayer) player);
}
+ @Override
+ public boolean supportsNumberFormat() {
+ return false; // TODO implement it
+ }
+
@Override
public boolean supportsListOrder() {
return false; // TODO when they add API
diff --git a/velocity/src/main/java/me/neznamy/tab/platforms/velocity/VelocityPlatform.java b/velocity/src/main/java/me/neznamy/tab/platforms/velocity/VelocityPlatform.java
index b4fbfccda..35feaea6a 100644
--- a/velocity/src/main/java/me/neznamy/tab/platforms/velocity/VelocityPlatform.java
+++ b/velocity/src/main/java/me/neznamy/tab/platforms/velocity/VelocityPlatform.java
@@ -179,6 +179,11 @@ public TabList createTabList(@NotNull TabPlayer player) {
return new VelocityTabList((VelocityTabPlayer) player);
}
+ @Override
+ public boolean supportsNumberFormat() {
+ return true;
+ }
+
@Override
public boolean supportsListOrder() {
return false; // TODO when they add API