Skip to content

Commit

Permalink
Fix scheduled time being early spring 1st rather than late spring 27th
Browse files Browse the repository at this point in the history
Also adds more robust handling of get request failures
  • Loading branch information
Emirlol committed Jul 1, 2024
1 parent 2e2b875 commit 3856ba8
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 13 deletions.
2 changes: 1 addition & 1 deletion src/main/java/de/hysky/skyblocker/utils/Http.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class Http {
.followRedirects(Redirect.NORMAL)
.build();

private static ApiResponse sendCacheableGetRequest(String url, @Nullable String token) throws IOException, InterruptedException {
public static ApiResponse sendCacheableGetRequest(String url, @Nullable String token) throws IOException, InterruptedException {
HttpRequest.Builder requestBuilder = HttpRequest.newBuilder()
.GET()
.header("Accept", "application/json")
Expand Down
45 changes: 33 additions & 12 deletions src/main/java/de/hysky/skyblocker/utils/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import org.apache.http.client.HttpResponseException;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.time.Instant;
import java.util.Collections;
import java.util.List;
Expand Down Expand Up @@ -78,6 +78,7 @@ public class Utils {
//This is required to prevent the location change event from being fired twice.
private static boolean locationChanged = true;
private static boolean mayorTickScheduled = false;
private static int mayorTickRetryAttempts = 0;
private static String mayor = "";

/**
Expand Down Expand Up @@ -192,9 +193,9 @@ public static String getMayor() {

public static void init() {
SkyblockEvents.JOIN.register(() -> {
long millisUntilNextYear = 446400000L - (SkyblockTime.getSkyblockMillis() % 446400000L);
if (!mayorTickScheduled) {
Scheduler.INSTANCE.scheduleCyclic(Utils::tickMayorCache, (int) millisUntilNextYear / 50 + 1);
tickMayorCache();
scheduleMayorTick();
mayorTickScheduled = true;
}
});
Expand Down Expand Up @@ -484,20 +485,40 @@ private static void resetLocRawInfo() {
location = Location.UNKNOWN;
}

private static void scheduleMayorTick() {
long currentYearMillis = SkyblockTime.getSkyblockMillis() % 446400000L; //446400000ms is 1 year, 105600000ms is the amount of time from early spring 1st to late spring 27th
// If current time is past late spring 27th, the next mayor change is at next year's spring 27th, otherwise it's at this year's spring 27th
long millisUntilNextMayorChange = currentYearMillis > 105600000L ? 446400000L - currentYearMillis + 105600000L : 105600000L - currentYearMillis;
Scheduler.INSTANCE.schedule(Utils::tickMayorCache, (int) (millisUntilNextMayorChange / 50) + 5 * 60 * 20); // 5 extra minutes to allow the cache to expire. This is a simpler than checking age and subtracting from max age and rescheduling again.
}

private static void tickMayorCache() {
CompletableFuture.supplyAsync(() -> {
try {
JsonObject json = JsonParser.parseString(Http.sendGetRequest("https://api.hypixel.net/v2/resources/skyblock/election")).getAsJsonObject();
if (json.get("success").getAsBoolean()) return json.get("mayor").getAsJsonObject().get("name").getAsString();
throw new IOException(json.get("cause").getAsString());
Http.ApiResponse response = Http.sendCacheableGetRequest("https://api.hypixel.net/v2/resources/skyblock/election");
if (!response.ok()) throw new HttpResponseException(response.statusCode(), response.content());
JsonObject json = JsonParser.parseString(response.content()).getAsJsonObject();
if (!json.get("success").getAsBoolean()) throw new RuntimeException("Request failed!"); //Can't find a more appropriate exception to throw here.
return json.get("mayor").getAsJsonObject().get("name").getAsString();
} catch (Exception e) {
LOGGER.error("[Skyblocker] Failed to get mayor status!", e);
throw new RuntimeException(e); //Wrap the exception to be handled by the exceptionally block
}
}).exceptionally(throwable -> {
LOGGER.error("[Skyblocker] Failed to get mayor status!", throwable.getCause());
if (mayorTickRetryAttempts < 5) {
int minutes = 5 * (mayorTickRetryAttempts == 0 ? 1 : 2 << mayorTickRetryAttempts - 1); //5, 10, 20, 40, 80 minutes
mayorTickRetryAttempts++;
LOGGER.warn("[Skyblocker] Retrying in {} minutes.", minutes);
Scheduler.INSTANCE.schedule(Utils::tickMayorCache, minutes * 60 * 20);
} else {
LOGGER.warn("[Skyblocker] Failed to get mayor status after 5 retries! Stopping further retries until next reboot.");
}
return "";
}).thenAccept(s -> {
if (!s.isEmpty()) {
mayor = s;
LOGGER.info("[Skyblocker] Mayor set to {}", mayor);
return ""; //Have to return a value for the thenAccept block.
}).thenAccept(result -> {
if (!result.isEmpty()) {
mayor = result;
LOGGER.info("[Skyblocker] Mayor set to {}.", mayor);
scheduleMayorTick(); //Ends up as a cyclic task with finer control over scheduled time
}
});
}
Expand Down

0 comments on commit 3856ba8

Please sign in to comment.