This commit is contained in:
@ -1,40 +0,0 @@
|
||||
package cc.fascinated.service;
|
||||
|
||||
import cc.fascinated.common.WebRequest;
|
||||
import cc.fascinated.model.mojang.MojangProfile;
|
||||
import cc.fascinated.model.mojang.MojangUsernameToUuid;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service @Log4j2
|
||||
public class MojangAPIService {
|
||||
|
||||
@Value("${mojang.session-server}")
|
||||
private String mojangSessionServerUrl;
|
||||
|
||||
@Value("${mojang.api}")
|
||||
private String mojangApiUrl;
|
||||
|
||||
/**
|
||||
* Gets the Session Server profile of the
|
||||
* player with the given UUID.
|
||||
*
|
||||
* @param id the uuid or name of the player
|
||||
* @return the profile
|
||||
*/
|
||||
public MojangProfile getProfile(String id) {
|
||||
return WebRequest.getAsEntity(mojangSessionServerUrl + "/session/minecraft/profile/" + id, MojangProfile.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the UUID of the player using
|
||||
* the name of the player.
|
||||
*
|
||||
* @param id the name of the player
|
||||
* @return the profile
|
||||
*/
|
||||
public MojangUsernameToUuid getUuidFromUsername(String id) {
|
||||
return WebRequest.getAsEntity(mojangApiUrl + "/users/profiles/minecraft/" + id, MojangUsernameToUuid.class);
|
||||
}
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
package cc.fascinated.service;
|
||||
|
||||
import cc.fascinated.common.UUIDUtils;
|
||||
import cc.fascinated.model.mojang.MojangProfile;
|
||||
import cc.fascinated.model.mojang.MojangUsernameToUuid;
|
||||
import cc.fascinated.model.player.Player;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import net.jodah.expiringmap.ExpirationPolicy;
|
||||
import net.jodah.expiringmap.ExpiringMap;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Service @Log4j2
|
||||
public class PlayerService {
|
||||
|
||||
/**
|
||||
* The cache of players.
|
||||
*/
|
||||
private final Map<UUID, Player> players = ExpiringMap.builder()
|
||||
.expiration(1, TimeUnit.HOURS)
|
||||
.expirationPolicy(ExpirationPolicy.CREATED)
|
||||
.build();
|
||||
|
||||
/**
|
||||
* The cache of player names to UUIDs.
|
||||
*/
|
||||
private final Map<String, UUID> playerNameToUUIDCache = ExpiringMap.builder()
|
||||
.expiration(1, TimeUnit.DAYS)
|
||||
.expirationPolicy(ExpirationPolicy.CREATED)
|
||||
.build();
|
||||
|
||||
private final MojangAPIService mojangAPIService;
|
||||
|
||||
public PlayerService(MojangAPIService mojangAPIService) {
|
||||
this.mojangAPIService = mojangAPIService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a player by their UUID.
|
||||
*
|
||||
* @param id the uuid or name of the player
|
||||
* @return the player or null if the player does not exist
|
||||
*/
|
||||
public Player getPlayer(String id) {
|
||||
UUID uuid = null;
|
||||
if (id.length() == 32 || id.length() == 36) { // Check if the id is a UUID
|
||||
try {
|
||||
uuid = UUID.fromString(id.length() == 32 ? UUIDUtils.addUuidDashes(id) : id);
|
||||
} catch (Exception ignored) {}
|
||||
} else { // Check if the id is a name
|
||||
uuid = playerNameToUUIDCache.get(id.toUpperCase());
|
||||
}
|
||||
|
||||
// Check if the player is cached
|
||||
if (uuid != null && players.containsKey(uuid)) {
|
||||
return players.get(uuid);
|
||||
}
|
||||
|
||||
MojangProfile profile = uuid == null ? null : mojangAPIService.getProfile(uuid.toString());
|
||||
if (profile == null) { // The player cannot be found using their UUID
|
||||
MojangUsernameToUuid apiProfile = mojangAPIService.getUuidFromUsername(id); // Get the UUID of the player using their name
|
||||
if (apiProfile == null || !apiProfile.isValid()) {
|
||||
return null;
|
||||
}
|
||||
// Get the profile of the player using their UUID
|
||||
profile = mojangAPIService.getProfile(apiProfile.getId().length() == 32 ?
|
||||
UUIDUtils.addUuidDashes(apiProfile.getId()) : apiProfile.getId());
|
||||
}
|
||||
if (profile == null) { // The player cannot be found using their name or UUID
|
||||
log.info("Player with id {} could not be found", id);
|
||||
return null;
|
||||
}
|
||||
Player player = new Player(profile);
|
||||
players.put(player.getUuid(), player);
|
||||
playerNameToUUIDCache.put(player.getName().toUpperCase(), player.getUuid());
|
||||
return player;
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
package cc.fascinated.service.pinger;
|
||||
|
||||
/**
|
||||
* @author Braydon
|
||||
* @param <T> the type of server to ping
|
||||
*/
|
||||
public interface MinecraftServerPinger<T> {
|
||||
T ping(String hostname, int port);
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
package cc.fascinated.service.pinger.impl;
|
||||
|
||||
import cc.fascinated.Main;
|
||||
import cc.fascinated.common.packet.impl.java.JavaPacketHandshakingInSetProtocol;
|
||||
import cc.fascinated.common.packet.impl.java.JavaPacketStatusInStart;
|
||||
import cc.fascinated.model.mojang.JavaServerStatusToken;
|
||||
import cc.fascinated.model.server.JavaMinecraftServer;
|
||||
import cc.fascinated.service.pinger.MinecraftServerPinger;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
|
||||
/**
|
||||
* @author Braydon
|
||||
*/
|
||||
@Log4j2(topic = "Java Pinger")
|
||||
public final class JavaMinecraftServerPinger implements MinecraftServerPinger<JavaMinecraftServer> {
|
||||
public static final JavaMinecraftServerPinger INSTANCE = new JavaMinecraftServerPinger();
|
||||
|
||||
private static final int TIMEOUT = 3000; // The timeout for the socket
|
||||
|
||||
@Override
|
||||
public JavaMinecraftServer ping(String hostname, int port) {
|
||||
log.info("Pinging {}:{}...", hostname, port);
|
||||
|
||||
// Open a socket connection to the server
|
||||
try (Socket socket = new Socket()) {
|
||||
socket.setTcpNoDelay(true);
|
||||
socket.connect(new InetSocketAddress(hostname, port), TIMEOUT);
|
||||
|
||||
// Open data streams to begin packet transaction
|
||||
try (DataInputStream inputStream = new DataInputStream(socket.getInputStream());
|
||||
DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream())) {
|
||||
// Begin handshaking with the server
|
||||
new JavaPacketHandshakingInSetProtocol(hostname, port, 47).process(inputStream, outputStream);
|
||||
|
||||
// Send the status request to the server, and await back the response
|
||||
JavaPacketStatusInStart packetStatusInStart = new JavaPacketStatusInStart();
|
||||
packetStatusInStart.process(inputStream, outputStream);
|
||||
System.out.println("packetStatusInStart.getResponse() = " + packetStatusInStart.getResponse());
|
||||
JavaServerStatusToken token = Main.GSON.fromJson(packetStatusInStart.getResponse(), JavaServerStatusToken.class);
|
||||
return new JavaMinecraftServer(hostname, port, token.getDescription());
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user