Skip to content

Commit 14160e1

Browse files
authored
feat: Implement SkinSource for Player and GameProfile (PaperMC#1721)
1 parent 9bfe19f commit 14160e1

File tree

2 files changed

+34
-2
lines changed

2 files changed

+34
-2
lines changed

api/src/main/java/com/velocitypowered/api/proxy/Player.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import net.kyori.adventure.text.Component;
4040
import net.kyori.adventure.text.event.HoverEvent;
4141
import net.kyori.adventure.text.event.HoverEventSource;
42+
import net.kyori.adventure.text.object.PlayerHeadObjectContents;
4243
import org.checkerframework.checker.nullness.qual.Nullable;
4344
import org.jetbrains.annotations.NotNull;
4445

@@ -49,7 +50,8 @@ public interface Player extends
4950
/* Fundamental Velocity interfaces */
5051
CommandSource, InboundConnection, ChannelMessageSource, ChannelMessageSink,
5152
/* Adventure-specific interfaces */
52-
Identified, HoverEventSource<HoverEvent.ShowEntity>, Keyed, KeyIdentifiable, Sound.Emitter {
53+
Identified, HoverEventSource<HoverEvent.ShowEntity>, Keyed, KeyIdentifiable, Sound.Emitter,
54+
PlayerHeadObjectContents.SkinSource {
5355

5456
/**
5557
* Returns the player's current username.
@@ -339,6 +341,16 @@ default void clearHeaderAndFooter() {
339341
Component.text(getUsername()))));
340342
}
341343

344+
@SuppressWarnings("UnstableApiUsage") // permitted implementation
345+
@Override
346+
default void applySkinToPlayerHeadContents(
347+
final PlayerHeadObjectContents.@NotNull Builder builder) {
348+
builder.skin(this.getGameProfile());
349+
if (this.hasSentPlayerSettings()) {
350+
builder.hat(this.getPlayerSettings().getSkinParts().hasHat());
351+
}
352+
}
353+
342354
/**
343355
* Gets the player's client brand.
344356
*

api/src/main/java/com/velocitypowered/api/util/GameProfile.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,14 @@
1111
import com.google.common.collect.ImmutableList;
1212
import java.util.List;
1313
import java.util.UUID;
14+
import java.util.stream.Collectors;
15+
import net.kyori.adventure.text.object.PlayerHeadObjectContents;
16+
import org.jetbrains.annotations.NotNull;
1417

1518
/**
1619
* Represents a Mojang game profile. This class is immutable.
1720
*/
18-
public final class GameProfile {
21+
public final class GameProfile implements PlayerHeadObjectContents.SkinSource {
1922

2023
private final UUID id;
2124
private final String undashedId;
@@ -169,6 +172,23 @@ public static GameProfile forOfflinePlayer(String username) {
169172
ImmutableList.of());
170173
}
171174

175+
@SuppressWarnings("UnstableApiUsage") // permitted implementation
176+
@Override
177+
public void applySkinToPlayerHeadContents(
178+
final PlayerHeadObjectContents.@NotNull Builder builder) {
179+
if (this.properties.isEmpty()) {
180+
builder.id(this.id);
181+
return;
182+
}
183+
184+
builder.id(this.id)
185+
.name(this.name)
186+
.profileProperties(this.properties.stream()
187+
.map(property -> PlayerHeadObjectContents.property(property.getName(),
188+
property.getValue(), property.getSignature()))
189+
.collect(Collectors.toList()));
190+
}
191+
172192
@Override
173193
public String toString() {
174194
return "GameProfile{"

0 commit comments

Comments
 (0)