Add server icon route
All checks were successful
Deploy App / docker (ubuntu-latest, 2.44.0) (push) Successful in 1m11s
All checks were successful
Deploy App / docker (ubuntu-latest, 2.44.0) (push) Successful in 1m11s
This commit is contained in:
parent
a5725849f3
commit
9315182e3c
@ -10,7 +10,7 @@ A simple, yet useful RESTful API for Minecraft utilizing Springboot.
|
||||
Hi there! Looking for usage? View the [Wiki](https://git.rainnny.club/Rainnny/RESTfulMC/wiki) for more information!
|
||||
|
||||
## TODO
|
||||
- [ ] Server Icon Route
|
||||
- [x] Server Icon Route
|
||||
- [ ] Unit Tests
|
||||
- [ ] Blacklist Checking
|
||||
- [ ] HTTP Codes in wiki
|
||||
|
@ -692,7 +692,7 @@ import java.net.URL;
|
||||
* @author Braydon
|
||||
*/
|
||||
@UtilityClass
|
||||
public final class PlayerUtils {
|
||||
public final class ImageUtils {
|
||||
public static final int SKIN_TEXTURE_SIZE = 64; // The skin of a skin texture
|
||||
|
||||
/**
|
@ -686,6 +686,8 @@ import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Base64;
|
||||
|
||||
/**
|
||||
* The controller for handling
|
||||
* {@link MinecraftServer} related requests.
|
||||
@ -696,6 +698,8 @@ import org.springframework.web.bind.annotation.*;
|
||||
@RequestMapping(value = "/server", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Log4j2(topic = "Server Controller")
|
||||
public final class ServerController {
|
||||
private static final String DEFAULT_SERVER_ICON = "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";
|
||||
|
||||
/**
|
||||
* The Mojang service to use for server information.
|
||||
*/
|
||||
@ -715,9 +719,28 @@ public final class ServerController {
|
||||
*/
|
||||
@GetMapping("/{platform}/{hostname}")
|
||||
@ResponseBody
|
||||
public ResponseEntity<CachedMinecraftServer> getServer(@PathVariable @NonNull String platform,
|
||||
@PathVariable @NonNull String hostname
|
||||
) {
|
||||
public ResponseEntity<CachedMinecraftServer> getServer(@PathVariable @NonNull String platform, @PathVariable @NonNull String hostname) {
|
||||
return ResponseEntity.ofNullable(mojangService.getMinecraftServer(platform, hostname));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the server icon of a Minecraft
|
||||
* server by its platform and hostname.
|
||||
*
|
||||
* @param platform the platform of the server
|
||||
* @param hostname the hostname of the server
|
||||
* @return the server icon
|
||||
*/
|
||||
@GetMapping("/icon/{platform}/{hostname}")
|
||||
@ResponseBody
|
||||
public ResponseEntity<byte[]> getServerIcon(@PathVariable @NonNull String platform, @PathVariable @NonNull String hostname) {
|
||||
MinecraftServer.Favicon favicon = mojangService.getMinecraftServer(platform, hostname).getValue().getFavicon();
|
||||
String icon = favicon == null ? DEFAULT_SERVER_ICON : favicon.getBase64(); // Get the server icon
|
||||
if (favicon != null) { // Remove the data type from the server icon
|
||||
icon = icon.substring(icon.indexOf(",") + 1);
|
||||
}
|
||||
return ResponseEntity.ok()
|
||||
.contentType(MediaType.IMAGE_PNG)
|
||||
.body(Base64.getDecoder().decode(icon));
|
||||
}
|
||||
}
|
@ -678,6 +678,7 @@ package me.braydon.mc.model;
|
||||
|
||||
import lombok.*;
|
||||
import me.braydon.mc.common.ColorUtils;
|
||||
import me.braydon.mc.config.AppConfig;
|
||||
import me.braydon.mc.service.pinger.MinecraftServerPinger;
|
||||
import me.braydon.mc.service.pinger.impl.BedrockMinecraftServerPinger;
|
||||
import me.braydon.mc.service.pinger.impl.JavaMinecraftServerPinger;
|
||||
@ -712,16 +713,16 @@ public class MinecraftServer {
|
||||
*/
|
||||
@NonNull private final Players players;
|
||||
|
||||
/**
|
||||
* The favicon of this server, null if none.
|
||||
*/
|
||||
private final Favicon favicon;
|
||||
|
||||
/**
|
||||
* The MOTD of this server.
|
||||
*/
|
||||
@NonNull private final MOTD motd;
|
||||
|
||||
/**
|
||||
* The Base64 encoded icon of this server, null if no icon.
|
||||
*/
|
||||
private final String icon;
|
||||
|
||||
/**
|
||||
* Player count data for a server.
|
||||
*/
|
||||
@ -759,6 +760,32 @@ public class MinecraftServer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The favicon for a server.
|
||||
*/
|
||||
@AllArgsConstructor @Getter @ToString
|
||||
public static class Favicon {
|
||||
/**
|
||||
* The raw Base64 encoded favicon.
|
||||
*/
|
||||
@NonNull private final String base64;
|
||||
|
||||
/**
|
||||
* The URL to the favicon.
|
||||
*/
|
||||
@NonNull private final String url;
|
||||
|
||||
public static Favicon create(String base64, @NonNull Platform platform, @NonNull String hostname) {
|
||||
if (base64 == null) { // No favicon to create
|
||||
return null;
|
||||
}
|
||||
return new Favicon(
|
||||
base64,
|
||||
AppConfig.INSTANCE.getServerPublicUrl() + "/server/icon/" + platform.name().toLowerCase() + "/" + hostname
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The MOTD for a server.
|
||||
*/
|
||||
|
@ -679,7 +679,7 @@ 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.common.ImageUtils;
|
||||
import me.braydon.mc.config.AppConfig;
|
||||
|
||||
import java.util.HashMap;
|
||||
@ -754,7 +754,7 @@ public final class Skin {
|
||||
*/
|
||||
@AllArgsConstructor @Getter @ToString
|
||||
public enum Part {
|
||||
HEAD(8, 8, PlayerUtils.SKIN_TEXTURE_SIZE / 8, PlayerUtils.SKIN_TEXTURE_SIZE / 8);
|
||||
HEAD(8, 8, ImageUtils.SKIN_TEXTURE_SIZE / 8, ImageUtils.SKIN_TEXTURE_SIZE / 8);
|
||||
|
||||
/**
|
||||
* The coordinates of this part.
|
||||
|
@ -686,7 +686,7 @@ import me.braydon.mc.model.MinecraftServer;
|
||||
*/
|
||||
public final class BedrockMinecraftServer extends MinecraftServer {
|
||||
private BedrockMinecraftServer(@NonNull String hostname, String ip, int port, @NonNull Players players,
|
||||
@NonNull MOTD motd, String icon) {
|
||||
super(hostname, ip, port, players, motd, icon);
|
||||
Favicon favicon, @NonNull MOTD motd) {
|
||||
super(hostname, ip, port, players, favicon, motd);
|
||||
}
|
||||
}
|
@ -724,9 +724,9 @@ public final class JavaMinecraftServer extends MinecraftServer {
|
||||
private final boolean mojangBanned;
|
||||
|
||||
private JavaMinecraftServer(@NonNull String hostname, String ip, int port, @NonNull Players players,
|
||||
@NonNull MOTD motd, String icon, @NonNull Version version, ModInfo modInfo,
|
||||
Favicon favicon, @NonNull MOTD motd, @NonNull Version version, ModInfo modInfo,
|
||||
boolean enforcesSecureChat, boolean preventsChatReports, boolean mojangBanned) {
|
||||
super(hostname, ip, port, players, motd, icon);
|
||||
super(hostname, ip, port, players, favicon, motd);
|
||||
this.version = version;
|
||||
this.modInfo = modInfo;
|
||||
this.enforcesSecureChat = enforcesSecureChat;
|
||||
@ -749,9 +749,9 @@ public final class JavaMinecraftServer extends MinecraftServer {
|
||||
if (motdString == null) { // Not a string motd, convert from Json
|
||||
motdString = new TextComponent(ComponentSerializer.parse(RESTfulMC.GSON.toJson(token.getDescription()))).toLegacyText();
|
||||
}
|
||||
return new JavaMinecraftServer(hostname, ip, port, token.getPlayers(), MOTD.create(motdString),
|
||||
token.getFavicon(), token.getVersion().detailedCopy(), token.getModInfo(),
|
||||
token.isEnforcesSecureChat(), token.isPreventsChatReports(), false
|
||||
return new JavaMinecraftServer(hostname, ip, port, token.getPlayers(), Favicon.create(token.getFavicon(), Platform.JAVA, hostname),
|
||||
MOTD.create(motdString), token.getVersion().detailedCopy(), token.getModInfo(), token.isEnforcesSecureChat(),
|
||||
token.isPreventsChatReports(), false
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -850,7 +850,7 @@ public final class MojangService {
|
||||
if (target == null) { // Fallback to the default skin
|
||||
target = Skin.DEFAULT_STEVE;
|
||||
}
|
||||
return PlayerUtils.getSkinPart(target, part, size);
|
||||
return ImageUtils.getSkinPart(target, part, size);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user