fix unknown player and add player not found response
All checks were successful
deploy / deploy (push) Successful in 42s

This commit is contained in:
Lee 2024-04-06 18:57:09 +01:00
parent 1542cff64e
commit a060d5d027
5 changed files with 86 additions and 7 deletions

@ -0,0 +1,32 @@
package cc.fascinated.api.controller;
import cc.fascinated.api.model.ErrorResponse;
import io.micrometer.common.lang.NonNull;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
@ControllerAdvice
public final class ExceptionControllerAdvice {
/**
* Handle a raised exception.
*
* @param ex the raised exception
* @return the error response
*/
@ExceptionHandler(Exception.class)
public ResponseEntity<?> handleException(@NonNull Exception ex) {
HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR; // Get the HTTP status
if (ex.getClass().isAnnotationPresent(ResponseStatus.class)) { // Get from the @ResponseStatus annotation
status = ex.getClass().getAnnotation(ResponseStatus.class).value();
}
String message = ex.getLocalizedMessage(); // Get the error message
if (message == null) { // Fallback
message = "An internal error has occurred.";
}
ex.printStackTrace(); // Print the stack trace
return new ResponseEntity<>(new ErrorResponse(status, message), status);
}
}

@ -5,14 +5,13 @@ import cc.fascinated.player.impl.Player;
import cc.fascinated.player.impl.Skin; import cc.fascinated.player.impl.Skin;
import cc.fascinated.player.impl.SkinPart; import cc.fascinated.player.impl.SkinPart;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.CacheControl; import org.springframework.http.CacheControl;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@RestController @RestController
@ -27,10 +26,10 @@ public class PlayerController {
} }
@GetMapping(value = "/{id}", produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody @GetMapping(value = "/{id}", produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody
public ResponseEntity<Player> getPlayer(@PathVariable String id) { public ResponseEntity<?> getPlayer(@PathVariable String id) {
Player player = playerManagerService.getPlayer(id); Player player = playerManagerService.getPlayer(id);
if (player == null) { if (player == null) {
return ResponseEntity.notFound().build(); return new ResponseEntity<>(Map.of("error", "Player not found"), HttpStatus.NOT_FOUND);
} }
return ResponseEntity.ok(player); return ResponseEntity.ok(player);
} }

@ -0,0 +1,40 @@
package cc.fascinated.api.model;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.micrometer.common.lang.NonNull;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import org.springframework.http.HttpStatus;
import java.util.Date;
@NoArgsConstructor
@Setter
@Getter
@ToString
public final class ErrorResponse {
/**
* The status code of this error.
*/
@NonNull
private HttpStatus status;
/**
* The message of this error.
*/
@NonNull private String message;
/**
* The timestamp this error occurred.
*/
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy hh:mm:ss")
private Date timestamp;
public ErrorResponse(@NonNull HttpStatus status, @NonNull String message) {
this.status = status;
this.message = message;
timestamp = new Date();
}
}

@ -35,6 +35,9 @@ public class MojangAPIService {
.build(); .build();
HttpResponse<String> response = Main.getCLIENT().send(request, HttpResponse.BodyHandlers.ofString()); HttpResponse<String> response = Main.getCLIENT().send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) {
return null;
}
return Main.getGSON().fromJson(response.body(), new TypeToken<MojangSessionServerProfile>(){}.getType()); return Main.getGSON().fromJson(response.body(), new TypeToken<MojangSessionServerProfile>(){}.getType());
} }
@ -52,6 +55,9 @@ public class MojangAPIService {
.build(); .build();
HttpResponse<String> response = Main.getCLIENT().send(request, HttpResponse.BodyHandlers.ofString()); HttpResponse<String> response = Main.getCLIENT().send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) {
return null;
}
return Main.getGSON().fromJson(response.body(), new TypeToken<MojangApiProfile>(){}.getType()); return Main.getGSON().fromJson(response.body(), new TypeToken<MojangApiProfile>(){}.getType());
} }
} }

@ -46,14 +46,16 @@ public class PlayerManagerService {
* @return the player or null if the player does not exist * @return the player or null if the player does not exist
*/ */
public Player getPlayer(String id) { public Player getPlayer(String id) {
UUID uuid; UUID uuid = null;
if (id.length() == 32 || id.length() == 36) { if (id.length() == 32 || id.length() == 36) {
uuid = UUID.fromString(id.length() == 32 ? UUIDUtils.addUUIDDashes(id) : id); try {
uuid = UUID.fromString(id.length() == 32 ? UUIDUtils.addUUIDDashes(id) : id);
} catch (Exception ignored) {}
} else { } else {
uuid = playerNameToUUIDCache.get(id.toUpperCase()); uuid = playerNameToUUIDCache.get(id.toUpperCase());
} }
if (players.containsKey(uuid)) { if (uuid != null && players.containsKey(uuid)) {
return players.get(uuid); return players.get(uuid);
} }