91 lines
4.1 KiB
Java
91 lines
4.1 KiB
Java
package io.gitlab.jfronny.inceptum.launcher.api;
|
|
|
|
import io.gitlab.jfronny.commons.HttpUtils;
|
|
import io.gitlab.jfronny.inceptum.common.Net;
|
|
import io.gitlab.jfronny.inceptum.launcher.model.curseforge.CurseforgeFile;
|
|
import io.gitlab.jfronny.inceptum.launcher.model.curseforge.CurseforgeMod;
|
|
import io.gitlab.jfronny.inceptum.launcher.model.curseforge.response.*;
|
|
|
|
import java.io.*;
|
|
import java.net.URISyntaxException;
|
|
import java.util.*;
|
|
|
|
public class CurseforgeApi {
|
|
// So you found the API key.
|
|
// Please be aware that CurseForge requires you to change this if you make any kind of derivative work
|
|
// Creating your own API key is relatively simple, so please don't abuse this
|
|
private static final String API_KEY = new String(unsalt(new byte[]{
|
|
-30, 50, -60, -121, 62, -31, 35, 17, 16, -53,
|
|
-53, -88, 21, -21, 15, -105, -115, -108, 114, -50,
|
|
-49, -4, 56, -65, -70, 108, -65, -3, -55, -4,
|
|
36, -86, -40, 116, 71, -5, 75, -9, -43, 4,
|
|
91, -91, -29, 40, 66, 87, -80, -74, 71, 41,
|
|
76, -96, 108, -61, -113, 118, 7, -39, -116, -120
|
|
}, 1024));
|
|
|
|
private static final String API_URL = "https://api.curseforge.com/v1/";
|
|
private static final int pageSize = 20;
|
|
|
|
public static List<CurseforgeMod> search(String gameVersion, String query, int page, String sort) throws IOException {
|
|
return Net.downloadObject(Net.buildUrl(API_URL, "mods/search", Map.of(
|
|
"gameId", "432", // minecraft
|
|
"modLoaderType", "4", // fabric
|
|
"classId", "6", // mods
|
|
// "categoryId", ""
|
|
"searchFilter", query,
|
|
"sortField", sort,
|
|
"sortOrder", "desc",
|
|
"gameVersion", gameVersion,
|
|
"pageSize", Integer.toString(pageSize),
|
|
"index", Integer.toString(page * pageSize)
|
|
)), GC_SearchResponse::read, API_KEY).data();
|
|
}
|
|
|
|
public static CurseforgeMod getMod(String slug) throws IOException {
|
|
SearchResponse response = Net.downloadObject(Net.buildUrl(API_URL, "mods/search", Map.of(
|
|
"gameId", "432",
|
|
"classId", "6",
|
|
"slug", slug
|
|
)), GC_SearchResponse::read, API_KEY);
|
|
if (response.pagination().totalCount() != 1) {
|
|
throw new FileNotFoundException("Could not find mod with slug \"" + slug + "\"");
|
|
}
|
|
return checkDistribution(response.data().get(0));
|
|
}
|
|
|
|
public static CurseforgeMod getMod(int id) throws IOException {
|
|
return checkDistribution(Net.downloadObject(API_URL + "mods/" + id, GC_GetModResponse::read, API_KEY).data());
|
|
}
|
|
|
|
public static String getDescription(int id) throws IOException {
|
|
return Net.downloadObject(API_URL + "mods/" + id + "/description", GC_GetModDescriptionResponse::read, API_KEY).data();
|
|
}
|
|
|
|
private static CurseforgeMod checkDistribution(CurseforgeMod mod) {
|
|
if (!mod.allowModDistribution()) {
|
|
throw new IllegalArgumentException("The author of the mod \"" + mod.slug() + "\" has chosen to deliberately break your ability of downloading it.\n"
|
|
+ "Please let them know that disabling third party downloads does nothing but make the users life harder for no reason.");
|
|
}
|
|
return mod;
|
|
}
|
|
|
|
public static CurseforgeFile getFile(int modId, int fileId) throws IOException {
|
|
return Net.downloadObject(API_URL + "mods/" + modId + "/files/" + fileId, GC_GetModFileResponse::read, API_KEY).data();
|
|
}
|
|
|
|
public static FingerprintMatchesResponse.Result checkFingerprint(long hash) throws IOException, URISyntaxException {
|
|
try (Reader r = HttpUtils.post(API_URL + "fingerprints").bodyJson("{\"fingerprints\":[" + hash + "]}").sendReader()) {
|
|
return GC_FingerprintMatchesResponse.read(r).data();
|
|
}
|
|
}
|
|
|
|
private static byte[] unsalt(byte[] data, int salt) {
|
|
byte[] result = new byte[data.length];
|
|
new Random(salt).nextBytes(result);
|
|
for (int i = 0; i < data.length; i++) {
|
|
result[i] ^= data[i];
|
|
}
|
|
return result;
|
|
}
|
|
}
|