diff options
Diffstat (limited to 'src/main/java/de/hysky/skyblocker/utils')
10 files changed, 120 insertions, 54 deletions
diff --git a/src/main/java/de/hysky/skyblocker/utils/ApiUtils.java b/src/main/java/de/hysky/skyblocker/utils/ApiUtils.java new file mode 100644 index 00000000..0121f8ad --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/utils/ApiUtils.java @@ -0,0 +1,53 @@ +package de.hysky.skyblocker.utils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.JsonParser; +import com.mojang.util.UndashedUuid; + +import de.hysky.skyblocker.utils.Http.ApiResponse; +import de.hysky.skyblocker.utils.scheduler.Scheduler; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.session.Session; + +/* + * Contains only basic helpers for using Http APIs + */ +public class ApiUtils { + private static final Logger LOGGER = LoggerFactory.getLogger(ApiUtils.class); + /** + * Do not iterate over this map, it will be accessed and modified by multiple threads. + */ + private static final Object2ObjectOpenHashMap<String, String> NAME_2_UUID_CACHE = new Object2ObjectOpenHashMap<>(); + + public static void init() { + //Clear cache every 20 minutes + Scheduler.INSTANCE.scheduleCyclic(NAME_2_UUID_CACHE::clear, 24_000, true); + } + + /** + * Multithreading is to be handled by the method caller + */ + public static String name2Uuid(String name) { + Session session = MinecraftClient.getInstance().getSession(); + + if (session.getUsername().equals(name)) return UndashedUuid.toString(session.getUuidOrNull()); + if (NAME_2_UUID_CACHE.containsKey(name)) return NAME_2_UUID_CACHE.get(name); + + try (ApiResponse response = Http.sendName2UuidRequest(name)) { + if (response.ok()) { + String uuid = JsonParser.parseString(response.content()).getAsJsonObject().get("id").getAsString(); + + NAME_2_UUID_CACHE.put(name, uuid); + + return uuid; + } + } catch (Exception e) { + LOGGER.error("[Skyblocker] Name to uuid lookup failed! Name: {}", name, e); + } + + return ""; + } +} diff --git a/src/main/java/de/hysky/skyblocker/utils/Constants.java b/src/main/java/de/hysky/skyblocker/utils/Constants.java index 94eacf49..e0a5bb5a 100644 --- a/src/main/java/de/hysky/skyblocker/utils/Constants.java +++ b/src/main/java/de/hysky/skyblocker/utils/Constants.java @@ -14,7 +14,7 @@ import net.minecraft.util.Formatting; * Holds generic static constants */ public interface Constants { - String LEVEL_EMBLEMS = "\u2E15\u273F\u2741\u2E19\u03B1\u270E\u2615\u2616\u2663\u213B\u2694\u27B6\u26A1\u2604\u269A\u2693\u2620\u269B\u2666\u2660\u2764\u2727\u238A\u1360\u262C\u269D\u29C9\uA214\u32D6\u2E0E\u26A0\uA541\u3020\u30C4\u2948\u2622\u2623\u273E\u269C\u0BD0\u0A6D\u2742\u16C3\u3023\u10F6\u0444\u266A\u266B\u04C3\u26C1\u26C3\u16DD\uA03E\u1C6A\u03A3\u09EB\u2603\u2654\u26C2\u12DE"; + String LEVEL_EMBLEMS = "\u2E15\u273F\u2741\u2E19\u03B1\u270E\u2615\u2616\u2663\u213B\u2694\u27B6\u26A1\u2604\u269A\u2693\u2620\u269B\u2666\u2660\u2764\u2727\u238A\u1360\u262C\u269D\u29C9\uA214\u32D6\u2E0E\u26A0\uA541\u3020\u30C4\u2948\u2622\u2623\u273E\u269C\u0BD0\u0A6D\u2742\u16C3\u3023\u10F6\u0444\u266A\u266B\u04C3\u26C1\u26C3\u16DD\uA03E\u1C6A\u03A3\u09EB\u2603\u2654\u26C2\u0FC7\u12DE"; IntFunction<UnaryOperator<Style>> WITH_COLOR = color -> style -> style.withColor(color); Supplier<MutableText> PREFIX = () -> Text.empty() .append(Text.literal("[").formatted(Formatting.GRAY)) diff --git a/src/main/java/de/hysky/skyblocker/utils/Http.java b/src/main/java/de/hysky/skyblocker/utils/Http.java index eabb02e4..82ab6c5e 100644 --- a/src/main/java/de/hysky/skyblocker/utils/Http.java +++ b/src/main/java/de/hysky/skyblocker/utils/Http.java @@ -32,11 +32,11 @@ public class Http { .connectTimeout(Duration.ofSeconds(10)) .followRedirects(Redirect.NORMAL) .build(); - + public static String sendGetRequest(String url) throws IOException, InterruptedException { return sendCacheableGetRequest(url).content(); } - + private static ApiResponse sendCacheableGetRequest(String url) throws IOException, InterruptedException { HttpRequest request = HttpRequest.newBuilder() .GET() @@ -46,14 +46,16 @@ public class Http { .version(Version.HTTP_2) .uri(URI.create(url)) .build(); - + HttpResponse<InputStream> response = HTTP_CLIENT.send(request, BodyHandlers.ofInputStream()); InputStream decodedInputStream = getDecodedInputStream(response); + String body = new String(decodedInputStream.readAllBytes()); - - return new ApiResponse(body, response.statusCode(), getCacheStatus(response.headers())); + HttpHeaders headers = response.headers(); + + return new ApiResponse(body, response.statusCode(), getCacheStatus(headers), getAge(headers)); } - + public static HttpHeaders sendHeadRequest(String url) throws IOException, InterruptedException { HttpRequest request = HttpRequest.newBuilder() .method("HEAD", BodyPublishers.noBody()) @@ -61,15 +63,15 @@ public class Http { .version(Version.HTTP_2) .uri(URI.create(url)) .build(); - - HttpResponse<Void> response = HTTP_CLIENT.send(request, BodyHandlers.discarding()); + + HttpResponse<Void> response = HTTP_CLIENT.send(request, BodyHandlers.discarding()); return response.headers(); } - - public static String sendName2UuidRequest(String name) throws IOException, InterruptedException { - return sendGetRequest(NAME_2_UUID + name); + + public static ApiResponse sendName2UuidRequest(String name) throws IOException, InterruptedException { + return sendCacheableGetRequest(NAME_2_UUID + name); } - + /** * @param endpoint the endpoint - do not include any leading or trailing slashes * @param query the query string - use empty string if n/a @@ -78,10 +80,10 @@ public class Http { public static ApiResponse sendHypixelRequest(String endpoint, @NotNull String query) throws IOException, InterruptedException { return sendCacheableGetRequest(HYPIXEL_PROXY + endpoint + query); } - + private static InputStream getDecodedInputStream(HttpResponse<InputStream> response) { String encoding = getContentEncoding(response.headers()); - + try { switch (encoding) { case "": @@ -97,37 +99,47 @@ public class Http { throw new UncheckedIOException(e); } } - + private static String getContentEncoding(HttpHeaders headers) { return headers.firstValue("Content-Encoding").orElse(""); } - + public static String getEtag(HttpHeaders headers) { return headers.firstValue("Etag").orElse(""); } - + public static String getLastModified(HttpHeaders headers) { return headers.firstValue("Last-Modified").orElse(""); } - + /** * Returns the cache status of the resource * * @see <a href="https://developers.cloudflare.com/cache/concepts/default-cache-behavior/#cloudflare-cache-responses">Cloudflare Cache Docs</a> */ - public static String getCacheStatus(HttpHeaders headers) { + private static String getCacheStatus(HttpHeaders headers) { return headers.firstValue("CF-Cache-Status").orElse("UNKNOWN"); } - + + private static int getAge(HttpHeaders headers) { + return Integer.parseInt(headers.firstValue("Age").orElse("-1")); + } + //TODO If ever needed, we could just replace cache status with the response headers and go from there - public record ApiResponse(String content, int statusCode, String cacheStatus) { - + public record ApiResponse(String content, int statusCode, String cacheStatus, int age) implements AutoCloseable { + public boolean ok() { return statusCode == 200; } - + public boolean cached() { return cacheStatus.equals("HIT"); } + + @Override + public void close() { + //Allows for nice syntax when dealing with api requests in try catch blocks + //Maybe one day we'll have some resources to free + } } } diff --git a/src/main/java/de/hysky/skyblocker/utils/NEURepoManager.java b/src/main/java/de/hysky/skyblocker/utils/NEURepoManager.java index 6d78b3f3..870e94da 100644 --- a/src/main/java/de/hysky/skyblocker/utils/NEURepoManager.java +++ b/src/main/java/de/hysky/skyblocker/utils/NEURepoManager.java @@ -14,10 +14,12 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; +import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.List; import java.util.concurrent.CompletableFuture; +import java.util.stream.Stream; /** * Initializes the NEU repo, which contains item metadata and fairy souls location data. Clones the repo if it does not exist and checks for updates. Use {@link #runAsyncAfterLoad(Runnable)} to run code after the repo is initialized. @@ -74,8 +76,7 @@ public class NEURepoManager { CompletableFuture.runAsync(() -> { try { ItemRepository.setFilesImported(false); - File dir = NEURepoManager.LOCAL_REPO_DIR.toFile(); - recursiveDelete(dir); + recursiveDelete(NEURepoManager.LOCAL_REPO_DIR); } catch (Exception ex) { if (MinecraftClient.getInstance().player != null) MinecraftClient.getInstance().player.sendMessage(Constants.PREFIX.get().append(Text.translatable("skyblocker.updaterepository.failed")), false); @@ -86,14 +87,18 @@ public class NEURepoManager { } @SuppressWarnings("ResultOfMethodCallIgnored") - private static void recursiveDelete(File dir) { - File[] children; - if (dir.isDirectory() && !Files.isSymbolicLink(dir.toPath()) && (children = dir.listFiles()) != null) { - for (File child : children) { - recursiveDelete(child); - } + private static void recursiveDelete(Path dir) throws IOException { + if (Files.isDirectory(dir) && !Files.isSymbolicLink(dir)) { + Files.list(dir).forEach(child -> { + try { + recursiveDelete(child); + } catch (Exception e) { + LOGGER.error("[Skyblocker] Encountered an exception while deleting a file! Path: {}", child.toAbsolutePath(), e); + } + }); } - dir.delete(); + + Files.delete(dir); } /** diff --git a/src/main/java/de/hysky/skyblocker/utils/SlayerUtils.java b/src/main/java/de/hysky/skyblocker/utils/SlayerUtils.java index 0a42c6ae..2edd61f1 100644 --- a/src/main/java/de/hysky/skyblocker/utils/SlayerUtils.java +++ b/src/main/java/de/hysky/skyblocker/utils/SlayerUtils.java @@ -42,13 +42,13 @@ public class SlayerUtils { try { for (int i = 0; i < Utils.STRING_SCOREBOARD.size(); i++) { String line = Utils.STRING_SCOREBOARD.get(i); - + if (line.contains("Slay the boss!")) return true; } } catch (NullPointerException e) { LOGGER.error("[Skyblocker] Error while checking if player is in slayer", e); } - + return false; } }
\ No newline at end of file diff --git a/src/main/java/de/hysky/skyblocker/utils/Utils.java b/src/main/java/de/hysky/skyblocker/utils/Utils.java index b1a347f9..02b1637b 100644 --- a/src/main/java/de/hysky/skyblocker/utils/Utils.java +++ b/src/main/java/de/hysky/skyblocker/utils/Utils.java @@ -33,10 +33,10 @@ import java.util.List; public class Utils { private static final Logger LOGGER = LoggerFactory.getLogger(Utils.class); private static final String ALTERNATE_HYPIXEL_ADDRESS = System.getProperty("skyblocker.alternateHypixelAddress", ""); + private static final String DUNGEONS_LOCATION = "dungeon"; private static final String PROFILE_PREFIX = "Profile: "; private static boolean isOnHypixel = false; private static boolean isOnSkyblock = false; - private static boolean isInDungeons = false; private static boolean isInjected = false; /** * The profile name parsed from the player list. @@ -79,7 +79,7 @@ public class Utils { } public static boolean isInDungeons() { - return isInDungeons; + return getLocationRaw().equals(DUNGEONS_LOCATION) || FabricLoader.getInstance().isDevelopmentEnvironment(); } public static boolean isInTheRift() { @@ -164,7 +164,6 @@ public class Utils { sidebar = Collections.emptyList(); } else { isOnSkyblock = false; - isInDungeons = false; return; } } @@ -188,7 +187,6 @@ public class Utils { } else { onLeaveSkyblock(); } - isInDungeons = fabricLoader.isDevelopmentEnvironment() || isOnSkyblock && string.contains("The Catacombs"); } else if (isOnHypixel) { isOnHypixel = false; onLeaveSkyblock(); @@ -205,7 +203,6 @@ public class Utils { private static void onLeaveSkyblock() { if (isOnSkyblock) { isOnSkyblock = false; - isInDungeons = false; SkyblockEvents.LEAVE.invoker().onSkyblockLeave(); } } @@ -366,7 +363,7 @@ public class Utils { if (isOnSkyblock && message.startsWith("Profile ID: ")) { profileId = message.replace("Profile ID: ", ""); - + MuseumItemCache.tick(profileId); } diff --git a/src/main/java/de/hysky/skyblocker/utils/chat/ChatMessageListener.java b/src/main/java/de/hysky/skyblocker/utils/chat/ChatMessageListener.java index 7892445e..2c75ef0a 100644 --- a/src/main/java/de/hysky/skyblocker/utils/chat/ChatMessageListener.java +++ b/src/main/java/de/hysky/skyblocker/utils/chat/ChatMessageListener.java @@ -9,7 +9,6 @@ import de.hysky.skyblocker.skyblock.dungeon.ThreeWeirdos; import de.hysky.skyblocker.skyblock.dungeon.Trivia; import de.hysky.skyblocker.skyblock.dwarven.Fetchur; import de.hysky.skyblocker.skyblock.dwarven.Puzzler; -import de.hysky.skyblocker.skyblock.filters.*; import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents; import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; diff --git a/src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java b/src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java index 064b564c..e4cfea1b 100644 --- a/src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java +++ b/src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java @@ -42,16 +42,16 @@ public class RenderHelper { renderFilled(context, Vec3d.of(pos), ONE, colorComponents, alpha, false); } } - + private static void renderFilled(WorldRenderContext context, Vec3d pos, Vec3d dimensions, float[] colorComponents, float alpha, boolean throughWalls) { MatrixStack matrices = context.matrixStack(); Vec3d camera = context.camera().getPos(); Tessellator tessellator = RenderSystem.renderThreadTesselator(); BufferBuilder buffer = tessellator.getBuffer(); - + matrices.push(); matrices.translate(-camera.x, -camera.y, -camera.z); - + RenderSystem.setShader(GameRenderer::getPositionColorProgram); RenderSystem.setShaderColor(1f, 1f, 1f, 1f); RenderSystem.polygonOffset(-1f, -10f); @@ -61,11 +61,11 @@ public class RenderHelper { RenderSystem.enableDepthTest(); RenderSystem.depthFunc(throughWalls ? GL11.GL_ALWAYS : GL11.GL_LEQUAL); RenderSystem.disableCull(); - + buffer.begin(DrawMode.TRIANGLE_STRIP, VertexFormats.POSITION_COLOR); WorldRenderer.renderFilledBox(matrices, buffer, pos.x, pos.y, pos.z, pos.x + dimensions.x, pos.y + dimensions.y, pos.z + dimensions.z, colorComponents[0], colorComponents[1], colorComponents[2], alpha); tessellator.draw(); - + matrices.pop(); RenderSystem.polygonOffset(0f, 0f); RenderSystem.disablePolygonOffset(); diff --git a/src/main/java/de/hysky/skyblocker/utils/render/title/TitleContainerConfigScreen.java b/src/main/java/de/hysky/skyblocker/utils/render/title/TitleContainerConfigScreen.java index 19d41c91..cc80f74c 100644 --- a/src/main/java/de/hysky/skyblocker/utils/render/title/TitleContainerConfigScreen.java +++ b/src/main/java/de/hysky/skyblocker/utils/render/title/TitleContainerConfigScreen.java @@ -27,7 +27,7 @@ public class TitleContainerConfigScreen extends Screen { private float hudY = SkyblockerConfigManager.get().general.titleContainer.y; private final Screen parent; private boolean changedScale; - + protected TitleContainerConfigScreen() { this(null); } @@ -173,18 +173,18 @@ public class TitleContainerConfigScreen extends Screen { public void close() { SkyblockerConfigManager.get().general.titleContainer.x = (int) hudX; SkyblockerConfigManager.get().general.titleContainer.y = (int) hudY; - + //TODO Come up with a better, less hacky solution for this in the future (: if (parent instanceof YACLScreen yaclScreen) { ConfigCategory category = yaclScreen.config.categories().stream().filter(cat -> cat.name().getString().equals(I18n.translate("text.autoconfig.skyblocker.category.general"))).findFirst().orElseThrow(); OptionGroup group = category.groups().stream().filter(grp -> grp.name().getString().equals(I18n.translate("text.autoconfig.skyblocker.option.general.titleContainer"))).findFirst().orElseThrow(); - + Option<?> scaleOpt = group.options().get(0); - + // Refresh the value in the config with the bound value if (changedScale) scaleOpt.forgetPendingValue(); } - + SkyblockerConfigManager.save(); this.client.setScreen(parent); } diff --git a/src/main/java/de/hysky/skyblocker/utils/scheduler/Scheduler.java b/src/main/java/de/hysky/skyblocker/utils/scheduler/Scheduler.java index b254f524..139ac05e 100644 --- a/src/main/java/de/hysky/skyblocker/utils/scheduler/Scheduler.java +++ b/src/main/java/de/hysky/skyblocker/utils/scheduler/Scheduler.java @@ -28,14 +28,14 @@ public class Scheduler { protected Scheduler() { } - + /** * @see #schedule(Runnable, int, boolean) */ public void schedule(Runnable task, int delay) { schedule(task, delay, false); } - + /** * @see #scheduleCyclic(Runnable, int, boolean) */ |