more cleanup
All checks were successful
deploy / deploy (push) Successful in 42s

This commit is contained in:
Lee
2024-04-08 05:29:05 +01:00
parent 3f7f1864a6
commit 1f45d26f53
11 changed files with 34 additions and 31 deletions

View File

@ -0,0 +1,13 @@
package cc.fascinated.model.player;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter @AllArgsConstructor
public class Cape {
/**
* The URL of the cape
*/
private final String url;
}

View File

@ -0,0 +1,53 @@
package cc.fascinated.model.player;
import cc.fascinated.service.mojang.model.MojangProfile;
import cc.fascinated.util.Tuple;
import cc.fascinated.util.UUIDUtils;
import lombok.Getter;
import java.util.List;
import java.util.UUID;
@Getter
public class Player {
/**
* The UUID of the player
*/
private final UUID uuid;
/**
* The name of the player
*/
private final String name;
/**
* The skin of the player, null if the
* player does not have a skin
*/
private Skin skin;
/**
* The cape of the player, null if the
* player does not have a cape
*/
private Cape cape;
/**
* The raw properties of the player
*/
private final List<MojangProfile.ProfileProperty> rawProperties;
public Player(MojangProfile profile) {
this.uuid = UUID.fromString(UUIDUtils.addUUIDDashes(profile.getId()));
this.name = profile.getName();
this.rawProperties = profile.getProperties();
// Get the skin and cape
Tuple<Skin, Cape> skinAndCape = profile.getSkinAndCape();
if (skinAndCape != null) {
this.skin = skinAndCape.getLeft();
this.cape = skinAndCape.getRight();
}
}
}

View File

@ -0,0 +1,136 @@
package cc.fascinated.model.player;
import cc.fascinated.Main;
import cc.fascinated.config.Config;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.SneakyThrows;
import lombok.extern.log4j.Log4j2;
import java.io.InputStream;
import java.net.URI;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.HashMap;
import java.util.Map;
@Getter @Log4j2
public class Skin {
/**
* The URL of the skin
*/
private final String url;
/**
* The model of the skin
*/
private final SkinType model;
/**
* The bytes of the skin
*/
@JsonIgnore
private final byte[] skinBytes;
/**
* The skin parts for this skin
*/
@JsonIgnore
private final Map<SkinPartEnum, SkinPart> parts = new HashMap<>();
@JsonProperty("parts")
private final Map<String, String> partUrls = new HashMap<>();
public Skin(String playerUuid, String url, SkinType model) {
this.url = url;
this.model = model;
this.skinBytes = this.getSkinData();
// The skin parts
this.parts.put(SkinPartEnum.HEAD, new SkinPart(this.skinBytes, SkinPartEnum.HEAD));
for (Map.Entry<SkinPartEnum, SkinPart> entry : this.parts.entrySet()) {
String partName = entry.getKey().name().toLowerCase();
this.partUrls.put(partName, Config.INSTANCE.getWebPublicUrl() + "/player/" + partName + "/" + playerUuid + "?size=250");
}
}
/**
* 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;
}
}
/**
* Gets the skin data from the URL.
*
* @return the skin data
*/
@SneakyThrows @JsonIgnore
public byte[] getSkinData() {
HttpRequest request = HttpRequest.newBuilder()
.uri(new URI(this.url))
.GET()
.build();
return Main.getCLIENT().send(request, HttpResponse.BodyHandlers.ofByteArray()).body();
}
/**
* Gets a part from the skin.
*
* @param part the part name
* @return the part
*/
public SkinPart getPart(String part) {
return this.parts.get(SkinPartEnum.valueOf(part.toUpperCase()));
}
/**
* The skin part enum that contains the
* information about the part.
*/
@Getter @AllArgsConstructor
public enum SkinPartEnum {
HEAD(8, 8, 8, 8, 250);
/**
* The x and y position of the part.
*/
private final int x, y;
/**
* The width and height of the part.
*/
private final int width, height;
/**
* The scale of the part.
*/
private final int defaultSize;
}
/**
* The type of the skin.
*/
public enum SkinType {
DEFAULT,
SLIM
}
}

View File

@ -0,0 +1,69 @@
package cc.fascinated.model.player;
import lombok.Getter;
import lombok.extern.log4j.Log4j2;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@Getter @Log4j2
public class SkinPart {
/**
* The whole skin data.
*/
private final byte[] data;
/**
* The information about the part.
*/
private final Skin.SkinPartEnum skinPartEnum;
/**
* The part data from the skin.
*/
private byte[] partBytes;
public SkinPart(byte[] data, Skin.SkinPartEnum skinPartEnum) {
this.data = data;
this.skinPartEnum = skinPartEnum;
}
/**
* Gets the part data from the skin.
*
* @return the part data
*/
public byte[] getPartData(int size) {
if (size == -1) {
size = this.skinPartEnum.getDefaultSize();
}
try {
BufferedImage image = ImageIO.read(new ByteArrayInputStream(this.data));
if (image == null) {
return null;
}
// Get the part of the image (e.g. the head)
BufferedImage partImage = image.getSubimage(this.skinPartEnum.getX(), this.skinPartEnum.getY(), this.skinPartEnum.getWidth(), this.skinPartEnum.getHeight());
// Scale the image
BufferedImage scaledImage = new BufferedImage(size, size, partImage.getType());
Graphics2D graphics2D = scaledImage.createGraphics();
graphics2D.drawImage(partImage, 0, 0, size, size, null);
graphics2D.dispose();
partImage = scaledImage;
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ImageIO.write(partImage, "png", byteArrayOutputStream);
this.partBytes = byteArrayOutputStream.toByteArray();
return this.partBytes;
} catch (Exception ex) {
log.error("Failed to read image from skin data.", ex);
return null;
}
}
}

View File

@ -1,4 +1,4 @@
package cc.fascinated.model;
package cc.fascinated.model.response;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.micrometer.common.lang.NonNull;