From 7c9f889efd9c5d889394f8bf00288ef1c38f8ae4 Mon Sep 17 00:00:00 2001 From: CalMWolfs <94038482+CalMWolfs@users.noreply.github.com> Date: Tue, 24 Sep 2024 00:11:18 +1000 Subject: Backend: Add Http Request Patching (#2578) --- .../java/at/hannibal2/skyhanni/utils/APIUtils.kt | 213 +++++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 src/main/java/at/hannibal2/skyhanni/utils/APIUtils.kt (limited to 'src/main/java/at/hannibal2/skyhanni/utils/APIUtils.kt') diff --git a/src/main/java/at/hannibal2/skyhanni/utils/APIUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/APIUtils.kt new file mode 100644 index 000000000..d28263af6 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/utils/APIUtils.kt @@ -0,0 +1,213 @@ +package at.hannibal2.skyhanni.utils + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.test.command.ErrorManager +import com.google.gson.JsonElement +import com.google.gson.JsonObject +import com.google.gson.JsonParser +import com.google.gson.JsonSyntaxException +import org.apache.http.HttpEntity +import org.apache.http.client.config.RequestConfig +import org.apache.http.client.methods.HttpGet +import org.apache.http.client.methods.HttpPost +import org.apache.http.entity.ContentType +import org.apache.http.entity.StringEntity +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.security.KeyStore +import javax.net.ssl.HttpsURLConnection +import javax.net.ssl.KeyManagerFactory +import javax.net.ssl.SSLContext +import javax.net.ssl.TrustManagerFactory + +object APIUtils { + + private val parser = JsonParser() + private var showApiErrors = false + + private val ctx: SSLContext? = run { + try { + val myKeyStore = KeyStore.getInstance("JKS") + myKeyStore.load(APIUtils.javaClass.getResourceAsStream("/keystore.jks"), "changeit".toCharArray()) + val kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()) + val tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()) + kmf.init(myKeyStore, null) + tmf.init(myKeyStore) + SSLContext.getInstance("TLS").apply { + init(kmf.keyManagers, tmf.trustManagers, null) + } + } catch (e: Exception) { + println("Failed to load keystore. A lot of API requests won't work") + e.printStackTrace() + null + } + } + + fun patchHttpsRequest(connection: HttpsURLConnection) { + ctx?.let { + connection.sslSocketFactory = it.socketFactory + } + } + + data class ApiResponse(val success: Boolean, val message: String?, val data: JsonObject) + + private val builder: HttpClientBuilder = + HttpClients.custom().setUserAgent("SkyHanni/${SkyHanniMod.version}") + .setDefaultHeaders( + mutableListOf( + BasicHeader("Pragma", "no-cache"), + BasicHeader("Cache-Control", "no-cache"), + ), + ) + .setDefaultRequestConfig( + RequestConfig.custom() + .build(), + ) + .useSystemProperties() + + /** + * TODO + * make suspend + * use withContext(Dispatchers.IO) { APIUtils.getJSONResponse(url) }.asJsonObject + */ + fun getJSONResponse(urlString: String, silentError: Boolean = false) = + getJSONResponseAsElement(urlString, silentError) as JsonObject + + fun getJSONResponseAsElement( + urlString: String, + silentError: Boolean = false, + apiName: String = "Hypixel API", + ): JsonElement { + val client = builder.build() + try { + client.execute(HttpGet(urlString)).use { response -> + val entity = response.entity + if (entity != null) { + val retSrc = EntityUtils.toString(entity) + try { + return parser.parse(retSrc) + } catch (e: JsonSyntaxException) { + val name = e.javaClass.name + val message = "$name: ${e.message}" + if (e.message?.contains("Use JsonReader.setLenient(true)") == true) { + println("MalformedJsonException: Use JsonReader.setLenient(true)") + println(" - getJSONResponse: '$urlString'") + ChatUtils.debug("MalformedJsonException: Use JsonReader.setLenient(true)") + } else if (retSrc.contains("