Make the skin part route dynamic

This commit is contained in:
Braydon 2024-04-07 00:11:22 -04:00
parent 50a6af9ed8
commit add07cb84c

@ -2,6 +2,7 @@ package me.braydon.mc.controller;
import lombok.NonNull; import lombok.NonNull;
import lombok.extern.log4j.Log4j2; import lombok.extern.log4j.Log4j2;
import me.braydon.mc.common.EnumUtils;
import me.braydon.mc.common.PlayerUtils; import me.braydon.mc.common.PlayerUtils;
import me.braydon.mc.exception.impl.BadRequestException; import me.braydon.mc.exception.impl.BadRequestException;
import me.braydon.mc.exception.impl.ResourceNotFoundException; import me.braydon.mc.exception.impl.ResourceNotFoundException;
@ -24,8 +25,8 @@ import org.springframework.web.bind.annotation.*;
@RequestMapping(value = "/player", produces = MediaType.APPLICATION_JSON_VALUE) @RequestMapping(value = "/player", produces = MediaType.APPLICATION_JSON_VALUE)
@Log4j2(topic = "Player Controller") @Log4j2(topic = "Player Controller")
public final class PlayerController { public final class PlayerController {
private static final int DEFAULT_HEAD_SIZE = 128; private static final int DEFAULT_PART_TEXTURE_SIZE = 128;
private static final int MAX_HEAD_SIZE = 512; private static final int MAX_PART_TEXTURE_SIZE = 512;
/** /**
* The Mojang service to use for player information. * The Mojang service to use for player information.
@ -52,34 +53,39 @@ public final class PlayerController {
} }
/** /**
* Get the head texture of a player * Get the part of a skin texture for
* by their username or UUID. * a player by their username or UUID.
* <p> * <p>
* If the player being searched is * If the player being searched is
* invalid, the default Steve skin * invalid, the default Steve skin
* will be used. * will be used.
* </p> * </p>
* *
* @param partName the part of the player's skin texture to get
* @param query the query to search for the player by * @param query the query to search for the player by
* @param extension the head image extension * @param extension the skin part image extension
* @param size the size of the head image * @param size the size of the skin part image
* @return the head texture * @return the skin part texture
* @throws BadRequestException if the extension is invalid * @throws BadRequestException if the extension is invalid
*/ */
@GetMapping("/head/{query}.{extension}") @GetMapping("/{partName}/{query}.{extension}")
@ResponseBody @ResponseBody
public ResponseEntity<byte[]> getHead(@PathVariable @NonNull String query, @PathVariable @NonNull String extension, public ResponseEntity<byte[]> getPartTexture(@PathVariable @NonNull String partName, @PathVariable @NonNull String query,
@RequestParam(required = false) Integer size @PathVariable @NonNull String extension, @RequestParam(required = false) Integer size
) throws BadRequestException { ) throws BadRequestException {
Skin.Part part = EnumUtils.getEnumConstant(Skin.Part.class, partName.toUpperCase()); // The skin part to get
if (part == null) { // Default to the head part
part = Skin.Part.HEAD;
}
if ((extension = extension.trim()).isBlank()) { // Invalid extension if ((extension = extension.trim()).isBlank()) { // Invalid extension
throw new BadRequestException("Invalid extension"); throw new BadRequestException("Invalid extension");
} }
if (size == null || size <= 0) { // Invalid size if (size == null || size <= 0) { // Invalid size
size = DEFAULT_HEAD_SIZE; size = DEFAULT_PART_TEXTURE_SIZE;
} }
size = Math.min(size, MAX_HEAD_SIZE); // Limit the size to 512 size = Math.min(size, MAX_PART_TEXTURE_SIZE); // Limit the size to 512
Skin target = null; // The target skin to get the head of Skin target = null; // The target skin to get the skin part of
try { try {
CachedPlayer player = mojangService.getPlayer(query, false); // Retrieve the player CachedPlayer player = mojangService.getPlayer(query, false); // Retrieve the player
target = player.getSkin(); // Use the player's skin target = player.getSkin(); // Use the player's skin
@ -89,9 +95,9 @@ public final class PlayerController {
if (target == null) { // Fallback to the default skin if (target == null) { // Fallback to the default skin
target = Skin.DEFAULT_STEVE; target = Skin.DEFAULT_STEVE;
} }
// Return the head texture // Return the skin part texture
return ResponseEntity.ok() return ResponseEntity.ok()
.contentType(extension.equalsIgnoreCase("png") ? MediaType.IMAGE_PNG : MediaType.IMAGE_JPEG) .contentType(extension.equalsIgnoreCase("png") ? MediaType.IMAGE_PNG : MediaType.IMAGE_JPEG)
.body(PlayerUtils.getSkinPart(target, Skin.Part.HEAD, size)); .body(PlayerUtils.getSkinPart(target, part, size));
} }
} }