Show skin part URLs in the Skin model

This commit is contained in:
Braydon 2024-04-07 00:07:08 -04:00
parent 193974dda9
commit 50a6af9ed8
6 changed files with 80 additions and 6 deletions

@ -17,18 +17,19 @@ import java.net.URL;
*/
@UtilityClass
public final class PlayerUtils {
private static final int SKIN_TEXTURE_SIZE = 64; // The skin of a skin texture
public static final int SKIN_TEXTURE_SIZE = 64; // The skin of a skin texture
/**
* Get the head texture of a skin.
*
* @param skin the skin to get the head texture from
* @param part the part of the skin to get
* @param size the size to scale the head texture to
* @return the head texture of the skin
*/
@SneakyThrows
public static byte[] getHeadTexture(@NonNull Skin skin, int size) {
return getSkinPartTexture(skin, 8, 8, SKIN_TEXTURE_SIZE / 8, SKIN_TEXTURE_SIZE / 8, size);
public static byte[] getSkinPart(@NonNull Skin skin, @NonNull Skin.Part part, int size) {
return getSkinPartTexture(skin, part.getX(), part.getY(), part.getWidth(), part.getHeight(), size);
}
/**

@ -0,0 +1,24 @@
package me.braydon.mc.config;
import jakarta.annotation.PostConstruct;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
/**
* The configuration for the app.
*
* @author Braydon
*/
@Configuration @Getter
public class AppConfig {
public static AppConfig INSTANCE;
@Value("${server.publicUrl}")
private String serverPublicUrl;
@PostConstruct
public void onInitialize() {
INSTANCE = this;
}
}

@ -92,6 +92,6 @@ public final class PlayerController {
// Return the head texture
return ResponseEntity.ok()
.contentType(extension.equalsIgnoreCase("png") ? MediaType.IMAGE_PNG : MediaType.IMAGE_JPEG)
.body(PlayerUtils.getHeadTexture(target, size));
.body(PlayerUtils.getSkinPart(target, Skin.Part.HEAD, size));
}
}

@ -1,14 +1,20 @@
package me.braydon.mc.model;
import com.google.gson.JsonObject;
import com.google.gson.annotations.SerializedName;
import lombok.*;
import me.braydon.mc.common.PlayerUtils;
import me.braydon.mc.config.AppConfig;
import java.util.HashMap;
import java.util.Map;
/**
* A skin for a {@link Player}.
*
* @author Braydon
*/
@AllArgsConstructor(access = AccessLevel.PRIVATE) @Getter @ToString
@RequiredArgsConstructor(access = AccessLevel.PRIVATE) @Setter @Getter @ToString
public final class Skin {
public static final Skin DEFAULT_STEVE = new Skin("http://textures.minecraft.net/texture/60a5bd016b3c9a1b9272e4929e30827a67be4ebb219017adbbc4a4d22ebd5b1", Model.DEFAULT);
@ -22,6 +28,25 @@ public final class Skin {
*/
@NonNull private final Model model;
/**
* URLs to the parts of this skin.
*/
@NonNull @SerializedName("parts") private Map<String, String> partUrls = new HashMap<>();
/**
* Populate the part URLs for this skin.
*
* @param playerUuid the UUID of the player
* @return the skin
*/
@NonNull
public Skin populatePartUrls(@NonNull String playerUuid) {
for (Part part : Part.values()) {
partUrls.put(part.name(), AppConfig.INSTANCE.getServerPublicUrl() + "/player/" + part.name().toLowerCase() + "/" + playerUuid + ".png");
}
return this;
}
/**
* Build a skin from the given Json object.
*
@ -47,4 +72,22 @@ public final class Skin {
public enum Model {
SLIM, DEFAULT
}
/**
* The part of a skin.
*/
@AllArgsConstructor @Getter @ToString
public enum Part {
HEAD(8, 8, PlayerUtils.SKIN_TEXTURE_SIZE / 8, PlayerUtils.SKIN_TEXTURE_SIZE / 8);
/**
* The coordinates of this part.
*/
private final int x, y;
/**
* The size of this part.
*/
private final int width, height;
}
}

@ -38,6 +38,11 @@ public final class MojangProfileToken {
*/
@NonNull private final ProfileAction[] profileActions;
/**
* Get the skin and cape of this profile.
*
* @return the skin and cape of this profile
*/
public Tuple<Skin, Cape> getSkinAndCape() {
ProfileProperty textures = getPropertyByName("textures"); // Get the profile textures
if (textures == null) { // No profile textures
@ -48,7 +53,7 @@ public final class MojangProfileToken {
// Return the tuple containing the skin and cape
return new Tuple<>(
Skin.fromJsonObject(texturesJsonObject.getAsJsonObject("SKIN")),
Skin.fromJsonObject(texturesJsonObject.getAsJsonObject("SKIN")).populatePartUrls(id),
Cape.fromJsonObject(texturesJsonObject.getAsJsonObject("CAPE"))
);
}

@ -2,6 +2,7 @@
server:
address: 0.0.0.0
port: 7500
publicUrl: "http://localhost:7500" # The publicly accessible URL for this app
# Log Configuration
logging: