fix(launcher): defer CurseForge mod distribution exception until download is attempted

This commit is contained in:
Johannes Frohnmeyer 2024-10-04 18:40:32 +02:00
parent 363a62542e
commit 222120f935
Signed by: Johannes
GPG Key ID: E76429612C2929F4
5 changed files with 43 additions and 16 deletions

View File

@ -51,25 +51,17 @@ public class CurseforgeApi {
if (response.pagination().totalCount() != 1) {
throw new FileNotFoundException("Could not find mod with slug \"" + slug + "\"");
}
return checkDistribution(response.data().getFirst());
return response.data().getFirst();
}
public static CurseforgeMod getMod(int id) throws IOException {
return checkDistribution(Net.downloadJObject(API_URL + "mods/" + id, GC_GetModResponse::deserialize, API_KEY).data());
return Net.downloadJObject(API_URL + "mods/" + id, GC_GetModResponse::deserialize, API_KEY).data();
}
public static String getDescription(int id) throws IOException {
return Net.downloadJObject(API_URL + "mods/" + id + "/description", GC_GetModDescriptionResponse::deserialize, 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.downloadJObject(API_URL + "mods/" + modId + "/files/" + fileId, GC_GetModFileResponse::deserialize, API_KEY).data();
}

View File

@ -8,6 +8,7 @@ import io.gitlab.jfronny.inceptum.launcher.model.fabric.FabricModJson;
import io.gitlab.jfronny.inceptum.launcher.model.fabric.GC_FabricModJson;
import io.gitlab.jfronny.inceptum.launcher.system.instance.ModPath;
import io.gitlab.jfronny.inceptum.launcher.system.mds.*;
import io.gitlab.jfronny.inceptum.launcher.system.source.DistributionDisabledException;
import io.gitlab.jfronny.inceptum.launcher.system.source.ModSource;
import java.io.IOException;
@ -18,9 +19,14 @@ public record MdsDownloadTask(ProtoInstance instance) implements ThrowingConsume
public void accept(MdsMod mod) throws IOException {
if (mod.getScanStage().contains(ScanStage.DOWNLOAD)) return;
ModSource selectedSource = null;
DistributionDisabledException distributionDisabledException = null;
for (ModSource source : mod.getMetadata().sources().keySet()) {
if (!Files.exists(source.getJarPath()) && HttpClient.wasOnline()) source.download();
selectedSource = source;
try {
if (!Files.exists(source.getJarPath()) && HttpClient.wasOnline()) source.download();
selectedSource = source;
} catch (DistributionDisabledException de) {
distributionDisabledException = de;
}
}
Path imodPath = mod.getMetadataPath();
Path jarPath = mod.getJarPath();
@ -39,7 +45,11 @@ public record MdsDownloadTask(ProtoInstance instance) implements ThrowingConsume
jarPath = selectedSource.getJarPath();
managed = true;
}
} else if (!Files.exists(jarPath)) throw new IOException("Mod has no jar and no sources");
} else if (!Files.exists(jarPath)) {
IOException exception = new IOException("Mod has no jar and no sources");
if (distributionDisabledException != null) exception.addSuppressed(distributionDisabledException);
throw exception;
}
FabricModJson fmj;
try (FileSystem fs = Utils.openZipFile(jarPath, false)) {

View File

@ -10,6 +10,7 @@ import io.gitlab.jfronny.inceptum.launcher.model.inceptum.ModMeta;
import io.gitlab.jfronny.inceptum.launcher.system.mds.*;
import io.gitlab.jfronny.inceptum.launcher.system.instance.ModPath;
import io.gitlab.jfronny.inceptum.launcher.system.mds.noop.NoopMod;
import io.gitlab.jfronny.inceptum.launcher.system.source.DistributionDisabledException;
import io.gitlab.jfronny.inceptum.launcher.system.source.ModSource;
import java.io.IOException;
@ -46,9 +47,14 @@ public record FileScanTask(ProtoInstance instance, Path file, ThrowingBiConsumer
}
meta.updateCheck(gameVersion);
ModSource selectedSource = null;
DistributionDisabledException distributionDisabledException = null;
for (ModSource source : meta.sources().keySet()) {
if (!Files.exists(source.getJarPath())) source.download();
selectedSource = source;
try {
if (!Files.exists(source.getJarPath())) source.download();
selectedSource = source;
} catch (DistributionDisabledException de) {
distributionDisabledException = de;
}
}
if (selectedSource != null) {
if (Files.exists(jarPath)) {
@ -60,7 +66,11 @@ public record FileScanTask(ProtoInstance instance, Path file, ThrowingBiConsumer
}
jarPath = selectedSource.getJarPath();
managed = true;
} else if (!Files.exists(jarPath)) throw new IOException("Mod has no jar and no sources");
} else if (!Files.exists(jarPath)) {
IOException exception = new IOException("Mod has no jar and no sources");
if (distributionDisabledException != null) exception.addSuppressed(distributionDisabledException);
throw exception;
}
if (modified) meta = GC_ModMeta.deserialize(imodPath, GsonPreset.CONFIG);
FabricModJson fmj;

View File

@ -41,6 +41,7 @@ public final class CurseforgeModSource implements ModSource {
@Override
public ModDownload download() throws IOException {
if (!allowModDistribution()) throw new DistributionDisabledException(mod.slug());
Path path = getJarPath();
try {
Net.downloadFile(current.downloadUrl(), path);
@ -132,6 +133,10 @@ public final class CurseforgeModSource implements ModSource {
return other instanceof CurseforgeModSource cu && cu.projectId == projectId;
}
public boolean allowModDistribution() {
return mod.allowModDistribution();
}
public int getFileId() {
return fileId;
}

View File

@ -0,0 +1,10 @@
package io.gitlab.jfronny.inceptum.launcher.system.source;
import java.io.IOException;
public class DistributionDisabledException extends IOException {
public DistributionDisabledException(String mod) {
super("The author of the mod \"" + mod + "\" 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.");
}
}