diff --git a/src/main/java/cc/fascinated/api/controller/PlayerController.java b/src/main/java/cc/fascinated/api/controller/PlayerController.java index c2af20d..a7c79cd 100644 --- a/src/main/java/cc/fascinated/api/controller/PlayerController.java +++ b/src/main/java/cc/fascinated/api/controller/PlayerController.java @@ -4,6 +4,7 @@ import cc.fascinated.player.PlayerManagerService; import cc.fascinated.player.impl.Player; import cc.fascinated.player.impl.Skin; import cc.fascinated.player.impl.SkinPart; +import lombok.NonNull; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.CacheControl; import org.springframework.http.HttpStatus; @@ -12,12 +13,14 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.util.Map; +import java.util.Objects; import java.util.concurrent.TimeUnit; @RestController @RequestMapping(value = "/") public class PlayerController { + @NonNull private final SkinPart defaultHead = Objects.requireNonNull(Skin.getDefaultHead(), "Default head is null"); private final PlayerManagerService playerManagerService; @Autowired @@ -37,15 +40,17 @@ public class PlayerController { @GetMapping(value = "/avatar/{id}") public ResponseEntity getPlayerHead(@PathVariable String id) { Player player = playerManagerService.getPlayer(id); + byte[] headBytes; if (player == null) { - return null; + headBytes = defaultHead.getPartData(); + } else { + Skin skin = player.getSkin(); + SkinPart head = skin.getHead(); + headBytes = head.getPartData(); } - - Skin skin = player.getSkin(); - SkinPart head = skin.getHead(); return ResponseEntity.ok() .cacheControl(CacheControl.maxAge(1, TimeUnit.HOURS).cachePublic()) .contentType(MediaType.IMAGE_PNG) - .body(head.getPartData()); + .body(headBytes); } } diff --git a/src/main/java/cc/fascinated/player/impl/Player.java b/src/main/java/cc/fascinated/player/impl/Player.java index 1e8b406..54bbb37 100644 --- a/src/main/java/cc/fascinated/player/impl/Player.java +++ b/src/main/java/cc/fascinated/player/impl/Player.java @@ -67,5 +67,4 @@ public class Player { this.skin = new Skin(skinJson.get("url").getAsString(), SkinType.fromString(metadataJson.get("model").getAsString())); this.cape = new Cape(capeJson.get("url").getAsString()); } - } diff --git a/src/main/java/cc/fascinated/player/impl/Skin.java b/src/main/java/cc/fascinated/player/impl/Skin.java index f3f16bf..b7e9fa4 100644 --- a/src/main/java/cc/fascinated/player/impl/Skin.java +++ b/src/main/java/cc/fascinated/player/impl/Skin.java @@ -4,12 +4,15 @@ import cc.fascinated.Main; import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.Getter; import lombok.SneakyThrows; +import lombok.extern.log4j.Log4j2; +import org.apache.tomcat.util.http.fileupload.IOUtils; +import java.io.InputStream; import java.net.URI; import java.net.http.HttpRequest; import java.net.http.HttpResponse; -@Getter +@Getter @Log4j2 public class Skin { /** @@ -40,7 +43,7 @@ public class Skin { this.skinBytes = this.getSkinData(); // The skin parts - this.head = new SkinPart(this.skinBytes, 8, 8, 8, 8, 20); + this.head = new SkinPart(this.skinBytes, SkinPartEnum.HEAD); } /** @@ -57,4 +60,22 @@ public class Skin { return Main.getCLIENT().send(request, HttpResponse.BodyHandlers.ofByteArray()).body(); } + + /** + * Gets the default/fallback head. + * + * @return the default head + */ + public static SkinPart getDefaultHead() { + try (InputStream stream = Main.class.getClassLoader().getResourceAsStream("images/default_head.png")) { + if (stream == null) { + return null; + } + byte[] bytes = stream.readAllBytes(); + return new SkinPart(bytes, SkinPartEnum.HEAD); + } catch (Exception ex) { + log.warn("Failed to load default head", ex); + return null; + } + } } diff --git a/src/main/java/cc/fascinated/player/impl/SkinPart.java b/src/main/java/cc/fascinated/player/impl/SkinPart.java index 641ca17..5fc26d2 100644 --- a/src/main/java/cc/fascinated/player/impl/SkinPart.java +++ b/src/main/java/cc/fascinated/player/impl/SkinPart.java @@ -47,13 +47,13 @@ public class SkinPart { */ private byte[] partBytes; - public SkinPart(byte[] data, int x, int y, int width, int height, int scale) { + public SkinPart(byte[] data, SkinPartEnum skinPartEnum) { this.data = data; - this.x = x; - this.y = y; - this.width = width; - this.height = height; - this.scale = scale; + this.x = skinPartEnum.getX(); + this.y = skinPartEnum.getY(); + this.width = skinPartEnum.getWidth(); + this.height = skinPartEnum.getHeight(); + this.scale = skinPartEnum.getScale(); } /** diff --git a/src/main/java/cc/fascinated/player/impl/SkinPartEnum.java b/src/main/java/cc/fascinated/player/impl/SkinPartEnum.java new file mode 100644 index 0000000..9165f52 --- /dev/null +++ b/src/main/java/cc/fascinated/player/impl/SkinPartEnum.java @@ -0,0 +1,16 @@ +package cc.fascinated.player.impl; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter @AllArgsConstructor +public enum SkinPartEnum { + + HEAD(8, 8, 8, 8, 20); + + private final int x; + private final int y; + private final int width; + private final int height; + private final int scale; +} diff --git a/src/main/resources/images/default_head.png b/src/main/resources/images/default_head.png new file mode 100644 index 0000000..32b3889 Binary files /dev/null and b/src/main/resources/images/default_head.png differ