From e29fb0de21a19589bd700b4cec320871926fdd19 Mon Sep 17 00:00:00 2001 From: Dominilk01 <108392199+Dominilk01@users.noreply.github.com> Date: Sun, 28 Jun 2026 22:50:54 +0200 Subject: [PATCH 01/10] Update score handling for version 1.20.4 and above --- .../fr/mrmicky/fastboard/FastBoardBase.java | 39 ++++++++++++++----- .../fastboard/adventure/FastBoard.java | 6 ++- 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/src/main/java/fr/mrmicky/fastboard/FastBoardBase.java b/src/main/java/fr/mrmicky/fastboard/FastBoardBase.java index e2b215d..046111b 100644 --- a/src/main/java/fr/mrmicky/fastboard/FastBoardBase.java +++ b/src/main/java/fr/mrmicky/fastboard/FastBoardBase.java @@ -85,7 +85,9 @@ public abstract class FastBoardBase { try { MethodHandles.Lookup lookup = MethodHandles.lookup(); - if (FastReflection.isRepackaged()) { + if (FastReflection.optionalClass("org.bukkit.damage.DamageSource").isPresent()) { + VERSION_TYPE = VersionType.V1_20_4; + } else if (FastReflection.isRepackaged()) { VERSION_TYPE = VersionType.V1_17; } else if (FastReflection.nmsOptionalClass(null, "ScoreboardServer$Action").isPresent() || FastReflection.nmsOptionalClass(null, "ServerScoreboard$Method").isPresent()) { @@ -167,7 +169,9 @@ public abstract class FastBoardBase { packetSbSetScore = lookup.findConstructor(packetSbScoreClass, scoreType); OBJECTIVE = lookup.unreflectConstructor(objectiveClass.getConstructor(scoreboardClass, String.class, objectiveCriteriaClass, CHAT_COMPONENT_CLASS, objectiveRenderTypeClass)); PACKET_SB_OBJ = lookup.unreflectConstructor(packetSbObjClass.getConstructor(objectiveClass, int.class)); - PACKET_SB_DISPLAY_OBJ = lookup.unreflectConstructor(packetSbDisplayObjClass.getConstructor(int.class, objectiveClass)); + PACKET_SB_DISPLAY_OBJ = displaySlotEnum.isPresent() + ? lookup.unreflectConstructor(packetSbDisplayObjClass.getConstructor(displaySlotEnum.get(), objectiveClass)) + : lookup.unreflectConstructor(packetSbDisplayObjClass.getConstructor(int.class, objectiveClass)); } else { packetSbSetScore = lookup.findConstructor(packetSbScoreClass, MethodType.methodType(void.class)); if (VersionType.V1_13.isHigherOrEqual()) { @@ -449,14 +453,18 @@ public synchronized void updateLines(Collection lines, Collection scores) if (oldLines.size() > linesSize) { for (int i = oldLinesCopy.size(); i > linesSize; i--) { - sendTeamPacket(i - 1, TeamMode.REMOVE); + if (!VersionType.V1_20_4.isHigherOrEqual()) { + sendTeamPacket(i - 1, TeamMode.REMOVE); + } sendScorePacket(i - 1, ScoreboardAction.REMOVE); oldLines.remove(0); } } else { for (int i = oldLinesCopy.size(); i < linesSize; i++) { sendScorePacket(i, ScoreboardAction.CHANGE); - sendTeamPacket(i, TeamMode.CREATE, null, null); + if (!VersionType.V1_20_4.isHigherOrEqual()) { + sendTeamPacket(i, TeamMode.CREATE, null, null); + } } } } @@ -609,7 +617,11 @@ public synchronized void delete() { try { for (int i = 0; i < this.lines.size(); i++) { - sendTeamPacket(i, TeamMode.REMOVE); + if (VersionType.V1_20_4.isHigherOrEqual()) { + sendScorePacket(i, ScoreboardAction.REMOVE); + } else { + sendTeamPacket(i, TeamMode.REMOVE); + } } sendObjectivePacket(ObjectiveMode.REMOVE); @@ -666,6 +678,14 @@ protected Object sendObjectivePacket(ObjectiveMode mode) throws Throwable { false, // Auto-update, unused null // Number format ); + } else if (VersionType.V1_20_4.isHigherOrEqual()) { + objective = OBJECTIVE.invoke( + null, // Scoreboard, unused + this.id, // Objective name + null, // Criteria, unused + toMinecraftComponent(this.title), // Display name + ENUM_SB_HEALTH_DISPLAY_INTEGER // Render type + ); } else if (VersionType.V1_17.isHigherOrEqual()) { objective = OBJECTIVE.invoke( null, // Scoreboard, unused @@ -745,13 +765,14 @@ private void sendModernScorePacket(int score, ScoreboardAction action) throws Th return; } + T text = getLineByScore(score); T scoreFormat = getLineByScore(this.scores, score); Object format = scoreFormat != null ? FIXED_NUMBER_FORMAT.invoke(toMinecraftComponent(scoreFormat)) : BLANK_NUMBER_FORMAT; Object scorePacket = SCORE_OPTIONAL_COMPONENTS - ? PACKET_SB_SET_SCORE.invoke(objName, this.id, score, Optional.empty(), Optional.of(format)) - : PACKET_SB_SET_SCORE.invoke(objName, this.id, score, null, format); + ? PACKET_SB_SET_SCORE.invoke(objName, this.id, score, Optional.of(toMinecraftComponent(text)), Optional.of(format)) + : PACKET_SB_SET_SCORE.invoke(objName, this.id, score, toMinecraftComponent(text), format); sendPacket(scorePacket); } @@ -866,8 +887,8 @@ public enum ScoreboardAction { CHANGE, REMOVE } - enum VersionType { - V1_7, V1_8, V1_13, V1_17; + public enum VersionType { + V1_7, V1_8, V1_13, V1_17, V1_20_4; public boolean isHigherOrEqual() { return VERSION_TYPE.ordinal() >= ordinal(); diff --git a/src/main/java/fr/mrmicky/fastboard/adventure/FastBoard.java b/src/main/java/fr/mrmicky/fastboard/adventure/FastBoard.java index 77b3b12..e2b6570 100644 --- a/src/main/java/fr/mrmicky/fastboard/adventure/FastBoard.java +++ b/src/main/java/fr/mrmicky/fastboard/adventure/FastBoard.java @@ -83,7 +83,11 @@ public FastBoard(Player player) { protected void sendLineChange(int score) throws Throwable { Component line = getLineByScore(score); - sendTeamPacket(score, FastBoardBase.TeamMode.UPDATE, line, null); + if (VersionType.V1_20_4.isHigherOrEqual()) { + sendScorePacket(score, ScoreboardAction.CHANGE); + } else { + sendTeamPacket(score, TeamMode.UPDATE, line, null); + } } @Override From 358106e76df9e82c981377ff3bc8ee09e2d689f3 Mon Sep 17 00:00:00 2001 From: Dominilk01 <108392199+Dominilk01@users.noreply.github.com> Date: Sun, 28 Jun 2026 22:56:48 +0200 Subject: [PATCH 02/10] pom --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 0b4ef14..3f8909f 100644 --- a/pom.xml +++ b/pom.xml @@ -52,13 +52,13 @@ net.kyori adventure-api - 5.1.1 + 5.2.0 provided net.kyori adventure-text-serializer-legacy - 5.1.1 + 5.2.0 provided From dcf5920b28b3b3c7ce8429f472d498aa4a741431 Mon Sep 17 00:00:00 2001 From: Dominilk01 <108392199+Dominilk01@users.noreply.github.com> Date: Mon, 29 Jun 2026 00:43:05 +0200 Subject: [PATCH 03/10] Added support for string version Removed unnecessary code --- .../java/fr/mrmicky/fastboard/FastBoard.java | 6 +++++- .../java/fr/mrmicky/fastboard/FastBoardBase.java | 16 ---------------- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/src/main/java/fr/mrmicky/fastboard/FastBoard.java b/src/main/java/fr/mrmicky/fastboard/FastBoard.java index 53b9b04..cc67aae 100644 --- a/src/main/java/fr/mrmicky/fastboard/FastBoard.java +++ b/src/main/java/fr/mrmicky/fastboard/FastBoard.java @@ -130,7 +130,11 @@ protected void sendLineChange(int score) throws Throwable { suffix = suffix.substring(0, Math.min(maxLength, suffix.length())); } - sendTeamPacket(score, TeamMode.UPDATE, prefix, suffix); + if (VersionType.V1_20_4.isHigherOrEqual()) { + sendScorePacket(score, ScoreboardAction.CHANGE); + } else { + sendTeamPacket(score, TeamMode.UPDATE, prefix, suffix); + } } @Override diff --git a/src/main/java/fr/mrmicky/fastboard/FastBoardBase.java b/src/main/java/fr/mrmicky/fastboard/FastBoardBase.java index 046111b..f1a3836 100644 --- a/src/main/java/fr/mrmicky/fastboard/FastBoardBase.java +++ b/src/main/java/fr/mrmicky/fastboard/FastBoardBase.java @@ -678,22 +678,6 @@ protected Object sendObjectivePacket(ObjectiveMode mode) throws Throwable { false, // Auto-update, unused null // Number format ); - } else if (VersionType.V1_20_4.isHigherOrEqual()) { - objective = OBJECTIVE.invoke( - null, // Scoreboard, unused - this.id, // Objective name - null, // Criteria, unused - toMinecraftComponent(this.title), // Display name - ENUM_SB_HEALTH_DISPLAY_INTEGER // Render type - ); - } else if (VersionType.V1_17.isHigherOrEqual()) { - objective = OBJECTIVE.invoke( - null, // Scoreboard, unused - this.id, // Objective name - null, // Criteria, unused - toMinecraftComponent(this.title), // Display name - ENUM_SB_HEALTH_DISPLAY_INTEGER // Render type - ); } else if (VersionType.V1_13.isHigherOrEqual()) { objective = OBJECTIVE.invoke( null, // Scoreboard, unused From 66b408837b42637f607b2cc7b7348e4994bccaef Mon Sep 17 00:00:00 2001 From: Dominilk01 <108392199+Dominilk01@users.noreply.github.com> Date: Mon, 29 Jun 2026 00:43:05 +0200 Subject: [PATCH 04/10] Added support for string version Removed unnecessary code Simplify ternary --- .../java/fr/mrmicky/fastboard/FastBoard.java | 6 +++++- .../fr/mrmicky/fastboard/FastBoardBase.java | 20 +------------------ 2 files changed, 6 insertions(+), 20 deletions(-) diff --git a/src/main/java/fr/mrmicky/fastboard/FastBoard.java b/src/main/java/fr/mrmicky/fastboard/FastBoard.java index 53b9b04..cc67aae 100644 --- a/src/main/java/fr/mrmicky/fastboard/FastBoard.java +++ b/src/main/java/fr/mrmicky/fastboard/FastBoard.java @@ -130,7 +130,11 @@ protected void sendLineChange(int score) throws Throwable { suffix = suffix.substring(0, Math.min(maxLength, suffix.length())); } - sendTeamPacket(score, TeamMode.UPDATE, prefix, suffix); + if (VersionType.V1_20_4.isHigherOrEqual()) { + sendScorePacket(score, ScoreboardAction.CHANGE); + } else { + sendTeamPacket(score, TeamMode.UPDATE, prefix, suffix); + } } @Override diff --git a/src/main/java/fr/mrmicky/fastboard/FastBoardBase.java b/src/main/java/fr/mrmicky/fastboard/FastBoardBase.java index 046111b..1ee4caa 100644 --- a/src/main/java/fr/mrmicky/fastboard/FastBoardBase.java +++ b/src/main/java/fr/mrmicky/fastboard/FastBoardBase.java @@ -169,9 +169,7 @@ public abstract class FastBoardBase { packetSbSetScore = lookup.findConstructor(packetSbScoreClass, scoreType); OBJECTIVE = lookup.unreflectConstructor(objectiveClass.getConstructor(scoreboardClass, String.class, objectiveCriteriaClass, CHAT_COMPONENT_CLASS, objectiveRenderTypeClass)); PACKET_SB_OBJ = lookup.unreflectConstructor(packetSbObjClass.getConstructor(objectiveClass, int.class)); - PACKET_SB_DISPLAY_OBJ = displaySlotEnum.isPresent() - ? lookup.unreflectConstructor(packetSbDisplayObjClass.getConstructor(displaySlotEnum.get(), objectiveClass)) - : lookup.unreflectConstructor(packetSbDisplayObjClass.getConstructor(int.class, objectiveClass)); + PACKET_SB_DISPLAY_OBJ = lookup.unreflectConstructor(packetSbDisplayObjClass.getConstructor(displaySlotEnum.orElse(int.class), objectiveClass)); } else { packetSbSetScore = lookup.findConstructor(packetSbScoreClass, MethodType.methodType(void.class)); if (VersionType.V1_13.isHigherOrEqual()) { @@ -678,22 +676,6 @@ protected Object sendObjectivePacket(ObjectiveMode mode) throws Throwable { false, // Auto-update, unused null // Number format ); - } else if (VersionType.V1_20_4.isHigherOrEqual()) { - objective = OBJECTIVE.invoke( - null, // Scoreboard, unused - this.id, // Objective name - null, // Criteria, unused - toMinecraftComponent(this.title), // Display name - ENUM_SB_HEALTH_DISPLAY_INTEGER // Render type - ); - } else if (VersionType.V1_17.isHigherOrEqual()) { - objective = OBJECTIVE.invoke( - null, // Scoreboard, unused - this.id, // Objective name - null, // Criteria, unused - toMinecraftComponent(this.title), // Display name - ENUM_SB_HEALTH_DISPLAY_INTEGER // Render type - ); } else if (VersionType.V1_13.isHigherOrEqual()) { objective = OBJECTIVE.invoke( null, // Scoreboard, unused From 205734f5f09276d08d8c4fc07f659587095fd673 Mon Sep 17 00:00:00 2001 From: MrMicky Date: Mon, 29 Jun 2026 19:42:08 -0400 Subject: [PATCH 05/10] Use 1.20.3 instead of 1.20.4 - Scoreboard changes were introduced in 1.20.3, which was immediately replaced by 1.20.4 - Better naming before making VersionType public --- .../java/fr/mrmicky/fastboard/FastBoard.java | 8 ++-- .../fr/mrmicky/fastboard/FastBoardBase.java | 48 +++++++++---------- .../fastboard/adventure/FastBoard.java | 2 +- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/main/java/fr/mrmicky/fastboard/FastBoard.java b/src/main/java/fr/mrmicky/fastboard/FastBoard.java index cc67aae..37a5d0f 100644 --- a/src/main/java/fr/mrmicky/fastboard/FastBoard.java +++ b/src/main/java/fr/mrmicky/fastboard/FastBoard.java @@ -66,7 +66,7 @@ public FastBoard(Player player) { public void updateTitle(String title) { Objects.requireNonNull(title, "title"); - if (!VersionType.V1_13.isHigherOrEqual() && title.length() > 32) { + if (!VersionType.V1_13.isCurrentAtLeast() && title.length() > 32) { throw new IllegalArgumentException("Title is longer than 32 chars"); } @@ -82,7 +82,7 @@ public void updateTitle(String title) { public void updateLines(String... lines) { Objects.requireNonNull(lines, "lines"); - if (!VersionType.V1_13.isHigherOrEqual()) { + if (!VersionType.V1_13.isCurrentAtLeast()) { int lineCount = 0; for (String s : lines) { if (s != null && s.length() > 30) { @@ -130,7 +130,7 @@ protected void sendLineChange(int score) throws Throwable { suffix = suffix.substring(0, Math.min(maxLength, suffix.length())); } - if (VersionType.V1_20_4.isHigherOrEqual()) { + if (VersionType.V1_20_3.isCurrentAtLeast()) { sendScorePacket(score, ScoreboardAction.CHANGE); } else { sendTeamPacket(score, TeamMode.UPDATE, prefix, suffix); @@ -164,6 +164,6 @@ protected String emptyLine() { * @return true if scoreboard lines are limited by the legacy prefix/suffix length */ protected boolean hasLinesMaxLength() { - return !VersionType.V1_13.isHigherOrEqual(); + return !VersionType.V1_13.isCurrentAtLeast(); } } diff --git a/src/main/java/fr/mrmicky/fastboard/FastBoardBase.java b/src/main/java/fr/mrmicky/fastboard/FastBoardBase.java index 1ee4caa..2f8ebec 100644 --- a/src/main/java/fr/mrmicky/fastboard/FastBoardBase.java +++ b/src/main/java/fr/mrmicky/fastboard/FastBoardBase.java @@ -85,8 +85,8 @@ public abstract class FastBoardBase { try { MethodHandles.Lookup lookup = MethodHandles.lookup(); - if (FastReflection.optionalClass("org.bukkit.damage.DamageSource").isPresent()) { - VERSION_TYPE = VersionType.V1_20_4; + if (FastReflection.nmsOptionalClass("network.chat.numbers", "NumberFormat").isPresent()) { + VERSION_TYPE = VersionType.V1_20_3; } else if (FastReflection.isRepackaged()) { VERSION_TYPE = VersionType.V1_17; } else if (FastReflection.nmsOptionalClass(null, "ScoreboardServer$Action").isPresent() @@ -108,7 +108,7 @@ public abstract class FastBoardBase { Class packetSbDisplayObjClass = FastReflection.nmsClass(gameProtocolPackage, "PacketPlayOutScoreboardDisplayObjective", "ClientboundSetDisplayObjectivePacket"); Class packetSbScoreClass = FastReflection.nmsClass(gameProtocolPackage, "PacketPlayOutScoreboardScore", "ClientboundSetScorePacket"); Class packetSbTeamClass = FastReflection.nmsClass(gameProtocolPackage, "PacketPlayOutScoreboardTeam", "ClientboundSetPlayerTeamPacket"); - Class sbTeamClass = VersionType.V1_17.isHigherOrEqual() + Class sbTeamClass = VersionType.V1_17.isCurrentAtLeast() ? FastReflection.innerClass(packetSbTeamClass, innerClass -> !innerClass.isEnum()) : null; Field playerConnectionField = Arrays.stream(entityPlayerClass.getFields()) .filter(field -> field.getType().isAssignableFrom(playerConnectionClass)) @@ -135,22 +135,22 @@ public abstract class FastBoardBase { Class objectiveRenderTypeClass = FastReflection.nmsOptionalClass("world.scores.criteria", "IScoreboardCriteria$EnumScoreboardHealthDisplay", "ObjectiveCriteria$RenderType").orElse(null); - Optional> numberFormat = FastReflection.nmsOptionalClass("network.chat.numbers", "NumberFormat"); MethodHandle packetSbSetScore; MethodHandle packetSbResetScore = null; MethodHandle fixedFormatConstructor = null; Object blankNumberFormat = null; boolean scoreOptionalComponents = false; - if (numberFormat.isPresent()) { // 1.20.3 - OBJECTIVE = lookup.unreflectConstructor(objectiveClass.getConstructor(scoreboardClass, String.class, objectiveCriteriaClass, CHAT_COMPONENT_CLASS, objectiveRenderTypeClass, boolean.class, numberFormat.get())); + if (VersionType.V1_20_3.isCurrentAtLeast()) { + Class numberFormatClass = FastReflection.nmsClass("network.chat.numbers", "NumberFormat"); + OBJECTIVE = lookup.unreflectConstructor(objectiveClass.getConstructor(scoreboardClass, String.class, objectiveCriteriaClass, CHAT_COMPONENT_CLASS, objectiveRenderTypeClass, boolean.class, numberFormatClass)); PACKET_SB_OBJ = lookup.unreflectConstructor(packetSbObjClass.getConstructor(objectiveClass, int.class)); PACKET_SB_DISPLAY_OBJ = lookup.unreflectConstructor(packetSbDisplayObjClass.getConstructor(DISPLAY_SLOT_TYPE, objectiveClass)); Class blankFormatClass = FastReflection.nmsClass("network.chat.numbers", "BlankFormat"); Class fixedFormatClass = FastReflection.nmsClass("network.chat.numbers", "FixedFormat"); Class resetScoreClass = FastReflection.nmsClass(gameProtocolPackage, "ClientboundResetScorePacket"); - MethodType scoreType = MethodType.methodType(void.class, String.class, String.class, int.class, CHAT_COMPONENT_CLASS, numberFormat.get()); + MethodType scoreType = MethodType.methodType(void.class, String.class, String.class, int.class, CHAT_COMPONENT_CLASS, numberFormatClass); MethodType scoreTypeOptional = MethodType.methodType(void.class, String.class, String.class, int.class, Optional.class, Optional.class); MethodType removeScoreType = MethodType.methodType(void.class, String.class, String.class); MethodType fixedFormatType = MethodType.methodType(void.class, CHAT_COMPONENT_CLASS); @@ -163,7 +163,7 @@ public abstract class FastBoardBase { scoreOptionalComponents = optionalScorePacket.isPresent(); packetSbResetScore = lookup.findConstructor(resetScoreClass, removeScoreType); blankNumberFormat = blankField.isPresent() ? blankField.get().get(null) : null; - } else if (VersionType.V1_17.isHigherOrEqual()) { + } else if (VersionType.V1_17.isCurrentAtLeast()) { Class enumSbAction = FastReflection.nmsClass("server", "ScoreboardServer$Action", "ServerScoreboard$Method"); MethodType scoreType = MethodType.methodType(void.class, enumSbAction, String.class, String.class, int.class); packetSbSetScore = lookup.findConstructor(packetSbScoreClass, scoreType); @@ -172,7 +172,7 @@ public abstract class FastBoardBase { PACKET_SB_DISPLAY_OBJ = lookup.unreflectConstructor(packetSbDisplayObjClass.getConstructor(displaySlotEnum.orElse(int.class), objectiveClass)); } else { packetSbSetScore = lookup.findConstructor(packetSbScoreClass, MethodType.methodType(void.class)); - if (VersionType.V1_13.isHigherOrEqual()) { + if (VersionType.V1_13.isCurrentAtLeast()) { OBJECTIVE = lookup.unreflectConstructor(objectiveClass.getConstructor(scoreboardClass, String.class, objectiveCriteriaClass, CHAT_COMPONENT_CLASS, objectiveRenderTypeClass)); } else { OBJECTIVE = lookup.unreflectConstructor(objectiveClass.getConstructor(scoreboardClass, String.class, objectiveCriteriaClass)); @@ -204,8 +204,8 @@ public abstract class FastBoardBase { PACKETS.put(clazz, fields); } - if (VersionType.V1_8.isHigherOrEqual()) { - String enumSbActionClass = VersionType.V1_13.isHigherOrEqual() + if (VersionType.V1_8.isCurrentAtLeast()) { + String enumSbActionClass = VersionType.V1_13.isCurrentAtLeast() ? "ScoreboardServer$Action" : "PacketPlayOutScoreboardScore$EnumScoreboardAction"; ENUM_SB_HEALTH_DISPLAY = FastReflection.nmsClass("world.scores.criteria", "IScoreboardCriteria$EnumScoreboardHealthDisplay", "ObjectiveCriteria$RenderType"); @@ -220,7 +220,7 @@ public abstract class FastBoardBase { ENUM_SB_ACTION_CHANGE = null; ENUM_SB_ACTION_REMOVE = null; } - if (VersionType.V1_13.isHigherOrEqual()) { + if (VersionType.V1_13.isCurrentAtLeast()) { DUMMY_SCOREBOARD_CRITERIA = null; } else { DUMMY_SCOREBOARD_CRITERIA = FastReflection.nmsClass("world.scores.criteria", "ScoreboardBaseCriteria").getConstructor(String.class).newInstance("dummy"); @@ -451,7 +451,7 @@ public synchronized void updateLines(Collection lines, Collection scores) if (oldLines.size() > linesSize) { for (int i = oldLinesCopy.size(); i > linesSize; i--) { - if (!VersionType.V1_20_4.isHigherOrEqual()) { + if (!VersionType.V1_20_3.isCurrentAtLeast()) { sendTeamPacket(i - 1, TeamMode.REMOVE); } sendScorePacket(i - 1, ScoreboardAction.REMOVE); @@ -460,7 +460,7 @@ public synchronized void updateLines(Collection lines, Collection scores) } else { for (int i = oldLinesCopy.size(); i < linesSize; i++) { sendScorePacket(i, ScoreboardAction.CHANGE); - if (!VersionType.V1_20_4.isHigherOrEqual()) { + if (!VersionType.V1_20_3.isCurrentAtLeast()) { sendTeamPacket(i, TeamMode.CREATE, null, null); } } @@ -592,7 +592,7 @@ public boolean isDeleted() { * @return true if the server supports custom scores */ public boolean customScoresSupported() { - return BLANK_NUMBER_FORMAT != null; + return VersionType.V1_20_3.isCurrentAtLeast(); } /** @@ -615,7 +615,7 @@ public synchronized void delete() { try { for (int i = 0; i < this.lines.size(); i++) { - if (VersionType.V1_20_4.isHigherOrEqual()) { + if (VersionType.V1_20_3.isCurrentAtLeast()) { sendScorePacket(i, ScoreboardAction.REMOVE); } else { sendTeamPacket(i, TeamMode.REMOVE); @@ -676,7 +676,7 @@ protected Object sendObjectivePacket(ObjectiveMode mode) throws Throwable { false, // Auto-update, unused null // Number format ); - } else if (VersionType.V1_13.isHigherOrEqual()) { + } else if (VersionType.V1_13.isCurrentAtLeast()) { objective = OBJECTIVE.invoke( null, // Scoreboard, unused this.id, // Objective name @@ -707,7 +707,7 @@ protected void sendDisplayObjectivePacket(Object objective) throws Throwable { } protected void sendScorePacket(int score, ScoreboardAction action) throws Throwable { - if (VersionType.V1_17.isHigherOrEqual()) { + if (VersionType.V1_17.isCurrentAtLeast()) { sendModernScorePacket(score, action); return; } @@ -716,7 +716,7 @@ protected void sendScorePacket(int score, ScoreboardAction action) throws Throwa setField(packet, String.class, COLOR_CODES[score], 0); // Player Name - if (VersionType.V1_8.isHigherOrEqual()) { + if (VersionType.V1_8.isCurrentAtLeast()) { Object enumAction = action == ScoreboardAction.REMOVE ? ENUM_SB_ACTION_REMOVE : ENUM_SB_ACTION_CHANGE; setField(packet, ENUM_SB_ACTION, enumAction); @@ -771,7 +771,7 @@ protected void sendTeamPacket(int score, TeamMode mode, T prefix, T suffix) Object packet; if (mode == TeamMode.REMOVE) { - if (VersionType.V1_17.isHigherOrEqual()) { + if (VersionType.V1_17.isCurrentAtLeast()) { packet = PACKET_SB_TEAM.invoke( this.id + ':' + score, // Team name mode.ordinal(), // Update mode @@ -787,7 +787,7 @@ protected void sendTeamPacket(int score, TeamMode mode, T prefix, T suffix) return; } - if (VersionType.V1_17.isHigherOrEqual()) { + if (VersionType.V1_17.isCurrentAtLeast()) { Object team = PLAYER_TEAM.invoke(null, this.id + ':' + score); setComponentField(team, null, 1); // Display name setComponentField(team, prefix, 2); // Prefix @@ -843,7 +843,7 @@ private void setField(Object packet, Class fieldType, Object value, int count } private void setComponentField(Object packet, T value, int count) throws Throwable { - if (!VersionType.V1_13.isHigherOrEqual()) { + if (!VersionType.V1_13.isCurrentAtLeast()) { String line = value != null ? serializeLine(value) : ""; setField(packet, String.class, line, count); return; @@ -870,9 +870,9 @@ public enum ScoreboardAction { } public enum VersionType { - V1_7, V1_8, V1_13, V1_17, V1_20_4; + V1_7, V1_8, V1_13, V1_17, V1_20_3; - public boolean isHigherOrEqual() { + public boolean isCurrentAtLeast() { return VERSION_TYPE.ordinal() >= ordinal(); } } diff --git a/src/main/java/fr/mrmicky/fastboard/adventure/FastBoard.java b/src/main/java/fr/mrmicky/fastboard/adventure/FastBoard.java index e2b6570..3d9160c 100644 --- a/src/main/java/fr/mrmicky/fastboard/adventure/FastBoard.java +++ b/src/main/java/fr/mrmicky/fastboard/adventure/FastBoard.java @@ -83,7 +83,7 @@ public FastBoard(Player player) { protected void sendLineChange(int score) throws Throwable { Component line = getLineByScore(score); - if (VersionType.V1_20_4.isHigherOrEqual()) { + if (VersionType.V1_20_3.isCurrentAtLeast()) { sendScorePacket(score, ScoreboardAction.CHANGE); } else { sendTeamPacket(score, TeamMode.UPDATE, line, null); From 3ed22fe53e7d9d5d6097ea6a9d2008784e3cfbfb Mon Sep 17 00:00:00 2001 From: Dominilk01 <108392199+Dominilk01@users.noreply.github.com> Date: Wed, 1 Jul 2026 04:03:40 +0200 Subject: [PATCH 06/10] Removed loading of team packets for new version --- .../java/fr/mrmicky/fastboard/FastBoard.java | 6 +- .../fr/mrmicky/fastboard/FastBoardBase.java | 115 ++++++++++-------- .../fastboard/adventure/FastBoard.java | 7 +- 3 files changed, 69 insertions(+), 59 deletions(-) diff --git a/src/main/java/fr/mrmicky/fastboard/FastBoard.java b/src/main/java/fr/mrmicky/fastboard/FastBoard.java index 37a5d0f..5cc67f0 100644 --- a/src/main/java/fr/mrmicky/fastboard/FastBoard.java +++ b/src/main/java/fr/mrmicky/fastboard/FastBoard.java @@ -95,6 +95,9 @@ public void updateLines(String... lines) { super.updateLines(lines); } + /** + * {@inheritDoc} + */ @Override protected void sendLineChange(int score) throws Throwable { int maxLength = hasLinesMaxLength() ? 16 : 1024; @@ -131,8 +134,9 @@ protected void sendLineChange(int score) throws Throwable { } if (VersionType.V1_20_3.isCurrentAtLeast()) { - sendScorePacket(score, ScoreboardAction.CHANGE); + sendModernScorePacket(score, ScoreboardAction.CHANGE); } else { + sendScorePacket(score, ScoreboardAction.CHANGE); sendTeamPacket(score, TeamMode.UPDATE, prefix, suffix); } } diff --git a/src/main/java/fr/mrmicky/fastboard/FastBoardBase.java b/src/main/java/fr/mrmicky/fastboard/FastBoardBase.java index 2f8ebec..307b44a 100644 --- a/src/main/java/fr/mrmicky/fastboard/FastBoardBase.java +++ b/src/main/java/fr/mrmicky/fastboard/FastBoardBase.java @@ -107,7 +107,8 @@ public abstract class FastBoardBase { Class packetSbObjClass = FastReflection.nmsClass(gameProtocolPackage, "PacketPlayOutScoreboardObjective", "ClientboundSetObjectivePacket"); Class packetSbDisplayObjClass = FastReflection.nmsClass(gameProtocolPackage, "PacketPlayOutScoreboardDisplayObjective", "ClientboundSetDisplayObjectivePacket"); Class packetSbScoreClass = FastReflection.nmsClass(gameProtocolPackage, "PacketPlayOutScoreboardScore", "ClientboundSetScorePacket"); - Class packetSbTeamClass = FastReflection.nmsClass(gameProtocolPackage, "PacketPlayOutScoreboardTeam", "ClientboundSetPlayerTeamPacket"); + Class packetSbTeamClass = VersionType.V1_20_3.isCurrentAtLeast() + ? null : FastReflection.nmsClass(gameProtocolPackage, "PacketPlayOutScoreboardTeam", "ClientboundSetPlayerTeamPacket"); Class sbTeamClass = VersionType.V1_17.isCurrentAtLeast() ? FastReflection.innerClass(packetSbTeamClass, innerClass -> !innerClass.isEnum()) : null; Field playerConnectionField = Arrays.stream(entityPlayerClass.getFields()) @@ -128,16 +129,19 @@ public abstract class FastBoardBase { SEND_PACKET = lookup.unreflect(sendPacketMethod); Class scoreboardClass = FastReflection.nmsClass("world.scores", "Scoreboard"); - Class playerTeamClass = FastReflection.nmsClass("world.scores", "ScoreboardTeam", "PlayerTeam"); + Class playerTeamClass = VersionType.V1_20_3.isCurrentAtLeast() ? + null : FastReflection.nmsClass("world.scores", "ScoreboardTeam", "PlayerTeam"); Class objectiveClass = FastReflection.nmsClass("world.scores", "ScoreboardObjective", "Objective"); Class objectiveCriteriaClass = FastReflection.nmsClass("world.scores.criteria", "IScoreboardCriteria", "ObjectiveCriteria"); - PLAYER_TEAM = lookup.unreflectConstructor(playerTeamClass.getConstructor(scoreboardClass, String.class)); Class objectiveRenderTypeClass = FastReflection.nmsOptionalClass("world.scores.criteria", "IScoreboardCriteria$EnumScoreboardHealthDisplay", "ObjectiveCriteria$RenderType").orElse(null); MethodHandle packetSbSetScore; MethodHandle packetSbResetScore = null; MethodHandle fixedFormatConstructor = null; + MethodHandle packetSbSerializableTeam = null; + MethodHandle packetSbTeam = null; + MethodHandle playerTeam = null; Object blankNumberFormat = null; boolean scoreOptionalComponents = false; @@ -163,46 +167,53 @@ public abstract class FastBoardBase { scoreOptionalComponents = optionalScorePacket.isPresent(); packetSbResetScore = lookup.findConstructor(resetScoreClass, removeScoreType); blankNumberFormat = blankField.isPresent() ? blankField.get().get(null) : null; - } else if (VersionType.V1_17.isCurrentAtLeast()) { - Class enumSbAction = FastReflection.nmsClass("server", "ScoreboardServer$Action", "ServerScoreboard$Method"); - MethodType scoreType = MethodType.methodType(void.class, enumSbAction, String.class, String.class, int.class); - packetSbSetScore = lookup.findConstructor(packetSbScoreClass, scoreType); - OBJECTIVE = lookup.unreflectConstructor(objectiveClass.getConstructor(scoreboardClass, String.class, objectiveCriteriaClass, CHAT_COMPONENT_CLASS, objectiveRenderTypeClass)); - PACKET_SB_OBJ = lookup.unreflectConstructor(packetSbObjClass.getConstructor(objectiveClass, int.class)); - PACKET_SB_DISPLAY_OBJ = lookup.unreflectConstructor(packetSbDisplayObjClass.getConstructor(displaySlotEnum.orElse(int.class), objectiveClass)); } else { - packetSbSetScore = lookup.findConstructor(packetSbScoreClass, MethodType.methodType(void.class)); - if (VersionType.V1_13.isCurrentAtLeast()) { + Constructor packetSbTeamConstructor = sbTeamClass != null ? packetSbTeamClass.getDeclaredConstructor(String.class, int.class, Optional.class, Collection.class) : packetSbTeamClass.getDeclaredConstructor(); + packetSbTeamConstructor.setAccessible(true); + packetSbTeam = lookup.unreflectConstructor(packetSbTeamConstructor); + packetSbSerializableTeam = sbTeamClass != null ? lookup.unreflectConstructor(sbTeamClass.getConstructor(playerTeamClass)) : null; + + playerTeam = lookup.unreflectConstructor(playerTeamClass.getConstructor(scoreboardClass, String.class)); + if (VersionType.V1_17.isCurrentAtLeast()) { + Class enumSbAction = FastReflection.nmsClass("server", "ScoreboardServer$Action", "ServerScoreboard$Method"); + MethodType scoreType = MethodType.methodType(void.class, enumSbAction, String.class, String.class, int.class); + packetSbSetScore = lookup.findConstructor(packetSbScoreClass, scoreType); OBJECTIVE = lookup.unreflectConstructor(objectiveClass.getConstructor(scoreboardClass, String.class, objectiveCriteriaClass, CHAT_COMPONENT_CLASS, objectiveRenderTypeClass)); + PACKET_SB_OBJ = lookup.unreflectConstructor(packetSbObjClass.getConstructor(objectiveClass, int.class)); + PACKET_SB_DISPLAY_OBJ = lookup.unreflectConstructor(packetSbDisplayObjClass.getConstructor(displaySlotEnum.orElse(int.class), objectiveClass)); } else { - OBJECTIVE = lookup.unreflectConstructor(objectiveClass.getConstructor(scoreboardClass, String.class, objectiveCriteriaClass)); + packetSbSetScore = lookup.findConstructor(packetSbScoreClass, MethodType.methodType(void.class)); + if (VersionType.V1_13.isCurrentAtLeast()) { + OBJECTIVE = lookup.unreflectConstructor(objectiveClass.getConstructor(scoreboardClass, String.class, objectiveCriteriaClass, CHAT_COMPONENT_CLASS, objectiveRenderTypeClass)); + } else { + OBJECTIVE = lookup.unreflectConstructor(objectiveClass.getConstructor(scoreboardClass, String.class, objectiveCriteriaClass)); + } + PACKET_SB_OBJ = lookup.unreflectConstructor(packetSbObjClass.getConstructor(objectiveClass, int.class)); + PACKET_SB_DISPLAY_OBJ = lookup.unreflectConstructor(packetSbDisplayObjClass.getConstructor(int.class, objectiveClass)); + } + + for (Class clazz : Arrays.asList(packetSbScoreClass, packetSbTeamClass, sbTeamClass, playerTeamClass, objectiveClass)) { + if (clazz == null) { + continue; + } + Field[] fields = Arrays.stream(clazz.getDeclaredFields()) + .filter(field -> !Modifier.isStatic(field.getModifiers())) + .toArray(Field[]::new); + for (Field field : fields) { + field.setAccessible(true); + } + PACKETS.put(clazz, fields); } - PACKET_SB_OBJ = lookup.unreflectConstructor(packetSbObjClass.getConstructor(objectiveClass, int.class)); - PACKET_SB_DISPLAY_OBJ = lookup.unreflectConstructor(packetSbDisplayObjClass.getConstructor(int.class, objectiveClass)); } PACKET_SB_SET_SCORE = packetSbSetScore; PACKET_SB_RESET_SCORE = packetSbResetScore; - Constructor packetSbTeamConstructor = sbTeamClass != null ? packetSbTeamClass.getDeclaredConstructor(String.class, int.class, Optional.class, Collection.class) : packetSbTeamClass.getDeclaredConstructor(); - packetSbTeamConstructor.setAccessible(true); - PACKET_SB_TEAM = lookup.unreflectConstructor(packetSbTeamConstructor); - PACKET_SB_SERIALIZABLE_TEAM = sbTeamClass != null ? lookup.unreflectConstructor(sbTeamClass.getConstructor(playerTeamClass)) : null; + PACKET_SB_TEAM = packetSbTeam; + PACKET_SB_SERIALIZABLE_TEAM = packetSbSerializableTeam; FIXED_NUMBER_FORMAT = fixedFormatConstructor; BLANK_NUMBER_FORMAT = blankNumberFormat; SCORE_OPTIONAL_COMPONENTS = scoreOptionalComponents; - - for (Class clazz : Arrays.asList(packetSbScoreClass, packetSbTeamClass, sbTeamClass, playerTeamClass, objectiveClass)) { - if (clazz == null) { - continue; - } - Field[] fields = Arrays.stream(clazz.getDeclaredFields()) - .filter(field -> !Modifier.isStatic(field.getModifiers())) - .toArray(Field[]::new); - for (Field field : fields) { - field.setAccessible(true); - } - PACKETS.put(clazz, fields); - } + PLAYER_TEAM = playerTeam; if (VersionType.V1_8.isCurrentAtLeast()) { String enumSbActionClass = VersionType.V1_13.isCurrentAtLeast() @@ -350,8 +361,8 @@ public synchronized void updateLine(int line, T score, T scoreText) { sendLineChange(getScoreByLine(line)); - if (customScoresSupported()) { - sendScorePacket(getScoreByLine(line), ScoreboardAction.CHANGE); + if (VersionType.V1_20_3.isCurrentAtLeast()) { + sendModernScorePacket(getScoreByLine(line), ScoreboardAction.CHANGE); } return; @@ -495,8 +506,8 @@ public synchronized void updateScore(int line, T score) { this.scores.set(line, score); try { - if (customScoresSupported()) { - sendScorePacket(getScoreByLine(line), ScoreboardAction.CHANGE); + if (VersionType.V1_20_3.isCurrentAtLeast()) { + sendModernScorePacket(getScoreByLine(line), ScoreboardAction.CHANGE); } } catch (Throwable e) { throw new RuntimeException("Unable to update line score", e); @@ -550,8 +561,8 @@ public synchronized void updateScores(Collection scores) { this.scores.set(i, newScores.get(i)); try { - if (customScoresSupported()) { - sendScorePacket(getScoreByLine(i), ScoreboardAction.CHANGE); + if (VersionType.V1_20_3.isCurrentAtLeast()) { + sendModernScorePacket(getScoreByLine(i), ScoreboardAction.CHANGE); } } catch (Throwable e) { throw new RuntimeException("Unable to update scores", e); @@ -586,15 +597,6 @@ public boolean isDeleted() { return this.deleted; } - /** - * Returns whether the server supports custom scoreboard scores (1.20.3+ servers only). - * - * @return true if the server supports custom scores - */ - public boolean customScoresSupported() { - return VersionType.V1_20_3.isCurrentAtLeast(); - } - /** * Returns the scoreboard size (the number of lines). * @@ -630,6 +632,11 @@ public synchronized void delete() { this.deleted = true; } + /** + * Sends a line update packet for the specified internal score. + * + * @param score the position to update + */ protected abstract void sendLineChange(int score) throws Throwable; protected abstract Object toMinecraftComponent(T value) throws Throwable; @@ -732,7 +739,7 @@ protected void sendScorePacket(int score, ScoreboardAction action) throws Throwa sendPacket(packet); } - private void sendModernScorePacket(int score, ScoreboardAction action) throws Throwable { + protected void sendModernScorePacket(int score, ScoreboardAction action) throws Throwable { String objName = COLOR_CODES[score]; Object enumAction = action == ScoreboardAction.REMOVE ? ENUM_SB_ACTION_REMOVE : ENUM_SB_ACTION_CHANGE; @@ -747,14 +754,14 @@ private void sendModernScorePacket(int score, ScoreboardAction action) throws Th return; } - T text = getLineByScore(score); - T scoreFormat = getLineByScore(this.scores, score); - Object format = scoreFormat != null - ? FIXED_NUMBER_FORMAT.invoke(toMinecraftComponent(scoreFormat)) + Object text = toMinecraftComponent(getLineByScore(score)); + T rawFormat = getLineByScore(this.scores, score); + Object format = rawFormat != null + ? FIXED_NUMBER_FORMAT.invoke(toMinecraftComponent(rawFormat)) : BLANK_NUMBER_FORMAT; Object scorePacket = SCORE_OPTIONAL_COMPONENTS - ? PACKET_SB_SET_SCORE.invoke(objName, this.id, score, Optional.of(toMinecraftComponent(text)), Optional.of(format)) - : PACKET_SB_SET_SCORE.invoke(objName, this.id, score, toMinecraftComponent(text), format); + ? PACKET_SB_SET_SCORE.invoke(objName, this.id, score, Optional.of(text), Optional.of(format)) + : PACKET_SB_SET_SCORE.invoke(objName, this.id, score, text, format); sendPacket(scorePacket); } diff --git a/src/main/java/fr/mrmicky/fastboard/adventure/FastBoard.java b/src/main/java/fr/mrmicky/fastboard/adventure/FastBoard.java index 3d9160c..6717ba7 100644 --- a/src/main/java/fr/mrmicky/fastboard/adventure/FastBoard.java +++ b/src/main/java/fr/mrmicky/fastboard/adventure/FastBoard.java @@ -75,17 +75,16 @@ public FastBoard(Player player) { } /** - * Sends a line update packet for the specified internal score. - * - * @param score the internal score of the line to update + * {@inheritDoc} */ @Override protected void sendLineChange(int score) throws Throwable { Component line = getLineByScore(score); if (VersionType.V1_20_3.isCurrentAtLeast()) { - sendScorePacket(score, ScoreboardAction.CHANGE); + sendModernScorePacket(score, ScoreboardAction.CHANGE); } else { + sendScorePacket(score, ScoreboardAction.CHANGE); sendTeamPacket(score, TeamMode.UPDATE, line, null); } } From 2f422a95c4fd904ab97e99266e3445b8699a32ab Mon Sep 17 00:00:00 2001 From: Dominilk01 <108392199+Dominilk01@users.noreply.github.com> Date: Wed, 1 Jul 2026 04:09:52 +0200 Subject: [PATCH 07/10] de-duplicated sending --- .../java/fr/mrmicky/fastboard/FastBoardBase.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/main/java/fr/mrmicky/fastboard/FastBoardBase.java b/src/main/java/fr/mrmicky/fastboard/FastBoardBase.java index 307b44a..d2848e8 100644 --- a/src/main/java/fr/mrmicky/fastboard/FastBoardBase.java +++ b/src/main/java/fr/mrmicky/fastboard/FastBoardBase.java @@ -479,11 +479,16 @@ public synchronized void updateLines(Collection lines, Collection scores) } for (int i = 0; i < linesSize; i++) { - if (!Objects.equals(getLineByScore(oldLines, i), getLineByScore(i))) { - sendLineChange(i); - } - if (!Objects.equals(getLineByScore(oldScores, i), getLineByScore(this.scores, i))) { - sendScorePacket(i, ScoreboardAction.CHANGE); + boolean isNewTextDifferentFromOld = !Objects.equals(getLineByScore(oldLines, i), getLineByScore(i)); + boolean isNewFormatDifferentFromOld = !Objects.equals(getLineByScore(oldScores, i), getLineByScore(this.scores, i)); + if (VersionType.V1_20_3.isCurrentAtLeast() && (isNewTextDifferentFromOld || isNewFormatDifferentFromOld)) { + sendModernScorePacket(i, ScoreboardAction.CHANGE); + } else { + if (isNewTextDifferentFromOld) { + sendLineChange(i); + } if (isNewFormatDifferentFromOld) { + sendScorePacket(i, ScoreboardAction.CHANGE); + } } } } catch (Throwable t) { From 9fd83ca546bbd1aee17864ed4863fd8beec00cef Mon Sep 17 00:00:00 2001 From: Dominilk01 <108392199+Dominilk01@users.noreply.github.com> Date: Thu, 2 Jul 2026 15:07:02 +0200 Subject: [PATCH 08/10] fix + remove unnecessary sends --- .../fr/mrmicky/fastboard/FastBoardBase.java | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/main/java/fr/mrmicky/fastboard/FastBoardBase.java b/src/main/java/fr/mrmicky/fastboard/FastBoardBase.java index d2848e8..bdd1c69 100644 --- a/src/main/java/fr/mrmicky/fastboard/FastBoardBase.java +++ b/src/main/java/fr/mrmicky/fastboard/FastBoardBase.java @@ -109,7 +109,7 @@ public abstract class FastBoardBase { Class packetSbScoreClass = FastReflection.nmsClass(gameProtocolPackage, "PacketPlayOutScoreboardScore", "ClientboundSetScorePacket"); Class packetSbTeamClass = VersionType.V1_20_3.isCurrentAtLeast() ? null : FastReflection.nmsClass(gameProtocolPackage, "PacketPlayOutScoreboardTeam", "ClientboundSetPlayerTeamPacket"); - Class sbTeamClass = VersionType.V1_17.isCurrentAtLeast() + Class sbTeamClass = VersionType.V1_17.isCurrentAtLeast() && !VersionType.V1_20_3.isCurrentAtLeast() ? FastReflection.innerClass(packetSbTeamClass, innerClass -> !innerClass.isEnum()) : null; Field playerConnectionField = Arrays.stream(entityPlayerClass.getFields()) .filter(field -> field.getType().isAssignableFrom(playerConnectionClass)) @@ -360,11 +360,6 @@ public synchronized void updateLine(int line, T score, T scoreText) { this.scores.set(line, scoreText); sendLineChange(getScoreByLine(line)); - - if (VersionType.V1_20_3.isCurrentAtLeast()) { - sendModernScorePacket(getScoreByLine(line), ScoreboardAction.CHANGE); - } - return; } @@ -470,8 +465,12 @@ public synchronized void updateLines(Collection lines, Collection scores) } } else { for (int i = oldLinesCopy.size(); i < linesSize; i++) { - sendScorePacket(i, ScoreboardAction.CHANGE); - if (!VersionType.V1_20_3.isCurrentAtLeast()) { + if (VersionType.V1_20_3.isCurrentAtLeast()) { + sendModernScorePacket(i, ScoreboardAction.CHANGE); + oldLines.add(0, getLineByScore(i)); + oldScores.add(0, getLineByScore(this.scores, i)); + } else { + sendScorePacket(i, ScoreboardAction.CHANGE); sendTeamPacket(i, TeamMode.CREATE, null, null); } } @@ -486,8 +485,6 @@ public synchronized void updateLines(Collection lines, Collection scores) } else { if (isNewTextDifferentFromOld) { sendLineChange(i); - } if (isNewFormatDifferentFromOld) { - sendScorePacket(i, ScoreboardAction.CHANGE); } } } From 3a09c54dfe7f6e100d673ac83169fb12a56147e1 Mon Sep 17 00:00:00 2001 From: Dominilk01 <108392199+Dominilk01@users.noreply.github.com> Date: Mon, 6 Jul 2026 02:37:18 +0200 Subject: [PATCH 09/10] replace where score packet are send for new lines --- .../java/fr/mrmicky/fastboard/FastBoardBase.java | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/main/java/fr/mrmicky/fastboard/FastBoardBase.java b/src/main/java/fr/mrmicky/fastboard/FastBoardBase.java index bdd1c69..f4aa23d 100644 --- a/src/main/java/fr/mrmicky/fastboard/FastBoardBase.java +++ b/src/main/java/fr/mrmicky/fastboard/FastBoardBase.java @@ -463,16 +463,10 @@ public synchronized void updateLines(Collection lines, Collection scores) sendScorePacket(i - 1, ScoreboardAction.REMOVE); oldLines.remove(0); } - } else { + } else if (!VersionType.V1_20_3.isCurrentAtLeast()) { for (int i = oldLinesCopy.size(); i < linesSize; i++) { - if (VersionType.V1_20_3.isCurrentAtLeast()) { - sendModernScorePacket(i, ScoreboardAction.CHANGE); - oldLines.add(0, getLineByScore(i)); - oldScores.add(0, getLineByScore(this.scores, i)); - } else { - sendScorePacket(i, ScoreboardAction.CHANGE); - sendTeamPacket(i, TeamMode.CREATE, null, null); - } + sendScorePacket(i, ScoreboardAction.CHANGE); + sendTeamPacket(i, TeamMode.CREATE, null, null); } } } From 572fce5a323281bab11928e1fb5ef24e0d1e5801 Mon Sep 17 00:00:00 2001 From: Dominilk01 <108392199+Dominilk01@users.noreply.github.com> Date: Tue, 7 Jul 2026 14:34:10 +0200 Subject: [PATCH 10/10] deduplicate --- src/main/java/fr/mrmicky/fastboard/FastBoardBase.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/main/java/fr/mrmicky/fastboard/FastBoardBase.java b/src/main/java/fr/mrmicky/fastboard/FastBoardBase.java index f4aa23d..c8a8a85 100644 --- a/src/main/java/fr/mrmicky/fastboard/FastBoardBase.java +++ b/src/main/java/fr/mrmicky/fastboard/FastBoardBase.java @@ -148,8 +148,6 @@ public abstract class FastBoardBase { if (VersionType.V1_20_3.isCurrentAtLeast()) { Class numberFormatClass = FastReflection.nmsClass("network.chat.numbers", "NumberFormat"); OBJECTIVE = lookup.unreflectConstructor(objectiveClass.getConstructor(scoreboardClass, String.class, objectiveCriteriaClass, CHAT_COMPONENT_CLASS, objectiveRenderTypeClass, boolean.class, numberFormatClass)); - PACKET_SB_OBJ = lookup.unreflectConstructor(packetSbObjClass.getConstructor(objectiveClass, int.class)); - PACKET_SB_DISPLAY_OBJ = lookup.unreflectConstructor(packetSbDisplayObjClass.getConstructor(DISPLAY_SLOT_TYPE, objectiveClass)); Class blankFormatClass = FastReflection.nmsClass("network.chat.numbers", "BlankFormat"); Class fixedFormatClass = FastReflection.nmsClass("network.chat.numbers", "FixedFormat"); @@ -179,8 +177,6 @@ public abstract class FastBoardBase { MethodType scoreType = MethodType.methodType(void.class, enumSbAction, String.class, String.class, int.class); packetSbSetScore = lookup.findConstructor(packetSbScoreClass, scoreType); OBJECTIVE = lookup.unreflectConstructor(objectiveClass.getConstructor(scoreboardClass, String.class, objectiveCriteriaClass, CHAT_COMPONENT_CLASS, objectiveRenderTypeClass)); - PACKET_SB_OBJ = lookup.unreflectConstructor(packetSbObjClass.getConstructor(objectiveClass, int.class)); - PACKET_SB_DISPLAY_OBJ = lookup.unreflectConstructor(packetSbDisplayObjClass.getConstructor(displaySlotEnum.orElse(int.class), objectiveClass)); } else { packetSbSetScore = lookup.findConstructor(packetSbScoreClass, MethodType.methodType(void.class)); if (VersionType.V1_13.isCurrentAtLeast()) { @@ -188,8 +184,6 @@ public abstract class FastBoardBase { } else { OBJECTIVE = lookup.unreflectConstructor(objectiveClass.getConstructor(scoreboardClass, String.class, objectiveCriteriaClass)); } - PACKET_SB_OBJ = lookup.unreflectConstructor(packetSbObjClass.getConstructor(objectiveClass, int.class)); - PACKET_SB_DISPLAY_OBJ = lookup.unreflectConstructor(packetSbDisplayObjClass.getConstructor(int.class, objectiveClass)); } for (Class clazz : Arrays.asList(packetSbScoreClass, packetSbTeamClass, sbTeamClass, playerTeamClass, objectiveClass)) { @@ -206,6 +200,8 @@ public abstract class FastBoardBase { } } + PACKET_SB_OBJ = lookup.unreflectConstructor(packetSbObjClass.getConstructor(objectiveClass, int.class)); + PACKET_SB_DISPLAY_OBJ = lookup.unreflectConstructor(packetSbDisplayObjClass.getConstructor(DISPLAY_SLOT_TYPE, objectiveClass)); PACKET_SB_SET_SCORE = packetSbSetScore; PACKET_SB_RESET_SCORE = packetSbResetScore; PACKET_SB_TEAM = packetSbTeam;