Skip to content

Commit e563a73

Browse files
committed
feat(6.2.6): Minecraft 1.20.4 support (closes #71, #64, #69)
1 parent 791965d commit e563a73

15 files changed

Lines changed: 577 additions & 33 deletions

README.md

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<a target="_blank"><img src="https://github.com/CatCoderr/ProtocolSidebar/actions/workflows/build.yaml/badge.svg" alt="Build" /></a>
99
<a target="_blank"><img src="https://img.shields.io/github/license/CatCoderr/ProtocolSidebar" alt="License" /></a>
1010
<a target="_blank"><img src="https://img.shields.io/nexus/s/me.catcoder/bukkit-sidebar?server=https%3A%2F%2Foss.sonatype.org" alt="Nexus" /></a>
11-
<a target="_blank"><img src="https://img.shields.io/badge/Minecraft%20Versions-1.12.2--1.20.2-blue?style=flat" alt="Minecraft Versions" /></a>
11+
<a target="_blank"><img src="https://img.shields.io/badge/Minecraft%20Versions-1.12.2--1.20.4-blue?style=flat" alt="Minecraft Versions" /></a>
1212
</p>
1313

1414
* [Features](#features)
@@ -18,6 +18,7 @@
1818
* [Gradle (Kotlin DSL)](#gradle-kotlin-dsl)
1919
* [Basic usage](#basic-usage)
2020
* [Conditional lines](#conditional-lines)
21+
* [Score number formatting](#score-number-formatting)
2122
* [Sidebar title animations](#sidebar-title-animations)
2223
* [Sidebar Pager](#sidebar-pager)
2324

@@ -65,7 +66,7 @@ or [maven-shade-plugin](https://maven.apache.org/plugins/maven-shade-plugin/) (f
6566
<dependency>
6667
<groupId>me.catcoder</groupId>
6768
<artifactId>bukkit-sidebar</artifactId>
68-
<version>6.2.5-SNAPSHOT</version>
69+
<version>6.2.6-SNAPSHOT</version>
6970
</dependency>
7071
```
7172

@@ -78,7 +79,7 @@ repositories {
7879
```
7980
```groovy
8081
dependencies {
81-
implementation 'me.catcoder:bukkit-sidebar:6.2.5-SNAPSHOT'
82+
implementation 'me.catcoder:bukkit-sidebar:6.2.6-SNAPSHOT'
8283
}
8384
```
8485

@@ -91,7 +92,7 @@ repositories {
9192
```
9293
```kotlin
9394
dependencies {
94-
implementation("me.catcoder:bukkit-sidebar:6.2.5-SNAPSHOT")
95+
implementation("me.catcoder:bukkit-sidebar:6.2.6-SNAPSHOT")
9596
}
9697
```
9798

@@ -145,11 +146,19 @@ The visibility of these lines depends on the condition you set.
145146
If the condition is true, the line will be shown, otherwise it will be hidden.
146147
It's an updatable line, so it will update along with other updatable lines.
147148

149+
## Score number formatting
150+
You can use `scoreNumberFormat` method in both `ScoreboardObjective` and `SidebarLine` classes to format score numbers.
151+
152+
This feature is available starting from 1.20.4 version.
148153
```java
149-
sidebar.addConditionalLine(
150-
player -> Component.text("This line will be shown only for players with health less than 10"),
151-
player -> player.getHealth() <= 10
152-
);
154+
// removes scores completely for all lines
155+
sidebar.getObjective().scoreNumberFormatBlank();
156+
// set's custom fixed text for all lines
157+
sidebar.getObjective().scoreNumberFormatFixed(player -> Component.text("Test").color(NamedTextColor.BLUE));
158+
159+
// set's score number format for specific line (overrides objective's format)
160+
var line = sidebar.addLine(Component.text("Some line").color(NamedTextColor.YELLOW));
161+
line.scoreNumberFormatFixed(player -> Component.text("Test").color(NamedTextColor.BLUE));
153162
```
154163

155164
## Sidebar Title Animations

build.gradle.kts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ plugins {
66
}
77

88
group = "me.catcoder"
9-
version = "6.2.5-SNAPSHOT"
9+
version = "6.2.6-SNAPSHOT"
1010
description = "Powerful feature-packed Minecraft scoreboard library"
1111

1212
extra["sonatypeUsername"] = System.getenv("SONATYPE_USERNAME")
@@ -29,6 +29,7 @@ allprojects {
2929
maven { url = uri("https://oss.sonatype.org/content/groups/public/") }
3030
maven { url = uri("https://repo.viaversion.com") }
3131
maven { url = uri("https://repo.maven.apache.org/maven2/") }
32+
maven { url = uri("https://repo.opencollab.dev/maven-releases/") }
3233
}
3334
dependencies {
3435
testImplementation("junit:junit:4.13.2")
@@ -39,6 +40,8 @@ allprojects {
3940
compileOnly("io.papermc.paper:paper-api:${paperVersion}")
4041
testCompileOnly("io.papermc.paper:paper-api:${paperVersion}")
4142

43+
implementation("com.github.steveice10:opennbt:1.6")
44+
4245
compileOnly("org.projectlombok:lombok:${lombokVersion}")
4346
annotationProcessor("org.projectlombok:lombok:${lombokVersion}")
4447

run_test_server.sh

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
VIA_VERSION=4.7.0
1+
VIA_VERSION=4.9.3
2+
3+
./gradlew clean shadowJar
4+
25
echo "Copying ProtocolSidebar..."
36
cp bin/ProtocolSidebar-*.jar server/data/plugins/ProtocolSidebar.jar
47

server/docker-compose.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ services:
99
environment:
1010
EULA: "TRUE"
1111
TYPE: "PAPER"
12-
VERSION: "1.20.2"
12+
VERSION: "1.20.4"
1313
JAVA_TOOL_OPTIONS: "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005"
1414
tty: true
1515
stdin_open: true

src/main/java/me/catcoder/sidebar/ScoreboardObjective.java

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
package me.catcoder.sidebar;
22

3+
import com.google.common.base.Function;
34
import com.google.common.base.Preconditions;
45
import io.netty.buffer.ByteBuf;
56
import lombok.Getter;
67
import lombok.NonNull;
78
import me.catcoder.sidebar.protocol.ChannelInjector;
89
import me.catcoder.sidebar.protocol.PacketIds;
910
import me.catcoder.sidebar.protocol.ProtocolConstants;
11+
import me.catcoder.sidebar.protocol.ScoreNumberFormat;
1012
import me.catcoder.sidebar.text.TextProvider;
1113
import me.catcoder.sidebar.util.buffer.ByteBufNetOutput;
1214
import me.catcoder.sidebar.util.buffer.NetOutput;
@@ -32,9 +34,15 @@ public class ScoreboardObjective<R> {
3234

3335
private final String name;
3436
private final TextProvider<R> textProvider;
37+
38+
private ScoreNumberFormat numberFormat;
39+
private Function<Player, R> numberFormatter;
40+
3541
private R displayName;
3642

37-
ScoreboardObjective(@NonNull String name, @NonNull R displayName, @NonNull TextProvider<R> textProvider) {
43+
ScoreboardObjective(@NonNull String name,
44+
@NonNull R displayName,
45+
@NonNull TextProvider<R> textProvider) {
3846
Preconditions.checkArgument(
3947
name.length() <= 16, "Objective name exceeds 16 symbols limit");
4048

@@ -52,6 +60,21 @@ void updateValue(@NonNull Player player) {
5260
sendPacket(player, packet);
5361
}
5462

63+
public void scoreNumberFormatFixed(@NonNull Function<Player, R> numberFormatter) {
64+
this.numberFormat = ScoreNumberFormat.FIXED;
65+
this.numberFormatter = numberFormatter;
66+
}
67+
68+
public void scoreNumberFormatStyled(@NonNull Function<Player, R> numberFormatter) {
69+
this.numberFormat = ScoreNumberFormat.STYLED;
70+
this.numberFormatter = numberFormatter;
71+
}
72+
73+
public void scoreNumberFormatBlank() {
74+
this.numberFormat = ScoreNumberFormat.BLANK;
75+
this.numberFormatter = null;
76+
}
77+
5578
void create(@NonNull Player player) {
5679
ByteBuf packet = getPacket(player, ADD_OBJECTIVE);
5780
sendPacket(player, packet);
@@ -94,12 +117,28 @@ private ByteBuf getPacket(@NonNull Player player, int mode) {
94117
legacyText = legacyText.substring(0, 32);
95118
}
96119

97-
if (VersionUtil.SERVER_VERSION >= ProtocolConstants.MINECRAFT_1_13) {
120+
if (VersionUtil.SERVER_VERSION >= ProtocolConstants.MINECRAFT_1_20_3) {
121+
// what the heck 1.20.3?
122+
output.writeComponent(textProvider.asJsonMessage(player, displayName));
123+
} else if (VersionUtil.SERVER_VERSION >= ProtocolConstants.MINECRAFT_1_13) {
98124
output.writeString(textProvider.asJsonMessage(player, displayName));
99125
} else {
100126
output.writeString(legacyText);
101127
}
102128

129+
if (VersionUtil.SERVER_VERSION >= ProtocolConstants.MINECRAFT_1_20_3) {
130+
output.writeVarInt(0);
131+
output.writeBoolean(numberFormat != null); // has number format
132+
133+
if (numberFormat != null) {
134+
numberFormat.accept(output, numberFormatter == null ?
135+
null : textProvider.asJsonMessage(player, numberFormatter.apply(player))
136+
);
137+
}
138+
139+
return buf;
140+
}
141+
103142
if (VersionUtil.SERVER_VERSION >= ProtocolConstants.MINECRAFT_1_13) {
104143
output.writeVarInt(0); // Health display
105144
} else {

src/main/java/me/catcoder/sidebar/Sidebar.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ public class Sidebar<R> {
3535

3636
private final Set<UUID> viewers = Collections.synchronizedSet(new HashSet<>());
3737
private final List<SidebarLine<R>> lines = new ArrayList<>();
38+
@Getter
3839
private final ScoreboardObjective<R> objective;
3940

4041
private TextIterator titleText;

src/main/java/me/catcoder/sidebar/SidebarLine.java

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package me.catcoder.sidebar;
22

3+
import com.google.common.base.Function;
34
import com.google.common.base.Preconditions;
45
import io.netty.buffer.ByteBuf;
56
import lombok.*;
67
import me.catcoder.sidebar.protocol.ChannelInjector;
8+
import me.catcoder.sidebar.protocol.ScoreNumberFormat;
79
import me.catcoder.sidebar.protocol.ScoreboardPackets;
810
import me.catcoder.sidebar.text.TextProvider;
911
import me.catcoder.sidebar.util.lang.ThrowingFunction;
@@ -31,6 +33,8 @@ public class SidebarLine<R> {
3133
private ThrowingFunction<Player, R, Throwable> updater;
3234
private ThrowingPredicate<Player, Throwable> displayCondition;
3335
private final TextProvider<R> textProvider;
36+
private ScoreNumberFormat scoreNumberFormat;
37+
private Function<Player, R> scoreNumberFormatter;
3438

3539
SidebarLine(@NonNull ThrowingFunction<Player, R, Throwable> updater,
3640
@NonNull String teamName,
@@ -46,6 +50,24 @@ public class SidebarLine<R> {
4650
this.textProvider = textProvider;
4751
}
4852

53+
public SidebarLine<R> scoreNumberFormatBlank() {
54+
this.scoreNumberFormat = null;
55+
this.scoreNumberFormatter = null;
56+
return this;
57+
}
58+
59+
public SidebarLine<R> scoreNumberFormatFixed(@NonNull Function<Player, R> scoreNumberFormatter) {
60+
this.scoreNumberFormat = ScoreNumberFormat.FIXED;
61+
this.scoreNumberFormatter = scoreNumberFormatter;
62+
return this;
63+
}
64+
65+
public SidebarLine<R> scoreNumberFormatStyled(@NonNull Function<Player, R> scoreNumberFormatter) {
66+
this.scoreNumberFormat = ScoreNumberFormat.STYLED;
67+
this.scoreNumberFormatter = scoreNumberFormatter;
68+
return this;
69+
}
70+
4971
public BukkitTask updatePeriodically(long delay, long period, @NonNull Sidebar<R> sidebar) {
5072
Preconditions.checkState(!isStaticText(), "Cannot set updater for static text line");
5173

@@ -102,21 +124,25 @@ void updateTeam(@NonNull Player player, @NonNull String objective) throws Throwa
102124

103125
if (!isStaticText() && visible) {
104126
R text = updater.apply(player);
105-
sendPacket(player, ScoreboardPackets.createTeamPacket(ScoreboardPackets.TEAM_UPDATED, index, teamName,
127+
sendPacket(player, ScoreboardPackets.createTeamPacket(
128+
ScoreboardPackets.TEAM_UPDATED, index, teamName,
106129
player, text, textProvider));
107130
}
108131

109132
if (!visible) {
110133
// if player doesn't meet display condition, remove score
111-
sendPacket(player, ScoreboardPackets.createScorePacket(player, 1, objective, score, index));
134+
sendPacket(player, ScoreboardPackets.createScorePacket(
135+
player, 1, objective, score, index, textProvider, scoreNumberFormat, null));
112136
return;
113137
}
114138

115-
sendPacket(player, ScoreboardPackets.createScorePacket(player, 0, objective, score, index));
139+
sendPacket(player, ScoreboardPackets.createScorePacket(
140+
player, 0, objective, score, index, textProvider, scoreNumberFormat, scoreNumberFormatter));
116141
}
117142

118143
void removeTeam(@NonNull Player player, @NonNull String objective) {
119-
sendPacket(player, ScoreboardPackets.createScorePacket(player, 1, objective, score, index));
144+
sendPacket(player, ScoreboardPackets.createScorePacket(
145+
player, 1, objective, score, index, textProvider, null, null));
120146

121147
sendPacket(player, ScoreboardPackets.createTeamPacket(ScoreboardPackets.TEAM_REMOVED, index, teamName,
122148
player, null, textProvider));
@@ -131,7 +157,8 @@ void createTeam(@NonNull Player player, @NonNull String objective) throws Throwa
131157
player, text, textProvider));
132158

133159
if (visible) {
134-
sendPacket(player, ScoreboardPackets.createScorePacket(player, 0, objective, score, index));
160+
sendPacket(player, ScoreboardPackets.createScorePacket(
161+
player, 0, objective, score, index, textProvider, scoreNumberFormat, scoreNumberFormatter));
135162
}
136163
}
137164

src/main/java/me/catcoder/sidebar/protocol/PacketIds.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ public enum PacketIds {
1616
map(ProtocolConstants.MINECRAFT_1_19_1, 0x58),
1717
map(ProtocolConstants.MINECRAFT_1_19_3, 0x56),
1818
map(ProtocolConstants.MINECRAFT_1_19_4, 0x5A),
19-
map(ProtocolConstants.MINECRAFT_1_20_2, 0x5C)
19+
map(ProtocolConstants.MINECRAFT_1_20_2, 0x5C),
20+
map(ProtocolConstants.MINECRAFT_1_20_4, 0x5E)
2021
),
2122
UPDATE_SCORE(
2223
map(ProtocolConstants.MINECRAFT_1_12_2, 0x45),
@@ -27,8 +28,13 @@ public enum PacketIds {
2728
map(ProtocolConstants.MINECRAFT_1_19_1, 0x59),
2829
map(ProtocolConstants.MINECRAFT_1_19_3, 0x57),
2930
map(ProtocolConstants.MINECRAFT_1_19_4, 0x5B),
30-
map(ProtocolConstants.MINECRAFT_1_20_2, 0x5D)
31+
map(ProtocolConstants.MINECRAFT_1_20_2, 0x5D),
32+
map(ProtocolConstants.MINECRAFT_1_20_4, 0x5F)
3133

34+
35+
),
36+
RESET_SCORE(
37+
map(ProtocolConstants.MINECRAFT_1_20_3, 0x42)
3238
),
3339
OBJECTIVE_DISPLAY(
3440
map(ProtocolConstants.MINECRAFT_1_12_2, 0x3B),
@@ -39,7 +45,8 @@ public enum PacketIds {
3945
map(ProtocolConstants.MINECRAFT_1_19_1, 0x4F),
4046
map(ProtocolConstants.MINECRAFT_1_19_3, 0x4D),
4147
map(ProtocolConstants.MINECRAFT_1_19_4, 0x51),
42-
map(ProtocolConstants.MINECRAFT_1_20_2, 0x53)
48+
map(ProtocolConstants.MINECRAFT_1_20_2, 0x53),
49+
map(ProtocolConstants.MINECRAFT_1_20_4, 0x55)
4350

4451
),
4552
OBJECTIVE(
@@ -51,7 +58,8 @@ public enum PacketIds {
5158
map(ProtocolConstants.MINECRAFT_1_19_1, 0x56),
5259
map(ProtocolConstants.MINECRAFT_1_19_3, 0x54),
5360
map(ProtocolConstants.MINECRAFT_1_19_4, 0x58),
54-
map(ProtocolConstants.MINECRAFT_1_20_2, 0x5A)
61+
map(ProtocolConstants.MINECRAFT_1_20_2, 0x5A),
62+
map(ProtocolConstants.MINECRAFT_1_20_4, 0x5C)
5563
);
5664

5765
private final ProtocolConstants.ProtocolMapping[] mappings;

src/main/java/me/catcoder/sidebar/protocol/ProtocolConstants.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,11 @@ public class ProtocolConstants {
4343
public static final int MINECRAFT_1_20 = 763;
4444
public static final int MINECRAFT_1_20_1 = 763;
4545
public static final int MINECRAFT_1_20_2 = 764;
46+
public static final int MINECRAFT_1_20_3 = 765;
47+
public static final int MINECRAFT_1_20_4 = 765;
4648

4749
public static final int MINIMUM_SUPPORTED_VERSION = MINECRAFT_1_12_2;
48-
public static final int MAXIMUM_SUPPORTED_VERSION = MINECRAFT_1_20_2;
50+
public static final int MAXIMUM_SUPPORTED_VERSION = MINECRAFT_1_20_4;
4951

5052
@Getter
5153
@RequiredArgsConstructor
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package me.catcoder.sidebar.protocol;
2+
3+
import com.google.common.base.Preconditions;
4+
import me.catcoder.sidebar.util.buffer.NetOutput;
5+
6+
import java.util.function.BiConsumer;
7+
8+
public enum ScoreNumberFormat implements BiConsumer<NetOutput, String> {
9+
10+
BLANK {
11+
@Override
12+
public void accept(NetOutput out, String value) {
13+
out.writeVarInt(0);
14+
}
15+
},
16+
STYLED {
17+
@Override
18+
public void accept(NetOutput netOutput, String value) {
19+
netOutput.writeVarInt(1);
20+
Preconditions.checkArgument(value != null, "Value cannot be null for STYLED format");
21+
netOutput.writeComponent(value);
22+
}
23+
},
24+
FIXED {
25+
@Override
26+
public void accept(NetOutput out, String value) {
27+
out.writeVarInt(2);
28+
Preconditions.checkArgument(value != null, "Value cannot be null for FIXED format");
29+
out.writeComponent(value);
30+
}
31+
}
32+
}

0 commit comments

Comments
 (0)