Throw MojangApiException and IOException in HeadTexture#of and SkullBuilder constructor

Implements #54
This commit is contained in:
NichtStudioCode 2023-10-28 13:40:05 +02:00
parent 659e9596fc
commit f029914abd
2 changed files with 49 additions and 22 deletions

@ -17,7 +17,9 @@ import org.jetbrains.annotations.Nullable;
import xyz.xenondevs.inventoryaccess.util.ReflectionRegistry;
import xyz.xenondevs.inventoryaccess.util.ReflectionUtils;
import xyz.xenondevs.invui.util.MojangApiUtils;
import xyz.xenondevs.invui.util.MojangApiUtils.MojangApiException;
import java.io.IOException;
import java.io.Serializable;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
@ -31,8 +33,10 @@ public final class SkullBuilder extends AbstractItemBuilder<SkullBuilder> {
* Create a {@link SkullBuilder} of a {@link Player Player's} {@link UUID}.
*
* @param uuid The {@link UUID} of the skull owner.
* @throws MojangApiException If the Mojang API returns an error.
* @throws IOException If an I/O error occurs.
*/
public SkullBuilder(@NotNull UUID uuid) {
public SkullBuilder(@NotNull UUID uuid) throws MojangApiException, IOException {
this(HeadTexture.of(uuid));
}
@ -40,8 +44,10 @@ public final class SkullBuilder extends AbstractItemBuilder<SkullBuilder> {
* Create a {@link SkullBuilder} with the {@link Player Player's} username.
*
* @param username The username of the skull owner.
* @throws MojangApiException If the Mojang API returns an error.
* @throws IOException If an I/O error occurs.
*/
public SkullBuilder(@NotNull String username) {
public SkullBuilder(@NotNull String username) throws MojangApiException, IOException {
this(HeadTexture.of(username));
}
@ -128,9 +134,11 @@ public final class SkullBuilder extends AbstractItemBuilder<SkullBuilder> {
*
* @param offlinePlayer The skull owner.
* @return The {@link HeadTexture} of that player.
* @throws MojangApiException If the Mojang API returns an error.
* @throws IOException If an I/O error occurs.
* @see HeadTexture#of(UUID)
*/
public static HeadTexture of(@NotNull OfflinePlayer offlinePlayer) {
public static @NotNull HeadTexture of(@NotNull OfflinePlayer offlinePlayer) throws MojangApiException, IOException {
return of(offlinePlayer.getUniqueId());
}
@ -144,20 +152,28 @@ public final class SkullBuilder extends AbstractItemBuilder<SkullBuilder> {
*
* @param playerName The username of the player.
* @return The {@link HeadTexture} of that player.
* @throws MojangApiException If the Mojang API returns an error.
* @throws IOException If an I/O error occurs.
* @see HeadTexture#of(UUID)
*/
@SuppressWarnings("deprecation")
public static HeadTexture of(@NotNull String playerName) {
public static @NotNull HeadTexture of(@NotNull String playerName) throws MojangApiException, IOException {
if (Bukkit.getServer().getOnlineMode()) {
// if the server is in online mode, the Minecraft UUID cache (usercache.json) can be used
return of(Bukkit.getOfflinePlayer(playerName).getUniqueId());
} else {
// the server isn't in online mode - the UUID has to be retrieved from the Mojang API
try {
return of(uuidCache.get(playerName, () -> MojangApiUtils.getCurrentUUID(playerName)));
return of(uuidCache.get(playerName, () -> MojangApiUtils.getCurrentUuid(playerName)));
} catch (ExecutionException e) {
e.printStackTrace();
return null;
Throwable cause = e.getCause();
if (cause instanceof MojangApiException) {
throw (MojangApiException) cause;
} else if (cause instanceof IOException) {
throw (IOException) cause;
} else {
throw new RuntimeException(cause);
}
}
}
}
@ -169,13 +185,21 @@ public final class SkullBuilder extends AbstractItemBuilder<SkullBuilder> {
*
* @param uuid The {@link UUID} of the skull owner.
* @return The {@link HeadTexture} of that player.
* @throws MojangApiException If the Mojang API returns an error.
* @throws IOException If an I/O error occurs.
*/
public static HeadTexture of(@NotNull UUID uuid) {
public static @NotNull HeadTexture of(@NotNull UUID uuid) throws MojangApiException, IOException {
try {
return new HeadTexture(textureCache.get(uuid, () -> MojangApiUtils.getSkinData(uuid, false)[0]));
} catch (ExecutionException e) {
e.printStackTrace();
return null;
Throwable cause = e.getCause();
if (cause instanceof MojangApiException) {
throw (MojangApiException) cause;
} else if (cause instanceof IOException) {
throw (IOException) cause;
} else {
throw new RuntimeException(cause);
}
}
}

@ -10,13 +10,12 @@ import java.io.Reader;
import java.net.URL;
import java.util.UUID;
@SuppressWarnings("deprecation")
public class MojangApiUtils {
private static final String SKIN_DATA_URL = "https://sessionserver.mojang.com/session/minecraft/profile/%s?unsigned=%s";
private static final String NAME_AT_TIME_URL = "https://api.mojang.com/users/profiles/minecraft/%s?at=%s";
public static String[] getSkinData(UUID uuid, boolean requestSignature) throws IOException {
public static String[] getSkinData(UUID uuid, boolean requestSignature) throws MojangApiException, IOException {
String url = String.format(SKIN_DATA_URL, uuid, !requestSignature);
Reader reader = new InputStreamReader(new URL(url).openConnection().getInputStream());
JsonObject jsonObject = new JsonParser().parse(reader).getAsJsonObject();
@ -33,11 +32,11 @@ public class MojangApiUtils {
return null;
}
public static UUID getCurrentUUID(String name) throws IOException {
public static UUID getCurrentUuid(String name) throws MojangApiException, IOException {
return getUuidAtTime(name, System.currentTimeMillis() / 1000);
}
public static UUID getUuidAtTime(String name, long timestamp) throws IOException {
public static UUID getUuidAtTime(String name, long timestamp) throws MojangApiException, IOException {
String url = String.format(NAME_AT_TIME_URL, name, timestamp);
Reader reader = new InputStreamReader(new URL(url).openConnection().getInputStream());
JsonObject jsonObject = new JsonParser().parse(reader).getAsJsonObject();
@ -56,17 +55,21 @@ public class MojangApiUtils {
}
private static void checkForError(JsonObject jsonObject) throws MojangApiException {
if (jsonObject.has("error") && jsonObject.has("errorMessage")) {
if (jsonObject.has("errorMessage"))
throw new MojangApiException(jsonObject.get("errorMessage").getAsString());
else throw new MojangApiException("");
}
if (jsonObject.has("error"))
throw new MojangApiException(jsonObject);
}
public static class MojangApiException extends IOException {
public static class MojangApiException extends Exception {
public MojangApiException(String message) {
super(message);
private final JsonObject response;
public MojangApiException(JsonObject response) {
super(response.has("errorMessage") ? response.get("errorMessage").getAsString() : "");
this.response = response;
}
public JsonObject getResponse() {
return response;
}
}