Skip to content

Commit

Permalink
Add support for Minecraft 1.20.5 (#50)
Browse files Browse the repository at this point in the history
  • Loading branch information
syldium authored Apr 28, 2024
1 parent cb1a893 commit 177e5ea
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 11 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ jobs:

strategy:
matrix:
java-version: [8, 11, 17]
java-version: [8, 11, 17, 21]

steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Setup JDK ${{ matrix.java-version }}
uses: actions/setup-java@v2
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: ${{ matrix.java-version }}
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ Lightweight packet-based scoreboard API for Bukkit plugins, with 1.7.10 to 1.20.
<dependency>
<groupId>fr.mrmicky</groupId>
<artifactId>fastboard</artifactId>
<version>2.1.0</version>
<version>2.1.1</version>
</dependency>
</dependencies>
```
Expand All @@ -79,7 +79,7 @@ repositories {
}
dependencies {
implementation 'fr.mrmicky:fastboard:2.1.0'
implementation 'fr.mrmicky:fastboard:2.1.1'
}
shadowJar {
Expand Down
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>fr.mrmicky</groupId>
<artifactId>fastboard</artifactId>
<version>2.1.0</version>
<version>2.1.1</version>

<name>FastBoard</name>
<description>Lightweight packet-based scoreboard API for Bukkit plugins.</description>
Expand Down Expand Up @@ -52,7 +52,7 @@
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.16.1-R0.1-SNAPSHOT</version>
<version>1.16.5-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
Expand Down
20 changes: 16 additions & 4 deletions src/main/java/fr/mrmicky/fastboard/FastBoardBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
* The project is on <a href="https://github.com/MrMicky-FR/FastBoard">GitHub</a>.
*
* @author MrMicky
* @version 2.1.0
* @version 2.1.1
*/
public abstract class FastBoardBase<T> {

Expand All @@ -67,6 +67,7 @@ public abstract class FastBoardBase<T> {
private static final FastReflection.PacketConstructor PACKET_SB_SERIALIZABLE_TEAM;
private static final MethodHandle PACKET_SB_SET_SCORE;
private static final MethodHandle PACKET_SB_RESET_SCORE;
private static final boolean SCORE_OPTIONAL_COMPONENTS;
// Scoreboard enums
private static final Class<?> DISPLAY_SLOT_TYPE;
private static final Class<?> ENUM_SB_HEALTH_DISPLAY;
Expand Down Expand Up @@ -128,17 +129,23 @@ public abstract class FastBoardBase<T> {
MethodHandle packetSbResetScore = null;
MethodHandle fixedFormatConstructor = null;
Object blankNumberFormat = null;
boolean scoreOptionalComponents = false;

if (numberFormat.isPresent()) { // 1.20.3
Class<?> blankFormatClass = FastReflection.nmsClass("network.chat.numbers", "BlankFormat");
Class<?> fixedFormatClass = FastReflection.nmsClass("network.chat.numbers", "FixedFormat");
Class<?> resetScoreClass = FastReflection.nmsClass(gameProtocolPackage, "ClientboundResetScorePacket");
MethodType setScoreType = 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, numberFormat.get());
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);
Optional<Field> blankField = Arrays.stream(blankFormatClass.getFields()).filter(f -> f.getType() == blankFormatClass).findAny();
// Fields are of type Optional in 1.20.5+
Optional<MethodHandle> optionalScorePacket = FastReflection.optionalConstructor(packetSbScoreClass, lookup, scoreTypeOptional);
fixedFormatConstructor = lookup.findConstructor(fixedFormatClass, fixedFormatType);
packetSbSetScore = lookup.findConstructor(packetSbScoreClass, setScoreType);
packetSbSetScore = optionalScorePacket.isPresent() ? optionalScorePacket.get()
: lookup.findConstructor(packetSbScoreClass, scoreType);
scoreOptionalComponents = optionalScorePacket.isPresent();
packetSbResetScore = lookup.findConstructor(resetScoreClass, removeScoreType);
blankNumberFormat = blankField.isPresent() ? blankField.get().get(null) : null;
} else if (VersionType.V1_17.isHigherOrEqual()) {
Expand All @@ -155,6 +162,7 @@ public abstract class FastBoardBase<T> {
PACKET_SB_SERIALIZABLE_TEAM = sbTeamClass == null ? null : FastReflection.findPacketConstructor(sbTeamClass, lookup);
FIXED_NUMBER_FORMAT = fixedFormatConstructor;
BLANK_NUMBER_FORMAT = blankNumberFormat;
SCORE_OPTIONAL_COMPONENTS = scoreOptionalComponents;

for (Class<?> clazz : Arrays.asList(packetSbObjClass, packetSbDisplayObjClass, packetSbScoreClass, packetSbTeamClass, sbTeamClass)) {
if (clazz == null) {
Expand Down Expand Up @@ -623,6 +631,7 @@ protected void sendObjectivePacket(ObjectiveMode mode) throws Throwable {

if (mode != ObjectiveMode.REMOVE) {
setComponentField(packet, this.title, 1);
setField(packet, Optional.class, Optional.empty()); // Number format for 1.20.5+, previously nullable

if (VersionType.V1_8.isHigherOrEqual()) {
setField(packet, ENUM_SB_HEALTH_DISPLAY, ENUM_SB_HEALTH_DISPLAY_INTEGER);
Expand Down Expand Up @@ -688,8 +697,11 @@ private void sendModernScorePacket(int score, ScoreboardAction action) throws Th
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);

sendPacket(PACKET_SB_SET_SCORE.invoke(objName, this.id, score, null, format));
sendPacket(scorePacket);
}

protected void sendTeamPacket(int score, TeamMode mode) throws Throwable {
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/fr/mrmicky/fastboard/FastReflection.java
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,14 @@ static Class<?> innerClass(Class<?> parentClass, Predicate<Class<?>> classPredic
throw new ClassNotFoundException("No class in " + parentClass.getCanonicalName() + " matches the predicate.");
}

static Optional<MethodHandle> optionalConstructor(Class<?> declaringClass, MethodHandles.Lookup lookup, MethodType type) throws IllegalAccessException {
try {
return Optional.of(lookup.findConstructor(declaringClass, type));
} catch (NoSuchMethodException e) {
return Optional.empty();
}
}

public static PacketConstructor findPacketConstructor(Class<?> packetClass, MethodHandles.Lookup lookup) throws Exception {
try {
MethodHandle constructor = lookup.findConstructor(packetClass, VOID_METHOD_TYPE);
Expand Down

0 comments on commit 177e5ea

Please sign in to comment.