Skip to content

Commit d9b2563

Browse files
authored
Add support for Mojang mappings (#57)
1 parent 402661c commit d9b2563

File tree

4 files changed

+35
-23
lines changed

4 files changed

+35
-23
lines changed

README.md

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44
[![Maven Central](https://img.shields.io/maven-central/v/fr.mrmicky/fastboard.svg?label=Maven%20Central)](https://central.sonatype.com/artifact/fr.mrmicky/fastboard)
55
[![Discord](https://img.shields.io/discord/390919659874156560.svg?colorB=5865f2&label=Discord&logo=discord&logoColor=white)](https://discord.gg/q9UwaBT)
66

7-
Lightweight packet-based scoreboard API for Bukkit plugins, with 1.7.10 to 1.20.x support.
7+
Lightweight packet-based scoreboard API for Bukkit plugins, compatible with all Minecraft versions starting with 1.7.10.
88

99
> [!IMPORTANT]
1010
> To use FastBoard on a 1.8 server, the server must be on 1.8.8.
1111
1212
## Features
1313

1414
* No flickering (without using a buffer)
15-
* Works with all versions from 1.7.10 to 1.20
15+
* Compatible with all Minecraft versions starting with 1.7.10
1616
* Small (around 750 lines of code with the JavaDoc) and no dependencies
1717
* Easy to use
1818
* Dynamic scoreboard size: you don't need to add/remove lines, you can directly give a string list (or array) to change all the lines
@@ -23,6 +23,7 @@ Lightweight packet-based scoreboard API for Bukkit plugins, with 1.7.10 to 1.20.
2323
* [RGB HEX colors support](#rgb-colors) on 1.16 and higher
2424
* [Custom number formatting](#custom-number-formatting) (including blank) for scores on 1.20.3 and higher
2525
* [Adventure components support](#adventure-support)
26+
* Support for both Spigot and Mojang mappings
2627

2728
## Installation
2829

@@ -59,7 +60,7 @@ Lightweight packet-based scoreboard API for Bukkit plugins, with 1.7.10 to 1.20.
5960
<dependency>
6061
<groupId>fr.mrmicky</groupId>
6162
<artifactId>fastboard</artifactId>
62-
<version>2.1.2</version>
63+
<version>2.1.3</version>
6364
</dependency>
6465
</dependencies>
6566
```
@@ -79,7 +80,7 @@ repositories {
7980
}
8081
8182
dependencies {
82-
implementation 'fr.mrmicky:fastboard:2.1.2'
83+
implementation 'fr.mrmicky:fastboard:2.1.3'
8384
}
8485
8586
shadowJar {
@@ -187,24 +188,28 @@ public final class ExamplePlugin extends JavaPlugin implements Listener {
187188

188189
For servers on modern [PaperMC](https://papermc.io) versions, FastBoard supports
189190
using [Adventure](https://github.com/KyoriPowered/adventure) components instead of strings,
190-
by using the class `fr.mrmicky.fastboard.adventure.FastBoard`.
191+
by using the `fr.mrmicky.fastboard.adventure.FastBoard` class.
192+
193+
> [!WARNING]
194+
> With Adventure, on servers below Minecraft 1.13, lines are truncated to a maximum of 16 characters.
195+
> To get around this limit, upgrade to a newer version of Minecraft or use the non-Adventure version (`fr.mrmicky.fastboard.FastBoard`).
191196
192197
## RGB colors
193198

194199
When using the non-Adventure version of FastBoard, RGB colors can be added on 1.16 and higher with `ChatColor.of("#RRGGBB")` (`net.md_5.bungee.api.ChatColor` import).
195200

196201
## Custom number formatting
197202

198-
For servers on Minecraft 1.20.3 and higher, FastBoard supports custom number formatting for scores.
199-
By default, the blank format is used, so no score is visible, but it's also possible to specify custom scores using `FastBoard#updateLine(line, text, scoreText)`,
203+
For servers on Minecraft 1.20.3 and above, FastBoard supports custom number formatting for scores.
204+
By default, it uses the blank format, so that no score is visible, but it's also possible to set custom scores using `FastBoard#updateLine(line, text, scoreText)`,
200205
`FastBoard#updateLines(lines, scores)` and `FastBoard#updateScore(line, text)`.
201206

202207
Passing a `null` value as a score will result in a reset to the default blank formatting.
203208

204209
## ViaBackwards compatibility
205210

206211
When using ViaBackwards on a post-1.13 server with pre-1.13 clients, older clients
207-
might get incomplete lines. To solve this issue, you can override the method `hasLinesMaxLength()` and return `true` for older clients.
212+
may receive incomplete lines. To solve this problem, you can override the `hasLinesMaxLength()` method and return `true` for older clients.
208213
For example using the ViaVersion API:
209214
```java
210215
FastBoard board = new FastBoard(player) {

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>fr.mrmicky</groupId>
88
<artifactId>fastboard</artifactId>
9-
<version>2.1.2</version>
9+
<version>2.1.3</version>
1010

1111
<name>FastBoard</name>
1212
<description>Lightweight packet-based scoreboard API for Bukkit plugins.</description>

src/main/java/fr/mrmicky/fastboard/FastBoardBase.java

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
* The project is on <a href="https://github.com/MrMicky-FR/FastBoard">GitHub</a>.
4444
*
4545
* @author MrMicky
46-
* @version 2.1.2
46+
* @version 2.1.3
4747
*/
4848
public abstract class FastBoardBase<T> {
4949

@@ -84,23 +84,25 @@ public abstract class FastBoardBase<T> {
8484

8585
if (FastReflection.isRepackaged()) {
8686
VERSION_TYPE = VersionType.V1_17;
87-
} else if (FastReflection.nmsOptionalClass(null, "ScoreboardServer$Action").isPresent()) {
87+
} else if (FastReflection.nmsOptionalClass(null, "ScoreboardServer$Action").isPresent()
88+
|| FastReflection.nmsOptionalClass(null, "ServerScoreboard$Method").isPresent()) {
8889
VERSION_TYPE = VersionType.V1_13;
89-
} else if (FastReflection.nmsOptionalClass(null, "IScoreboardCriteria$EnumScoreboardHealthDisplay").isPresent()) {
90+
} else if (FastReflection.nmsOptionalClass(null, "IScoreboardCriteria$EnumScoreboardHealthDisplay").isPresent()
91+
|| FastReflection.nmsOptionalClass(null, "ObjectiveCriteria$RenderType").isPresent()) {
9092
VERSION_TYPE = VersionType.V1_8;
9193
} else {
9294
VERSION_TYPE = VersionType.V1_7;
9395
}
9496

9597
String gameProtocolPackage = "network.protocol.game";
9698
Class<?> craftPlayerClass = FastReflection.obcClass("entity.CraftPlayer");
97-
Class<?> entityPlayerClass = FastReflection.nmsClass("server.level", "EntityPlayer");
98-
Class<?> playerConnectionClass = FastReflection.nmsClass("server.network", "PlayerConnection");
99+
Class<?> entityPlayerClass = FastReflection.nmsClass("server.level", "EntityPlayer", "ServerPlayer");
100+
Class<?> playerConnectionClass = FastReflection.nmsClass("server.network", "PlayerConnection", "ServerGamePacketListenerImpl");
99101
Class<?> packetClass = FastReflection.nmsClass("network.protocol", "Packet");
100-
Class<?> packetSbObjClass = FastReflection.nmsClass(gameProtocolPackage, "PacketPlayOutScoreboardObjective");
101-
Class<?> packetSbDisplayObjClass = FastReflection.nmsClass(gameProtocolPackage, "PacketPlayOutScoreboardDisplayObjective");
102-
Class<?> packetSbScoreClass = FastReflection.nmsClass(gameProtocolPackage, "PacketPlayOutScoreboardScore");
103-
Class<?> packetSbTeamClass = FastReflection.nmsClass(gameProtocolPackage, "PacketPlayOutScoreboardTeam");
102+
Class<?> packetSbObjClass = FastReflection.nmsClass(gameProtocolPackage, "PacketPlayOutScoreboardObjective", "ClientboundSetObjectivePacket");
103+
Class<?> packetSbDisplayObjClass = FastReflection.nmsClass(gameProtocolPackage, "PacketPlayOutScoreboardDisplayObjective", "ClientboundSetDisplayObjectivePacket");
104+
Class<?> packetSbScoreClass = FastReflection.nmsClass(gameProtocolPackage, "PacketPlayOutScoreboardScore", "ClientboundSetScorePacket");
105+
Class<?> packetSbTeamClass = FastReflection.nmsClass(gameProtocolPackage, "PacketPlayOutScoreboardTeam", "ClientboundSetPlayerTeamPacket");
104106
Class<?> sbTeamClass = VersionType.V1_17.isHigherOrEqual()
105107
? FastReflection.innerClass(packetSbTeamClass, innerClass -> !innerClass.isEnum()) : null;
106108
Field playerConnectionField = Arrays.stream(entityPlayerClass.getFields())
@@ -113,8 +115,8 @@ public abstract class FastBoardBase<T> {
113115
.filter(m -> m.getParameterCount() == 1 && m.getParameterTypes()[0] == packetClass)
114116
.findFirst().orElseThrow(NoSuchMethodException::new);
115117
Optional<Class<?>> displaySlotEnum = FastReflection.nmsOptionalClass("world.scores", "DisplaySlot");
116-
CHAT_COMPONENT_CLASS = FastReflection.nmsClass("network.chat", "IChatBaseComponent");
117-
CHAT_FORMAT_ENUM = FastReflection.nmsClass(null, "EnumChatFormat");
118+
CHAT_COMPONENT_CLASS = FastReflection.nmsClass("network.chat", "IChatBaseComponent","Component");
119+
CHAT_FORMAT_ENUM = FastReflection.nmsClass(null, "EnumChatFormat", "ChatFormatting");
118120
DISPLAY_SLOT_TYPE = displaySlotEnum.orElse(int.class);
119121
RESET_FORMATTING = FastReflection.enumValueOf(CHAT_FORMAT_ENUM, "RESET", 21);
120122
SIDEBAR_DISPLAY_SLOT = displaySlotEnum.isPresent() ? FastReflection.enumValueOf(DISPLAY_SLOT_TYPE, "SIDEBAR", 1) : 1;
@@ -149,7 +151,7 @@ public abstract class FastBoardBase<T> {
149151
packetSbResetScore = lookup.findConstructor(resetScoreClass, removeScoreType);
150152
blankNumberFormat = blankField.isPresent() ? blankField.get().get(null) : null;
151153
} else if (VersionType.V1_17.isHigherOrEqual()) {
152-
Class<?> enumSbAction = FastReflection.nmsClass("server", "ScoreboardServer$Action");
154+
Class<?> enumSbAction = FastReflection.nmsClass("server", "ScoreboardServer$Action", "ServerScoreboard$Method");
153155
MethodType scoreType = MethodType.methodType(void.class, enumSbAction, String.class, String.class, int.class);
154156
packetSbSetScore = lookup.findConstructor(packetSbScoreClass, scoreType);
155157
} else {
@@ -181,8 +183,8 @@ public abstract class FastBoardBase<T> {
181183
String enumSbActionClass = VersionType.V1_13.isHigherOrEqual()
182184
? "ScoreboardServer$Action"
183185
: "PacketPlayOutScoreboardScore$EnumScoreboardAction";
184-
ENUM_SB_HEALTH_DISPLAY = FastReflection.nmsClass("world.scores.criteria", "IScoreboardCriteria$EnumScoreboardHealthDisplay");
185-
ENUM_SB_ACTION = FastReflection.nmsClass("server", enumSbActionClass);
186+
ENUM_SB_HEALTH_DISPLAY = FastReflection.nmsClass("world.scores.criteria", "IScoreboardCriteria$EnumScoreboardHealthDisplay", "ObjectiveCriteria$RenderType");
187+
ENUM_SB_ACTION = FastReflection.nmsClass("server", enumSbActionClass, "ServerScoreboard$Method");
186188
ENUM_SB_HEALTH_DISPLAY_INTEGER = FastReflection.enumValueOf(ENUM_SB_HEALTH_DISPLAY, "INTEGER", 0);
187189
ENUM_SB_ACTION_CHANGE = FastReflection.enumValueOf(ENUM_SB_ACTION, "CHANGE", 0);
188190
ENUM_SB_ACTION_REMOVE = FastReflection.enumValueOf(ENUM_SB_ACTION, "REMOVE", 1);

src/main/java/fr/mrmicky/fastboard/FastReflection.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ public final class FastReflection {
4545

4646
private static final MethodType VOID_METHOD_TYPE = MethodType.methodType(void.class);
4747
private static final boolean NMS_REPACKAGED = optionalClass(NM_PACKAGE + ".network.protocol.Packet").isPresent();
48+
private static final boolean MOJANG_MAPPINGS = optionalClass(NM_PACKAGE + ".network.chat.Component").isPresent();
4849

4950
private static volatile Object theUnsafe;
5051

@@ -70,6 +71,10 @@ public static Class<?> nmsClass(String post1_17package, String className) throws
7071
return Class.forName(nmsClassName(post1_17package, className));
7172
}
7273

74+
public static Class<?> nmsClass(String post1_17package, String spigotClass, String mojangClass) throws ClassNotFoundException {
75+
return nmsClass(post1_17package, MOJANG_MAPPINGS ? mojangClass : spigotClass);
76+
}
77+
7378
public static Optional<Class<?>> nmsOptionalClass(String post1_17package, String className) {
7479
return optionalClass(nmsClassName(post1_17package, className));
7580
}

0 commit comments

Comments
 (0)