Skip to content

Commit

Permalink
Hypixel Api Proxy + Profile Id Caching
Browse files Browse the repository at this point in the history
  • Loading branch information
AzureAaron committed Oct 25, 2023
1 parent fe1f8bc commit 0106d03
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 5 deletions.
48 changes: 44 additions & 4 deletions src/main/java/de/hysky/skyblocker/utils/Http.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.io.UncheckedIOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpClient.Redirect;
import java.net.http.HttpClient.Version;
import java.net.http.HttpHeaders;
import java.net.http.HttpRequest;
Expand All @@ -15,19 +16,28 @@
import java.util.zip.GZIPInputStream;
import java.util.zip.InflaterInputStream;

import org.jetbrains.annotations.NotNull;

import de.hysky.skyblocker.SkyblockerMod;
import net.minecraft.SharedConstants;

/**
* @implNote All http requests are sent using HTTP 2
*/
public class Http {
private static final String NAME_2_UUID = "https://api.minecraftservices.com/minecraft/profile/lookup/name/";
private static final String HYPIXEL_PROXY = "https://api.azureaaron.net/hypixel/";
private static final String USER_AGENT = "Skyblocker/" + SkyblockerMod.VERSION + " (" + SharedConstants.getGameVersion().getName() + ")";
private static final HttpClient HTTP_CLIENT = HttpClient.newBuilder()
.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()
.header("Accept", "application/json")
Expand All @@ -41,7 +51,7 @@ public static String sendGetRequest(String url) throws IOException, InterruptedE
InputStream decodedInputStream = getDecodedInputStream(response);
String body = new String(decodedInputStream.readAllBytes());

return body;
return new ApiResponse(body, getCacheStatus(response.headers()));
}

public static HttpHeaders sendHeadRequest(String url) throws IOException, InterruptedException {
Expand All @@ -56,8 +66,21 @@ public static HttpHeaders sendHeadRequest(String url) throws IOException, Interr
return response.headers();
}

public static String sendName2UuidRequest(String name) throws IOException, InterruptedException {
return sendGetRequest(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
* @return the requested data with zero pre-processing applied
*/
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);
String encoding = getContentEncoding(response.headers());

try {
switch (encoding) {
Expand All @@ -75,8 +98,8 @@ private static InputStream getDecodedInputStream(HttpResponse<InputStream> respo
}
}

private static String getContentEncoding(HttpResponse<InputStream> response) {
return response.headers().firstValue("Content-Encoding").orElse("");
private static String getContentEncoding(HttpHeaders headers) {
return headers.firstValue("Content-Encoding").orElse("");
}

public static String getEtag(HttpHeaders headers) {
Expand All @@ -86,4 +109,21 @@ public static String getEtag(HttpHeaders headers) {
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) {
return headers.firstValue("CF-Cache-Status").orElse("UNKNOWN");
}

//TODO If ever needed, we could just replace cache status with the response headers and go from there
public record ApiResponse(String content, String cacheStatus) {

public boolean cached() {
return cacheStatus.equals("HIT");
}
}
}
14 changes: 13 additions & 1 deletion src/main/java/de/hysky/skyblocker/utils/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ public class Utils {
@NotNull
private static String profile = "";
@NotNull
private static String profileId = "";
@NotNull
private static String server = "";
@NotNull
private static String gameType = "";
Expand Down Expand Up @@ -88,6 +90,11 @@ public static boolean isInjected() {
public static String getProfile() {
return profile;
}

@NotNull
public static String getProfileId() {
return profileId;
}

/**
* @return the server parsed from /locraw.
Expand Down Expand Up @@ -323,7 +330,7 @@ private static void updateLocRaw() {
}

/**
* Parses the /locraw reply from the server
* Parses the /locraw reply from the server and updates the players profile id
*
* @return not display the message in chat is the command is sent by the mod
*/
Expand All @@ -349,6 +356,11 @@ public static boolean onChatMessage(Text text, boolean overlay) {
return shouldFilter;
}
}

if (isOnSkyblock && message.startsWith("Profile ID: ")) {
profileId = message.replace("Profile ID: ", "");
}

return true;
}

Expand Down

0 comments on commit 0106d03

Please sign in to comment.