Resclone/src/main/java/io/gitlab/jfronny/resclone/fetchers/CurseforgeFetcher.java

79 lines
3.3 KiB
Java

package io.gitlab.jfronny.resclone.fetchers;
import io.gitlab.jfronny.commons.HttpUtils;
import io.gitlab.jfronny.resclone.Resclone;
import io.gitlab.jfronny.resclone.data.curseforge.GetModFilesResponse;
import io.gitlab.jfronny.resclone.data.curseforge.GetModResponse;
import net.minecraft.MinecraftVersion;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Date;
import java.util.Random;
public class CurseforgeFetcher extends BasePackFetcher {
// 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));
@Override
public String getSourceTypeName() {
return "curseforge";
}
@Override
public String getDownloadUrl(String baseUrl) throws Exception {
try {
GetModResponse response = GET(baseUrl, GetModResponse.class);
if (!response.data.allowModDistribution)
throw new Exception("The author of " + baseUrl + " disabled access to this pack outside of the curseforge launcher");
String version = MinecraftVersion.CURRENT.getName();
GetModFilesResponse.Data latest = null;
Date latestDate = null;
boolean foundMatchingVersion = false;
for (GetModFilesResponse.Data addon : GET(baseUrl + "/files", GetModFilesResponse.class).data) {
if (foundMatchingVersion && !addon.gameVersions.contains(version)) continue;
if (!foundMatchingVersion && addon.gameVersions.contains(version)) {
foundMatchingVersion = true;
latest = null;
}
if (latest == null || addon.fileDate.after(latestDate)) {
latest = addon;
latestDate = addon.fileDate;
}
}
if (latest == null) throw new FileNotFoundException("Could not identify valid version");
if (!foundMatchingVersion) Resclone.LOGGER.error("Could not find matching version of " + baseUrl + ", using latest");
return latest.downloadUrl;
} catch (Throwable e) {
throw new IOException("Could not get CurseForge download for " + baseUrl, e);
}
}
private static <T> T GET(String suffix, Class<T> klazz) throws URISyntaxException, IOException {
return HttpUtils.get("https://api.curseforge.com/v1/mods/" + suffix).header("x-api-key", API_KEY).sendSerialized(klazz);
}
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;
}
}