Skip to content

Commit

Permalink
Replace API keys with Polyfrost ursa-minor API
Browse files Browse the repository at this point in the history
  • Loading branch information
Wyvest committed Jul 15, 2023
1 parent 55fb476 commit ddab1b1
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 72 deletions.
24 changes: 0 additions & 24 deletions src/main/java/cc/woverflow/hytils/command/HytilsCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,13 @@
import cc.polyfrost.oneconfig.utils.commands.annotations.Description;
import cc.polyfrost.oneconfig.utils.commands.annotations.Main;
import cc.polyfrost.oneconfig.utils.commands.annotations.SubCommand;
import cc.polyfrost.oneconfig.utils.hypixel.HypixelUtils;
import cc.woverflow.hytils.HytilsReborn;
import cc.woverflow.hytils.command.parser.GEXPType;
import cc.woverflow.hytils.command.parser.GEXPTypeParser;
import cc.woverflow.hytils.command.parser.WinstreakType;
import cc.woverflow.hytils.command.parser.WinstreakTypeParser;
import cc.woverflow.hytils.config.HytilsConfig;
import cc.woverflow.hytils.util.HypixelAPIUtils;
import com.mojang.authlib.GameProfile;
import net.minecraft.util.EnumChatFormatting;
import org.jetbrains.annotations.Nullable;

