From 427402e8c65a78621e365e5921d18d66917e00e4 Mon Sep 17 00:00:00 2001 From: Lorenz Date: Sat, 20 Aug 2022 02:25:39 +0200 Subject: adding support for grabbing the api key from other mods: neu, cow, dsm, dg, st, soopy and sbe --- .../java/at/hannibal2/skyhanni/SkyHanniMod.java | 6 +- .../java/at/hannibal2/skyhanni/data/ApiData.kt | 90 ------------- .../at/hannibal2/skyhanni/data/ApiKeyGrabber.kt | 141 +++++++++++++++++++++ .../java/at/hannibal2/skyhanni/data/OtherMod.kt | 42 ++++++ .../java/at/hannibal2/skyhanni/utils/APIUtil.kt | 21 ++- 5 files changed, 203 insertions(+), 97 deletions(-) delete mode 100644 src/main/java/at/hannibal2/skyhanni/data/ApiData.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/data/ApiKeyGrabber.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/data/OtherMod.kt diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java index 35ed2eba9..ed0d3812c 100644 --- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java +++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java @@ -2,7 +2,7 @@ package at.hannibal2.skyhanni; import at.hannibal2.skyhanni.config.Features; import at.hannibal2.skyhanni.config.gui.commands.Commands; -import at.hannibal2.skyhanni.data.ApiData; +import at.hannibal2.skyhanni.data.ApiKeyGrabber; import at.hannibal2.skyhanni.data.HypixelData; import at.hannibal2.skyhanni.data.ItemRenderBackground; import at.hannibal2.skyhanni.data.ScoreboardData; @@ -54,7 +54,7 @@ public class SkyHanniMod { public static Features feature; private File configFile; - private final Gson gson = new GsonBuilder().setPrettyPrinting().excludeFieldsWithoutExposeAnnotation().create(); + public static final Gson gson = new GsonBuilder().setPrettyPrinting().excludeFieldsWithoutExposeAnnotation().create(); public static File configDirectory; public static RepoManager repo; @@ -67,7 +67,7 @@ public class SkyHanniMod { registerEvent(new HypixelData()); registerEvent(new DungeonData()); registerEvent(new ScoreboardData()); - registerEvent(new ApiData()); + registerEvent(new ApiKeyGrabber()); registerEvent(new SeaCreatureManager()); registerEvent(new ItemRenderBackground()); diff --git a/src/main/java/at/hannibal2/skyhanni/data/ApiData.kt b/src/main/java/at/hannibal2/skyhanni/data/ApiData.kt deleted file mode 100644 index 9e47d5d0f..000000000 --- a/src/main/java/at/hannibal2/skyhanni/data/ApiData.kt +++ /dev/null @@ -1,90 +0,0 @@ -package at.hannibal2.skyhanni.data - -import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.events.LorenzChatEvent -import at.hannibal2.skyhanni.events.ProfileApiDataLoadedEvent -import at.hannibal2.skyhanni.events.ProfileJoinEvent -import at.hannibal2.skyhanni.utils.APIUtil -import at.hannibal2.skyhanni.utils.LorenzUtils -import net.minecraft.client.Minecraft -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent - -class ApiData { - - private var currentProfileName = "" - - @SubscribeEvent - fun onStatusBar(event: LorenzChatEvent) { - val message = event.message - if (message.startsWith("§aYour new API key is §r§b")) { - SkyHanniMod.feature.hidden.apiKey = message.substring(26) - LorenzUtils.chat("§b[SkyHanni] A new API Key has been detected and installed") - - if (currentProfileName != "") { - updateApiData() - } - } - } - - @SubscribeEvent - fun onStatusBar(event: ProfileJoinEvent) { - currentProfileName = event.name - updateApiData() - } - - private fun updateApiData() { - val uuid = Minecraft.getMinecraft().thePlayer.uniqueID.toString().replace("-", "") - - val apiKey = SkyHanniMod.feature.hidden.apiKey - - if (apiKey.isEmpty()) { - LorenzUtils.error("SkyHanni has no API Key set. Type /api new to reload.") - return - } - - val url = "https://api.hypixel.net/player?key=$apiKey&uuid=$uuid" - - val jsonObject = APIUtil.getJSONResponse(url) - - if (!jsonObject["success"].asBoolean) { - val cause = jsonObject["cause"].asString - if (cause == "Invalid API key") { - LorenzUtils.error("SkyHanni got an API error: Invalid API key! Type /api new to reload.") - return - } else { - throw RuntimeException("API error for url '$url': $cause") - } - } - - val player = jsonObject["player"].asJsonObject - val stats = player["stats"].asJsonObject - val skyblock = stats["SkyBlock"].asJsonObject - val profiles = skyblock["profiles"].asJsonObject - for (entry in profiles.entrySet()) { - val asJsonObject = entry.value.asJsonObject - val name = asJsonObject["cute_name"].asString - val profileId = asJsonObject["profile_id"].asString - if (currentProfileName == name.lowercase()) { - loadProfile(uuid, profileId) - return - } - } - } - - private fun loadProfile(playerUuid: String, profileId: String) { - val apiKey = SkyHanniMod.feature.hidden.apiKey - val url = "https://api.hypixel.net/skyblock/profile?key=$apiKey&profile=$profileId" - - val jsonObject = APIUtil.getJSONResponse(url) - - val profile = jsonObject["profile"].asJsonObject - val members = profile["members"].asJsonObject - for (entry in members.entrySet()) { - if (entry.key == playerUuid) { - val profileData = entry.value.asJsonObject - ProfileApiDataLoadedEvent(profileData).postAndCatch() - - } - } - } -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/data/ApiKeyGrabber.kt b/src/main/java/at/hannibal2/skyhanni/data/ApiKeyGrabber.kt new file mode 100644 index 000000000..c3a7dada5 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/data/ApiKeyGrabber.kt @@ -0,0 +1,141 @@ +package at.hannibal2.skyhanni.data + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.events.ProfileApiDataLoadedEvent +import at.hannibal2.skyhanni.events.ProfileJoinEvent +import at.hannibal2.skyhanni.utils.APIUtil +import at.hannibal2.skyhanni.utils.LorenzUtils +import net.minecraft.client.Minecraft +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import java.io.File + +class ApiKeyGrabber { + + private var currentProfileName = "" + + @SubscribeEvent + fun onStatusBar(event: LorenzChatEvent) { + val message = event.message + if (message.startsWith("§aYour new API key is §r§b")) { + SkyHanniMod.feature.hidden.apiKey = message.substring(26) + LorenzUtils.chat("§b[SkyHanni] A new API Key has been detected and installed") + + if (currentProfileName != "") { + updateApiData() + } + } + } + + @SubscribeEvent + fun onStatusBar(event: ProfileJoinEvent) { + currentProfileName = event.name + updateApiData() + } + + private fun updateApiData() { + val uuid = Minecraft.getMinecraft().thePlayer.uniqueID.toString().replace("-", "") + + var apiKey = SkyHanniMod.feature.hidden.apiKey + if (!verifyKey(apiKey)) { + LorenzUtils.chat("§c[SkyHanni] Invalid api key detected, deleting it!") + apiKey = "" + SkyHanniMod.feature.hidden.apiKey = "" + } + + if (apiKey.isEmpty()) { + readApiKeyFromOtherMods() + apiKey = SkyHanniMod.feature.hidden.apiKey + if (apiKey.isEmpty()) { + LorenzUtils.warning("SkyHanni has no API Key set. Type /api new to reload.") + return + } + } + + val url = "https://api.hypixel.net/player?key=$apiKey&uuid=$uuid" + + val jsonObject = APIUtil.getJSONResponse(url) + + if (!jsonObject["success"].asBoolean) { + val cause = jsonObject["cause"].asString + if (cause == "Invalid API key") { + LorenzUtils.error("SkyHanni got an API error: Invalid API key! Type /api new to reload.") + return + } else { + throw RuntimeException("API error for url '$url': $cause") + } + } + + val player = jsonObject["player"].asJsonObject + val stats = player["stats"].asJsonObject + val skyblock = stats["SkyBlock"].asJsonObject + val profiles = skyblock["profiles"].asJsonObject + for (entry in profiles.entrySet()) { + val asJsonObject = entry.value.asJsonObject + val name = asJsonObject["cute_name"].asString + val profileId = asJsonObject["profile_id"].asString + if (currentProfileName == name.lowercase()) { + loadProfile(uuid, profileId) + return + } + } + } + + private fun readApiKeyFromOtherMods() { + println("Trying to find the API Key from the config of other mods..") + + var found = false + for (mod in OtherMod.values()) { + val modName = mod.modName + val file = File(mod.configPath) + if (file.exists()) { + val reader = APIUtil.readFile(file) + try { + val key = mod.readKey(reader).replace("\n", "").replace(" ", "") + if (verifyKey(key)) { + println("- $modName: good key!") + if (!found) { + found = true + LorenzUtils.chat("§e[SkyHanni] Grabbed the API key from $modName!") + SkyHanniMod.feature.hidden.apiKey = key + } + } else { + println("- $modName: wrong key!") + } + } catch (e: Throwable) { + println("- $modName: wrong config format! (" + e.message + ")") + continue + } + } else { + println("- $modName: no config found!") + } + } + } + + private fun verifyKey(key: String): Boolean { + return try { + val url = "https://api.hypixel.net/key?key=$key" + val bazaarData = APIUtil.getJSONResponse(url, silentError = true) + return bazaarData.get("success").asBoolean + } catch (e: Throwable) { + e.printStackTrace() + false + } + } + + private fun loadProfile(playerUuid: String, profileId: String) { + val apiKey = SkyHanniMod.feature.hidden.apiKey + val url = "https://api.hypixel.net/skyblock/profile?key=$apiKey&profile=$profileId" + + val jsonObject = APIUtil.getJSONResponse(url) + + val profile = jsonObject["profile"].asJsonObject + val members = profile["members"].asJsonObject + for (entry in members.entrySet()) { + if (entry.key == playerUuid) { + val profileData = entry.value.asJsonObject + ProfileApiDataLoadedEvent(profileData).postAndCatch() + } + } + } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/data/OtherMod.kt b/src/main/java/at/hannibal2/skyhanni/data/OtherMod.kt new file mode 100644 index 000000000..04f2a4d4f --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/data/OtherMod.kt @@ -0,0 +1,42 @@ +package at.hannibal2.skyhanni.data + +import at.hannibal2.skyhanni.SkyHanniMod +import com.google.gson.JsonObject +import java.io.BufferedReader + +enum class OtherMod(val modName: String, val configPath: String, val readKey: (BufferedReader) -> (String)) { + NEU("Not Enough Updates", "config/notenoughupdates/configNew.json", { reader -> + getJson(reader)["apiData"].asJsonObject["apiKey"].asString + }), + COW("Cowlection", "config/cowlection/do-not-share-me-with-other-players.cfg", { reader -> + val lines = reader.readText().split(System.lineSeparator()) + val line = lines.find { it.startsWith(" S:moo=") }!! + line.split("=")[1] + }), + DSM("Dankers SkyBlock Mod", "config/Danker's Skyblock Mod.cfg", { reader -> + val lines = reader.readText().split(System.lineSeparator()) + val line = lines.find { it.startsWith(" S:APIKey=") }!! + line.split("=")[1] + }), + DG("Dungeons Guide", "config/dungeonsguide/config.json", { reader -> + getJson(reader)["partykicker.apikey"].asJsonObject["apikey"].asString + }), + SKYTILS("Skytils", "config/skytils/config.toml", { reader -> + val lines = reader.readText().split(System.lineSeparator()) + val line = lines.find { it.startsWith(" hypixel_api_key = \"") }!! + line.split("\"")[1] + }), + HYPIXEL_API_KEY_MANAGER("Hypixel API Key Manager", "HypixelApiKeyManager/localdata.json", { reader -> + getJson(reader)["key"].asString + }), + SOOPY("Soopy Addons", "soopyAddonsData/apikey.txt", { reader -> + reader.readText() + }), + SBE("SkyBlock Extras", "config/SkyblockExtras.cfg", { reader -> + getJson(reader)["values"].asJsonObject["apiKey"].asString + }), +} + +fun getJson(reader: BufferedReader): JsonObject { + return SkyHanniMod.gson.fromJson(reader, com.google.gson.JsonObject::class.java) +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/utils/APIUtil.kt b/src/main/java/at/hannibal2/skyhanni/utils/APIUtil.kt index c321cf2d5..b66120f82 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/APIUtil.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/APIUtil.kt @@ -8,6 +8,11 @@ import org.apache.http.impl.client.HttpClientBuilder import org.apache.http.impl.client.HttpClients import org.apache.http.message.BasicHeader import org.apache.http.util.EntityUtils +import java.io.BufferedReader +import java.io.File +import java.io.FileInputStream +import java.io.InputStreamReader +import java.nio.charset.StandardCharsets object APIUtil { @@ -27,7 +32,7 @@ object APIUtil { ) .useSystemProperties() - fun getJSONResponse(urlString: String): JsonObject { + fun getJSONResponse(urlString: String, silentError: Boolean = false): JsonObject { val client = builder.build() try { client.execute(HttpGet(urlString)).use { response -> @@ -37,12 +42,20 @@ object APIUtil { return parser.parse(retSrc) as JsonObject } } - } catch (ex: Throwable) { - ex.printStackTrace() - LorenzUtils.error("SkyHanni ran into an ${ex::class.simpleName ?: "error"} whilst fetching a resource. See logs for more details.") + } catch (throwable: Throwable) { + if (silentError) { + throw throwable + } else { + throwable.printStackTrace() + LorenzUtils.error("SkyHanni ran into an ${throwable::class.simpleName ?: "error"} whilst fetching a resource. See logs for more details.") + } } finally { client.close() } return JsonObject() } + + fun readFile(file: File): BufferedReader { + return BufferedReader(InputStreamReader(FileInputStream(file), StandardCharsets.UTF_8)) + } } \ No newline at end of file -- cgit