Mojang service
This commit is contained in:
parent
c4891ccbb5
commit
2c54defef3
6
pom.xml
6
pom.xml
@ -48,6 +48,12 @@
|
|||||||
<version>1.18.32</version>
|
<version>1.18.32</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.code.gson</groupId>
|
||||||
|
<artifactId>gson</artifactId>
|
||||||
|
<version>2.10.1</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- Tests -->
|
<!-- Tests -->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package me.braydon.mc;
|
package me.braydon.mc;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@ -16,9 +18,14 @@ import java.util.Objects;
|
|||||||
*/
|
*/
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
@Slf4j(topic = "RESTfulMC")
|
@Slf4j(topic = "RESTfulMC")
|
||||||
public final class RESTfulMC {
|
public class RESTfulMC {
|
||||||
|
public static final Gson GSON = new GsonBuilder()
|
||||||
|
.serializeNulls()
|
||||||
|
.create();
|
||||||
|
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public static void main(@NonNull String[] args) {
|
public static void main(@NonNull String[] args) {
|
||||||
|
// Handle loading of our configuration file
|
||||||
File config = new File("application.yml");
|
File config = new File("application.yml");
|
||||||
if (!config.exists()) { // Saving the default config if it doesn't exist locally
|
if (!config.exists()) { // Saving the default config if it doesn't exist locally
|
||||||
Files.copy(Objects.requireNonNull(RESTfulMC.class.getResourceAsStream("/application.yml")), config.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
Files.copy(Objects.requireNonNull(RESTfulMC.class.getResourceAsStream("/application.yml")), config.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||||
@ -28,6 +35,8 @@ public final class RESTfulMC {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
log.info("Found configuration at '{}'", config.getAbsolutePath()); // Log the found config
|
log.info("Found configuration at '{}'", config.getAbsolutePath()); // Log the found config
|
||||||
|
|
||||||
|
// Start the app
|
||||||
SpringApplication.run(RESTfulMC.class, args);
|
SpringApplication.run(RESTfulMC.class, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
13
src/main/java/me/braydon/mc/service/MojangAPI.java
Normal file
13
src/main/java/me/braydon/mc/service/MojangAPI.java
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package me.braydon.mc.service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Endpoints for the Mojang API.
|
||||||
|
*
|
||||||
|
* @author Braydon
|
||||||
|
*/
|
||||||
|
public class MojangAPI {
|
||||||
|
private static final String SESSION_SERVER_ENDPOINT = "https://sessionserver.mojang.com";
|
||||||
|
private static final String API_ENDPOINT = "https://api.mojang.com";
|
||||||
|
protected static final String UUID_TO_PROFILE = SESSION_SERVER_ENDPOINT + "/session/minecraft/profile/%s";
|
||||||
|
protected static final String USERNAME_TO_UUID = API_ENDPOINT + "/users/profiles/minecraft/%s";
|
||||||
|
}
|
93
src/main/java/me/braydon/mc/service/MojangService.java
Normal file
93
src/main/java/me/braydon/mc/service/MojangService.java
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
package me.braydon.mc.service;
|
||||||
|
|
||||||
|
import lombok.NonNull;
|
||||||
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
import me.braydon.mc.common.UUIDUtils;
|
||||||
|
import me.braydon.mc.common.web.JsonWebException;
|
||||||
|
import me.braydon.mc.common.web.JsonWebRequest;
|
||||||
|
import me.braydon.mc.exception.impl.BadRequestException;
|
||||||
|
import me.braydon.mc.exception.impl.ResourceNotFoundException;
|
||||||
|
import me.braydon.mc.model.Player;
|
||||||
|
import me.braydon.mc.model.token.MojangProfileToken;
|
||||||
|
import me.braydon.mc.model.token.MojangUsernameToUUIDToken;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A service for interacting with the Mojang API.
|
||||||
|
*
|
||||||
|
* @author Braydon
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Log4j2(topic = "Mojang Service")
|
||||||
|
public final class MojangService {
|
||||||
|
/**
|
||||||
|
* Get a player by their username or UUID.
|
||||||
|
*
|
||||||
|
* @param query the query to search for the player by
|
||||||
|
* @return the player
|
||||||
|
* @throws BadRequestException if the UUID is malformed
|
||||||
|
* @throws ResourceNotFoundException if the player is not found
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public Player getPlayer(@NonNull String query) throws BadRequestException, ResourceNotFoundException {
|
||||||
|
log.info("Requesting player with query: {}", query);
|
||||||
|
|
||||||
|
UUID uuid; // The player UUID to lookup
|
||||||
|
boolean fullLength = query.length() == 36; // Was a UUID provided?
|
||||||
|
if (query.length() == 32 || fullLength) { // Parse the query as a UUID
|
||||||
|
try {
|
||||||
|
uuid = fullLength ? UUID.fromString(query) : UUIDUtils.addDashes(query);
|
||||||
|
log.info("Parsed {}UUID: {} -> {}", fullLength ? "" : "trimmed ", query, uuid);
|
||||||
|
} catch (IllegalArgumentException ex) {
|
||||||
|
throw new BadRequestException("Malformed UUID provided: %s".formatted(query));
|
||||||
|
}
|
||||||
|
} else { // The query is a username, request from Mojang
|
||||||
|
uuid = usernameToUUID(query);
|
||||||
|
log.info("Found UUID for username {}: {}", query, uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send a request to Mojang requesting
|
||||||
|
// the player profile by their UUID
|
||||||
|
try {
|
||||||
|
log.info("Retrieving player profile for UUID: {}", uuid);
|
||||||
|
MojangProfileToken token = JsonWebRequest.makeRequest(
|
||||||
|
MojangAPI.UUID_TO_PROFILE.formatted(uuid), HttpMethod.GET
|
||||||
|
).execute(MojangProfileToken.class);
|
||||||
|
|
||||||
|
// Return our player model representing the requested player
|
||||||
|
return new Player(uuid, token.getName(), token.getProfileActions());
|
||||||
|
} catch (JsonWebException ex) {
|
||||||
|
// No profile found, return null
|
||||||
|
if (ex.getStatusCode() == 400) {
|
||||||
|
throw new ResourceNotFoundException("Player not found with query: %s".formatted(query));
|
||||||
|
}
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the UUID of a player by their username.
|
||||||
|
*
|
||||||
|
* @param username the player's username
|
||||||
|
* @return the player's UUID
|
||||||
|
* @throws ResourceNotFoundException if the player isn't found
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
private UUID usernameToUUID(@NonNull String username) throws ResourceNotFoundException {
|
||||||
|
// Make a request to Mojang requesting the UUID
|
||||||
|
try {
|
||||||
|
MojangUsernameToUUIDToken token = JsonWebRequest.makeRequest(
|
||||||
|
MojangAPI.USERNAME_TO_UUID.formatted(username), HttpMethod.GET
|
||||||
|
).execute(MojangUsernameToUUIDToken.class);
|
||||||
|
return UUIDUtils.addDashes(token.getId()); // Return the UUID with dashes
|
||||||
|
} catch (JsonWebException ex) {
|
||||||
|
if (ex.getStatusCode() == 404) {
|
||||||
|
throw new ResourceNotFoundException("Player not found with username: %s".formatted(username));
|
||||||
|
}
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user