import java.util.Locale;
Expand All @@ -55,10 +52,6 @@ private void handleDefault() {
@SuppressWarnings("SameParameterValue")
private void gexp(@Description("username") @Nullable GameProfile player, @Description("type") @Nullable GEXPType type) {
Multithreading.runAsync(() -> {
if (HytilsConfig.apiKey.isEmpty() || !HypixelUtils.INSTANCE.isValidKey(HytilsConfig.apiKey)) {
HytilsReborn.INSTANCE.sendMessage(EnumChatFormatting.RED + "You need to provide a valid API key to run this command! Type /api new to autoset a key.");
return;
}
if (player != null) {
if (type == null) {
if (HypixelAPIUtils.getGEXP(player.getName())) {
Expand Down Expand Up @@ -112,10 +105,6 @@ private void gexp(@Description("username") @Nullable GameProfile player, @Descri
@SuppressWarnings("SameParameterValue")
private void winstreak(@Description("username") @Nullable GameProfile player, @Description("type") @Nullable WinstreakType gamemode) {
Multithreading.runAsync(() -> {
if (HytilsConfig.apiKey.isEmpty() || !HypixelUtils.INSTANCE.isValidKey(HytilsConfig.apiKey)) {
HytilsReborn.INSTANCE.sendMessage(EnumChatFormatting.RED + "You need to provide a valid API key to run this command! Type /api new to autoset a key.");
return;
}
if (player != null) {
if (gamemode != null) {
if (HypixelAPIUtils.getWinstreak(player.getName(), gamemode.name())) {
Expand Down Expand Up @@ -154,17 +143,4 @@ private void winstreak(@Description("username") @Nullable GameProfile player, @D
}
});
}

@SubCommand(description = "Sets your API key.", aliases = "setkey")
private static void key(@Description("API Key") String apiKey) {
Multithreading.runAsync(() -> {
if (HypixelUtils.INSTANCE.isValidKey(apiKey)) {
HytilsConfig.apiKey = apiKey;
HytilsReborn.INSTANCE.getConfig().save();
HytilsReborn.INSTANCE.sendMessage(EnumChatFormatting.GREEN + "Saved API key successfully!");
} else {
HytilsReborn.INSTANCE.sendMessage(EnumChatFormatting.RED + "Invalid API key! Please try again.");
}
});
}
}
11 changes: 0 additions & 11 deletions src/main/java/cc/woverflow/hytils/config/HytilsConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,6 @@
@SuppressWarnings("unused")
public class HytilsConfig extends Config {

// API

@Text(
name = "API Key",
description = "Automatically get the API Key from /api new.",
category = "API",
secure = true
)
@HypixelKey
public static String apiKey = "";

// Automatic

@Switch(
Expand Down
183 changes: 146 additions & 37 deletions src/main/java/cc/woverflow/hytils/util/HypixelAPIUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,38 +22,126 @@
import cc.polyfrost.oneconfig.events.event.Stage;
import cc.polyfrost.oneconfig.events.event.TickEvent;
import cc.polyfrost.oneconfig.libs.eventbus.Subscribe;
import cc.polyfrost.oneconfig.utils.JsonUtils;
import cc.polyfrost.oneconfig.utils.NetworkUtils;
import cc.polyfrost.oneconfig.utils.hypixel.HypixelUtils;
import cc.polyfrost.oneconfig.utils.hypixel.LocrawInfo;
import cc.woverflow.hytils.HytilsReborn;
import cc.woverflow.hytils.config.HytilsConfig;
import cc.woverflow.hytils.handlers.cache.HeightHandler;
import cc.woverflow.hytils.util.ranks.RankType;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.exceptions.AuthenticationException;
import net.minecraft.client.Minecraft;
import net.minecraft.util.EnumChatFormatting;
import org.apache.commons.io.IOUtils;
import org.jetbrains.annotations.Nullable;

import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
import java.time.Duration;
import java.time.Instant;
import java.util.*;

public class HypixelAPIUtils {
private static final String[] rankValues = {"rank", "monthlyPackageRank", "newPackageRank", "packageRank"};
public static String gexp;
public static String winstreak;
public static LocrawInfo locraw;
@Nullable
private static String token;
@Nullable
private static Instant expiry;
@Nullable
private static String username;
@Nullable
private static String serverId;
private int ticks = 0;
private static final String[] rankValues = {"rank", "monthlyPackageRank", "newPackageRank", "packageRank"};

private static String getCurrentESTTime() {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("EST"));
return simpleDateFormat.format(new Date(System.currentTimeMillis()));
}

private static boolean authorize() {
String serverId = UUID.randomUUID().toString();
try {
GameProfile profile = Minecraft.getMinecraft().getSession().getProfile();
String token = Minecraft.getMinecraft().getSession().getToken();
Minecraft.getMinecraft().getSessionService().joinServer(profile, token, serverId);
username = profile.getName();
HypixelAPIUtils.serverId = serverId;
} catch (AuthenticationException e) {
e.printStackTrace();
return false;
}
return true;
}

private static JsonObject getJsonObjectAuth(String url) {
HttpURLConnection connection = setupConnection(url);
if (connection == null) return null;
try (InputStreamReader input = new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8)) {
JsonElement element = JsonUtils.parseString(IOUtils.toString(input));
if (username != null && serverId != null) {
token = connection.getHeaderField("x-ursa-token");
expiry = calculateExpiry(connection.getHeaderField("x-ursa-expires"));
username = null;
serverId = null;
}
if (element == null || !element.isJsonObject()) {
return null;
}
return element.getAsJsonObject();
} catch (IOException e) {
return null;
}
}

private static Instant calculateExpiry(String expiry) {
try {
long expiryLong = Long.parseLong(expiry);
return Instant.ofEpochMilli(expiryLong);
} catch (NumberFormatException e) {
return Instant.now().plus(Duration.ofMinutes(55));
}
}

private static HttpURLConnection setupConnection(String url) {
HttpURLConnection connection;
try {
connection = ((HttpURLConnection) new URL(url).openConnection());
connection.setRequestMethod("GET");
connection.setUseCaches(false);
connection.addRequestProperty("User-Agent", "Hytils-Reborn/" + HytilsReborn.VERSION);
connection.setReadTimeout(5000);
connection.setConnectTimeout(5000);
connection.setDoOutput(true);
if (token != null && expiry != null && expiry.isAfter(Instant.now())) {
connection.addRequestProperty("x-ursa-token", token);
} else {
token = null;
expiry = null;
if (authorize()) {
connection.addRequestProperty("x-ursa-username", username);
connection.addRequestProperty("x-ursa-serverid", serverId);
} else {
return null;
}
}
return connection;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}


/**
* Gets the player's GEXP and stores it in a variable.
Expand All @@ -63,7 +151,11 @@ private static String getCurrentESTTime() {
public static boolean getGEXP() {
String gexp = null;
String uuid = Minecraft.getMinecraft().thePlayer.getGameProfile().getId().toString().replace("-", "");
JsonArray guildMembers = NetworkUtils.getJsonElement("https://api.hypixel.net/guild?key=" + HytilsConfig.apiKey + ";player=" + uuid).getAsJsonObject().getAsJsonObject("guild").getAsJsonArray("members");
JsonObject jsonObject = getJsonObjectAuth("https://api.polyfrost.cc/ursa/v1/hypixel/guild/" + uuid);
if (jsonObject == null) {
return false;
}
JsonArray guildMembers = jsonObject.getAsJsonObject("guild").getAsJsonArray("members");
for (JsonElement e : guildMembers) {
if (e.getAsJsonObject().get("uuid").getAsString().equals(uuid)) {
gexp = Integer.toString(e.getAsJsonObject().getAsJsonObject("expHistory").get(getCurrentESTTime()).getAsInt());
Expand All @@ -84,7 +176,11 @@ public static boolean getGEXP() {
public static boolean getGEXP(String username) {
String gexp = null;
String uuid = getUUID(username);
JsonArray guildMembers = NetworkUtils.getJsonElement("https://api.hypixel.net/guild?key=" + HytilsConfig.apiKey + ";player=" + uuid).getAsJsonObject().getAsJsonObject("guild").getAsJsonArray("members");
JsonObject jsonObject = getJsonObjectAuth("https://api.polyfrost.cc/ursa/v1/hypixel/guild/" + uuid);
if (jsonObject == null) {
return false;
}
JsonArray guildMembers = jsonObject.getAsJsonObject("guild").getAsJsonArray("members");
for (JsonElement e : guildMembers) {
if (e.getAsJsonObject().get("uuid").getAsString().equals(uuid)) {
gexp = Integer.toString(e.getAsJsonObject().getAsJsonObject("expHistory").get(getCurrentESTTime()).getAsInt());
Expand All @@ -104,7 +200,11 @@ public static boolean getGEXP(String username) {
public static boolean getWeeklyGEXP() {
String gexp = null;
String uuid = Minecraft.getMinecraft().thePlayer.getGameProfile().getId().toString().replace("-", "");
JsonArray guildMembers = NetworkUtils.getJsonElement("https://api.hypixel.net/guild?key=" + HytilsConfig.apiKey + ";player=" + uuid).getAsJsonObject().getAsJsonObject("guild").getAsJsonArray("members");
JsonObject jsonObject = getJsonObjectAuth("https://api.polyfrost.cc/ursa/v1/hypixel/guild/" + uuid);
if (jsonObject == null) {
return false;
}
JsonArray guildMembers = jsonObject.getAsJsonObject("guild").getAsJsonArray("members");
for (JsonElement e : guildMembers) {
if (e.getAsJsonObject().get("uuid").getAsString().equals(uuid)) {
int addGEXP = 0;
Expand All @@ -129,7 +229,11 @@ public static boolean getWeeklyGEXP() {
public static boolean getWeeklyGEXP(String username) {
String gexp = null;
String uuid = getUUID(username);
JsonArray guildMembers = NetworkUtils.getJsonElement("https://api.hypixel.net/guild?key=" + HytilsConfig.apiKey + ";player=" + uuid).getAsJsonObject().getAsJsonObject("guild").getAsJsonArray("members");
JsonObject jsonObject = getJsonObjectAuth("https://api.polyfrost.cc/ursa/v1/hypixel/guild/" + uuid);
if (jsonObject == null) {
return false;
}
JsonArray guildMembers = jsonObject.getAsJsonObject("guild").getAsJsonArray("members");
for (JsonElement e : guildMembers) {
if (e.getAsJsonObject().get("uuid").getAsString().equals(uuid)) {
int addGEXP = 0;
Expand All @@ -152,8 +256,11 @@ public static boolean getWeeklyGEXP(String username) {
*/
public static boolean getWinstreak() {
String uuid = Minecraft.getMinecraft().thePlayer.getGameProfile().getId().toString().replace("-", "");
JsonObject playerStats =
NetworkUtils.getJsonElement("https://api.hypixel.net/player?key=" + HytilsConfig.apiKey + ";uuid=" + uuid).getAsJsonObject().getAsJsonObject("player").getAsJsonObject("stats");
JsonObject jsonObject = getJsonObjectAuth("https://api.polyfrost.cc/ursa/v1/hypixel/player/" + uuid);
if (jsonObject == null) {
return false;
}
JsonObject playerStats = jsonObject.getAsJsonObject("player").getAsJsonObject("stats");
if (locraw != null) {
switch (locraw.getGameType()) {
case BEDWARS:
Expand Down Expand Up @@ -193,8 +300,11 @@ public static boolean getWinstreak() {
*/
public static boolean getWinstreak(String username) {
String uuid = getUUID(username);
JsonObject playerStats =
NetworkUtils.getJsonElement("https://api.hypixel.net/player?key=" + HytilsConfig.apiKey + ";uuid=" + uuid).getAsJsonObject().getAsJsonObject("player").getAsJsonObject("stats");
JsonObject jsonObject = getJsonObjectAuth("https://api.polyfrost.cc/ursa/v1/hypixel/player/" + uuid);
if (jsonObject == null) {
return false;
}
JsonObject playerStats = jsonObject.getAsJsonObject("player").getAsJsonObject("stats");
if (locraw != null) {
switch (locraw.getGameType()) {
case BEDWARS:
Expand Down Expand Up @@ -235,8 +345,11 @@ public static boolean getWinstreak(String username) {
*/
public static boolean getWinstreak(String username, String game) {
String uuid = getUUID(username);
JsonObject playerStats =
NetworkUtils.getJsonElement("https://api.hypixel.net/player?key=" + HytilsConfig.apiKey + ";uuid=" + uuid).getAsJsonObject().getAsJsonObject("player").getAsJsonObject("stats");
JsonObject jsonObject = getJsonObjectAuth("https://api.polyfrost.cc/ursa/v1/hypixel/player/" + uuid);
if (jsonObject == null) {
return false;
}
JsonObject playerStats = jsonObject.getAsJsonObject("player").getAsJsonObject("stats");
if (game != null) {
switch (game.toLowerCase(Locale.ENGLISH)) {
case "bedwars":
Expand Down Expand Up @@ -275,20 +388,21 @@ public static boolean getWinstreak(String username, String game) {
* @return Player rank, RankType.UNKNOWN if the player does not exist or the API key is empty
*/
public static RankType getRank(String username) {
if (!HytilsConfig.apiKey.isEmpty() && HypixelUtils.INSTANCE.isValidKey(HytilsConfig.apiKey)) {
String uuid = getUUID(username);
try {
JsonObject playerRank =
NetworkUtils.getJsonElement("https://api.hypixel.net/player?key=" + HytilsConfig.apiKey + ";uuid=" + uuid).getAsJsonObject().getAsJsonObject("player");
for (String value : rankValues) {
if (playerRank.has(value) && !playerRank.get(value).getAsString().matches("NONE|NORMAL")) {
return RankType.getRank(playerRank.get(value).getAsString());
}
String uuid = getUUID(username);
try {
JsonObject jsonObject = getJsonObjectAuth("https://api.polyfrost.cc/ursa/v1/hypixel/player/" + uuid);
if (jsonObject == null) {
return RankType.UNKNOWN;
}
JsonObject playerRank = jsonObject.getAsJsonObject("player");
for (String value : rankValues) {
if (playerRank.has(value) && !playerRank.get(value).getAsString().matches("NONE|NORMAL")) {
return RankType.getRank(playerRank.get(value).getAsString());
}
return RankType.NON;
} catch (Exception e) {
e.printStackTrace();
}
return RankType.NON;
} catch (Exception e) {
e.printStackTrace();
}
return RankType.UNKNOWN;
}
Expand All @@ -300,19 +414,14 @@ public static RankType getRank(String username) {
*/
public static String getUUID(String username) {
try {
JsonObject uuidResponse =
NetworkUtils.getJsonElement("https://api.mojang.com/users/profiles/minecraft/" + username).getAsJsonObject();
JsonObject uuidResponse = NetworkUtils.getJsonElement("https://api.mojang.com/users/profiles/minecraft/" + username).getAsJsonObject();
if (uuidResponse.has("error")) {
HytilsReborn.INSTANCE.sendMessage(
EnumChatFormatting.RED + "Failed with error: " + uuidResponse.get("reason").getAsString()
);
HytilsReborn.INSTANCE.sendMessage(EnumChatFormatting.RED + "Failed with error: " + uuidResponse.get("reason").getAsString());
return null;
}
return uuidResponse.get("id").getAsString();
} catch (Exception e) {
HytilsReborn.INSTANCE.sendMessage(
EnumChatFormatting.RED + "Failed to fetch " + username + "'s data. Please make sure this user exists."
);
HytilsReborn.INSTANCE.sendMessage(EnumChatFormatting.RED + "Failed to fetch " + username + "'s data. Please make sure this user exists.");
return null;
}
}
Expand Down

0 comments on commit ddab1b1

Please sign in to comment.